...

суббота, 26 июня 2021 г.

В Telegram добавили групповые видеозвонки и анимированные фоны

Мессенджер Telegram получил обновление, в котором разработчики добавили функцию групповых видеозвонков. Кроме этого, появились демонстрации экрана, улучшенное шумоподавление и анимированные фоны для чатов.

Разработчики добавили в мессенджер возможность транслировать изображение с камеры или изображение экрана в голосовом чате для групп.

Голосовой чат в группе переключается в режим видеоконференции, когда один из участников включает камеру.

Telegram поддерживает полноэкранный режим для конференций. Есть настройка для закрепления видео конкретного участника.

У конференции пока что есть ограничение на количество участников — 30 человек, но разработчики обещают увеличить лимит в ближайшее время. Голосовой режим без видео остался неограниченным по количеству собеседников.

Захват изображения с экрана устройства можно вести параллельно с включённой камерой. В версии для компьютера есть возможность демонстрации отдельного окна.

Команда Telegram также рассказала, что улучшила работу шумоподавления.

В версии для планшетов и компьютеров разработчики адаптировали интерфейс для работы в режиме видеоконференции. Голосовой чат открывается в отдельном окне и у пользователя остаётся доступ к чатам.

Разработчики Telegram изменили и графическую составляющую мессенджера. Они добавили анимированные фоны для чатов, анимации отправки сообщений и переделали кнопки меню для ботов.

Анимация фонов для чатов работает с помощью алгоритмического смешивания нескольких цветов и меняется при отправке сообщении или взаимодействии с клавиатурой.

По заявлению разработчиков функция анимации фонов почти не скажется на заряде аккумулятора.

Пользователи получили возможность создавать свои фоны с анимацией. Для этого достаточно указать три и четыре желаемых цвета и один из доступных узоров. Полученный фон можно отправить другим пользователям.

Появилась анимация «перелёта» сообщений из поля ввода в чат. В версии для iOS такая анимация работает для вложений и текстовых сообщений.

Изменилось меню у ботов. Создатели ботов смогут добавлять подсказки для пользователей в поле ввода. Разработчики добавили возможность вариативных команд в зависимости от выбранного чата и языка интерфейса. Кроме этого, владельцы ботов теперь могут задавать списки команд для определённых чатов или выбранных пользователей.

Команда разработчиков Telegram также добавила возможность создавать наборы стикеров для всех пользователей через бота @stickers и отслеживать статистику использования. Помимо этого, создатели мессенджера продолжают добавлять анимированные эмодзи.

Adblock test (Why?)

Испанская барахолка: жесткие диски, крепления для мониторов и кое-что еще


И снова в солнечная суббота, время на часах — 9:30 утра, а значит — пора отправляться на поиск интересных вещей на барахолку. Почему именно в такое время? Потому что продавцы только к этому времени полностью раскладывают свой товар, это раз, а два — температура после 11 уже приближается к 40 градусам, так что там уже не до поиска интересностей.

Сегодня попалось много примечательных вещей, некоторые из них я купил. Описание всего этого — под катом.
Все начинается с пары-тройки динамиков, усилителя (вроде как автомобильного), детской камеры.


Затем сразу же попадается Toshiba Satellite (модель не узнал) с Windows XP на борту. Выглядит неплохо, как с косметической, так и с практической точки зрения. Мне особенно нравится блок мультимедийных кнопок.

Затем, рядом, вижу геймерскую (ну, типа геймерскую) мышь от Trustmaster и обычную проводную мышку.

Еще чуть дальше какая-то простенькая пленочная камера. Выглядит ну очень недорого. Пришел домой, посмотрел, какая у нее цена на местной онлайн-барахолке, оказалось недурно — от 25 до 150 евро, в зависимости от комплектации (пленка, вспышка и т.п.) и состояния.

Потом встретилась видеоконсоль Weechamp Extreme. Вот это как раз недорогая штука. Посмотрел, сколько стоит на Амазоне — оказалось, купить можно за 14 евро (с отправкой, да). Видимо, кто-то пытается продать ну совсем ненужную вещь.

Переходим к телефонам. Это Qtek — просто идеальный коммуникатор своего времени. У меня был S100, в алюминиевом корпусе, это вещь, скажу я вам. А эта модель — следующее поколение, с физической клавиатурой, тыловой и фронтальной камерами, интернетом и кучей всего еще. Честно скажу, мне вот такой форм-фактор нравится гораздо больше, чем у современных «лопат».

Проектор для диафильмов. Думаю, эта штука была крайне дорога в свое время — выглядит очень круто. Производство — Германия, вроде как Нюнрберг. Стоит на столе, в ящиках которого — полным-полно диапозитивов. Если бы было место в доме — купил бы. Правда, цену не спрашивал. Думаю, от 20 до 50 евро.

Рабочий, по словам продавца, смарт-ТВ. Насчет рабочего я бы посомневался, скорее всего, сгорел светодиод и изображения нет. Продает за 60 евро. У меня такой же, в свое время купил за 60 евро (тут совпадение, да), починил подсветку и до сих пор работает, прошло уже года два. Беспроводное и проводное соединение, YouTube, все дела.

Вейп. Весь раздолбанный в хлам, но, думаю, знатоки могли бы найти что-то полезное.

Ноутбук Acer extenza 5630z, выпуска 2009 года. Не такой и древний, в общем-то, ему можно найти применение и сейчас. YouTube не посмотришь особо, но в качестве печатной машинки или еще чего-нить подобного — вполне.

Внутри — двухъядерный процессор Intel Pentium Dual Core T3200 2 x 2 GHz, видеочип Intel Graphics Media Accelerator (GMA) 4500MHD. Весит он около 3 кг. В свое время стоил 500 евро.


Какой-то древний ЖК-телевизор. Точнее, не какой-то, а Basic Line BLTFT23CL. Посмотрел, сколько стоит — за 20 евро можно купить б/у в рабочем состоянии на онлайн-барахолке. Но такой и даром уже не нужен, он просто огромный.


Еще один телевизор, что-то их много сегодня. Экран вроде не разбит, но продавец говорит, что телек не включается. Это может означать что угодно — от отсутствия изображения до действительно «мертвого» телевизора. Что в первом, что в последнем случае ремонт не очень сложен, но у меня их и так 3 штуки, а возиться потом с перепродажей не хочется.


Крутой коптер UFO Defender, у него даже светодиодные огни есть. Зачем, правда? В темноте особо не полетаешь. Но, в целом, неплохой. Продавец хотел за него 10 евро. Новый в магазине стоит 70 евро. Неплохо — в том случае, конечно, если он в рабочем состоянии (хотя похоже, что да).

Россыпь фото и видеокамер. Кто-то видит что-то интересное?

Вероятно, трансформатор. Я видел подобные советские, в одном случае к такому подключался телевизор «Березка». Если, конечно, если это именно трансформатор.

Сразу четыре неплохих телевизора. В магазин можно не идти :)

Телескоп. Модель не посмотрел, но корпус очень уж помят. Кстати, часто встречаются дорогие модели, в разном состоянии. Но чтобы понять степень работоспособности, нужно быть хотя бы любителем.

Монитор от Samsung — 24 дюйма, вполне современный. Здесь не выдержала душа поэта — я спросил цену, сторговался за 20 евро и купил его. Но по приходу домой оказалось, что экран поврежден — внешне это никак не проявлялось, ни полос, ни темных мест. Но при включении увидел трещину через весь экран. При этом продавец уверял, что монитор рабочий и он вот только его у себя дома со стола снял. Да, бывает, обманывают — расчет на то, что ты погрузишь его в машину и уедешь в свое пуэбло поблизости, а проверишь уже тогда, когда барахолка закончится. Я живу рядом, так что продавцу пришлось вернуть деньги.


Еще несколько старых ноутбуков и чуть более новых планшетов.

А вот это — изюминка сегодняшнего дня, графический планшет Cintiq 24HD DTK-2400.
Характеристики:
  • Серия:Cintiq
  • Тип монитора:TFT (H-IPS) с активной матрицей a-Si
  • Диагональ экрана:24 "
  • Разрешение:1920x1200 px
  • Размер зерна:0.27 мм
  • Глубина цвета:16.7 млн. цветов


Вышел он в 2011 году, и, наверное, может пригодиться дизайнерам, художникам, архитекторам и сейчас. Стоимость его на eBay — от 150 до 1000 евро даже сейчас. Продавец хотел около 80 евро, думаю, уступил и до 50 евро. Но проблема в том, что хранить просто негде. Правда, если вам интересен его обзор — отпишитесь в комментариях. Если заинтересованных будет много — могу купить и потестить в следующую субботу.


После планшета попался вот такой вот простенький робот-пылеосос. Думаю, вполне в рабочем состоянии. Просят за него всего 10 евро, этих денег он точно стоит — крошки на кухне, шерсть животных и т.п. точно уберет.

Еще попался вот такой десктоп, о состоянии которого я не спрашивал, если честно. Характеристики неплохие для своего времени — целых 4 ГБ ОЗУ DDR2, процессор 2.6 GHz, видео GeForce 7100 и жесткий диск на целый терабайт.


Еще немножко всякого-разного — есть что-то полезное/интересное?

И еще попался вот такой интересный девайс — какой-то беспроводной трансмиттер аналогового видео-сигнала Philips VL1400.

Ну а теперь — о покупках


Их всего три. Первая — банальный адаптер с возможностью изменения выходного напряжения. Я такие уже показывал, так что смысла нет. Надежный Китай, если так можно выразиться, ни разу не подводил.

Вторая — это сразу 40+ жестких дисков! 2,5-дюймовых, причем вполне себе современных. Объем — вплоть до 2 ТБ, по большей части — 500 МБ. Производители разные, включая WD, Seagate, Toshiba. Понятно, что гарантии их работоспособности никто не давал, но я и не надеялся ни на что. Приобрел все это всего за 20 евро, посчитав, что беру лотерейный билет.


И он сыграл! Придя домой, оказалось, что из 40+ штук дисков 15 — условно-рабочие, то есть они инициализируются, определяются, форматируются и затем — открываются без особых проблем. Более детально я их не тестировал.

Затем около 20 штук — не рабочие, но с возможностью восстановления. Некоторые не инициализируются, так что проблема может быть в плате, а поскольку у меня есть одинаковые модели, попробую переставить электронику и посмотреть, заведутся ли. Есть те, что пытаются инициализироваться, но система не дает по какой-то причине. Есть и еще несколько проблем — со всем этим буду разбираться по возможности.

И еще 9 штук — совсем нерабочие. Это те, что скрипят, трещат и издают другие очень громкие звуки. Тут уже понятно, что большинство повреждены физически. Сколько я подобные ни пробовал раньше восстанавливать специализированным софтом — толку нет, пустая трата времени.


И еще один джек-пот — это кронштейн сразу для трех (опционально — пяти) мониторов Arctic z3pro gen3. Мне удалось купить систему всего за 8 евро, в подержанном состоянии, но со всеми элементами. Новая стоит чуть больше 100 евро у производителя.

Больше всего мне понравилось здесь даже не то, что можно разместить сразу три монитора, а то, что основание — это одновременно USB-док станция, с 4 USB 3.2 портами и адаптером для подключения mini-USB устройств.




Просто шикарно. Сейчас у меня на столе стоит подставка для 2 мониторов, очень надежная, но без изысков. Вероятно, соберусь с силами и поставлю эту новую — тогда все USB будут под рукой, да и степеней свободы у кронштейнов немало. Появились даже мысли о покупке третьего монитора.

Ну а на сегодня все! Не переключайтесь.

Adblock test (Why?)

[Перевод] Проект MouseMover — мышь, живущая своей жизнью

Автор статьи, перевод которой мы сегодня публикуем, рассказывает о проекте MouseMover. Это — USB-устройство, которое имитирует присутствие пользователя за компьютером, периодически перемещая курсор мыши на небольшие расстояния, что позволяет избежать блокировки экрана компьютера или перехода компьютера в спящий режим.

MouseMover

Аппаратные и программные компоненты проекта


В этом проекте использована плата SparkFun Pro Micro — 5V/16MHz. Вместо неё можно воспользоваться Arduino Leonardo. Обратите внимание на то, что тут нужна лишь одна из вышеупомянутых плат.

Для работы над программной частью проекта используется Arduino IDE.

Обзор проекта


Я проработал в разных компаниях Америки почти сорок лет. Я видел, как изменился за это время подход к корпоративной компьютерной безопасности. Сначала правил безопасности, можно сказать, вовсе не было. А теперь же эти правила стали прямо-таки безумными. Сегодня во многих компаниях компьютеры настраивают так, чтобы они, если уходят в режим сна, запрашивали бы при пробуждении пароль для входа в систему. Иногда компьютеры «засыпают» после 5 минут бездействия пользователя. А на моей последней работе перешли на двухфакторную схему аутентификации, когда для входа в систему используется и пароль, и аппаратный токен, генерирующий набор цифр. Для того чтобы войти в систему, нужно ввести и обычный пароль, и код с токена. Хотя подобные меры безопасности — это, в современных условиях, очень хорошо, а порой и необходимо, они могут сильно досаждать людям, которые хотят сделать что-то полезное (а не заниматься постоянным вводом паролей). Я и сосчитать не могу — сколько раз мне приходилось вводить пароль и код, когда я отвлекался от работы на разговор с коллегой, а потом возвращался к делам и обнаруживал, что мой компьютер заблокировал экран. Хорошо было бы иметь некое устройство, которое, работая само по себе, периодически немного двигает курсор мыши, не давая компьютеру заблокировать экран или «заснуть».

Поискав подобные устройства в интернете, я узнал, что решить эту задачу уже пытались. Делалось это самыми разными способами — от механических, когда нечто само двигает настоящую мышь, до программных, когда на компьютере, в виде фоновой задачи, работает утилита, воздействующая на указатель мыши. «Механический» подход кажется мне слишком примитивным, а программный сработает далеко не всегда, так как системы безопасности, используемые в компаниях, могут распознать эту дешёвую уловку. Весьма интересно было бы сделать недорогое устройство, неотличимое, с точки зрения компьютера, от настоящей мыши, которая иногда перемещается. В результате и появился проект MouseMover, о котором я хочу рассказать.

Дисклеймер


Описываемая здесь прошивка и основанное на ней устройство могут быть использованы для обхода корпоративных требований, касающихся информационных технологий, а так же — имеющихся в организациях механизмов обеспечения безопасности. Подобное может произойти из-за того, что компьютер, к которому подключено устройство, не сможет, в отсутствие активности пользователя, заблокировать экран. Это может быть запрещено на уровне организации или на государственном уровне и может привести к наказанию виновного в подобном деянии. Тяжесть наказания зависит от ситуации. Если вы не уверены в том, что можете безнаказанно пользоваться подобным устройством — уточните это в IT-отделе своей компании. Пользуйтесь устройством на свой страх и риск.

Подробности о проекте


В рамках этого проекта реализовано устройство MouseMover, которое способно не допустить блокировку экрана компьютера или переход системы в спящий режим. В нём используется недорогой (стоимостью в районе $5-$17) модуль Pro Micro (Sparkfun DEV-12640 или эквивалентный клон) с микроконтроллером ATmega32U4, а так же — USB-кабель. Программное обеспечение проекта написано с использованием Arduino IDE. Это ПО может использоваться и на других платах Arduino, наподобие Arduino Leonardo или Arduino Micro, но плата Pro Micro отличается весьма компактными размерами, питание на неё подаётся по USB, она недорого стоит. Всё это делает её идеальным выбором для решения нашей задачи.

Наш контроллер перемещает курсор мыши на небольшое расстояние, выполняя это через каждую минуту или через другой небольшой временной интервал. Это имитирует работу пользователя с компьютером, не давая компьютеру, к которому подключено устройство, блокировать экран или уходить в режим сна. В отличие от исключительно программных решений, которые могут не сработать во многих IT-инфраструктурах, это решение выглядит, с точки зрения компьютера, как настоящая (вторая) мышь, подключённая к компьютеру. При этом пользователь продолжает работать с обычной мышью.

Обычно перемещения курсора на несколько пикселей, например, каждую минуту, достаточно для того чтобы поддерживать компьютер в рабочем состоянии. Так как расстояние перемещения курсора невелико (как правило, достаточно всего несколько пикселей в любом возможном направлении движения курсора), и так как это делается не слишком часто, это обычно не мешает обычной работе с компьютером. Для того чтобы поддерживать безопасность системы на уровне, близком к тому, который требуется в организации, устройство можно особым образом настроить. А именно — сделать так, чтобы оно работало лишь ограниченное время, после чего прекращало перемещать курсор до тех пор, пока не получит соответствующую команду, включающую перемещение курсора, или до тех пор, пока оно не будет отключено от компьютера и подключено к нему снова.

В коде, обеспечивающем работу устройства, имеется довольно много параметров, которые можно настраивать. Все параметры можно модифицировать, отправляя команды на последовательный порт контроллера, который добавляется на компьютер после подключения к нему устройства. А именно, контроллер виден в Windows как мышь (HID) и виртуальный последовательный (COM) порт. После того, как контроллер будет запрограммирован, параметрам будут назначены значения, применяемые по умолчанию. Но их можно изменить, а после этого — записать в EEPROM. В результате параметры, заданные пользователем, будут использоваться каждый раз, когда контроллер подключается к компьютеру.

Прошивка рассчитана на плату Pro Micro (с микроконтроллером ATmega32U4), которая соединена с компьютером через USB-порт. В результате оказывается, что аппаратная часть этого проекта представлена подходящей платой и USB-кабелем, посредством которого плата соединяется с компьютером.

Аппаратное обеспечение и система ввода-вывода


Хотя аппаратная часть этого проекта представлена лишь платой Pro Micro и USB-кабелем, на плате есть пины ввода-вывода, которые можно соединить перемычками для изменения поведения устройства. Кроме того, если нужно, к плате можно подключить светодиод, который будет сигнализировать о том, что устройство работает. Хотя это и необязательно, практика показала, что наличие светодиода — это удобно, так как позволяет точно знать о том, работает устройство или нет. Если говорить о перемычках, то они сделаны, в основном, ради того, чтобы устройством было бы удобнее управлять, или для тех случаев, когда создателю своего варианта MouseMover хотелось бы иметь возможность воздействия на него с помощью перемычек, а не посредством команд, отправляемых ему через последовательный порт.

Вот схема платы с указанием мест установки перемычек и подключения светодиода. Напомню, что это необязательно.


Схема платы

Перемычка, называемая JPE (это имя, как и имена других перемычек, определено в коде), может использоваться для выключения устройства. Подключение соответствующего пина к GND останавливает работу мыши (как если бы мышь отключили от компьютера). А если перемычку убрать — работа устройства продолжится. Эта перемычка подключается к пину 6 (PD7) Arduino.

Вторая перемычка, JP2, отключает программный таймер и заставляет мышь постоянно перемещаться, не обращая внимание на то, на какой временной интервал настроена программа. Если эту перемычку отключить — восстанавливается обычный режим работы. Эта перемычка подключается к пину 2 (PD1) Arduino.

Третья перемычка — PD3 — заставляет указатель мыши перемещаться каждые 5 секунд, при этом временной интервал, заданный в настройках, игнорируется. Если её убрать — система переходит в обычный режим работы. Перемычка подключается к пину 5 (PC6) Arduino.

Светодиод и резистор подключают к пину A3 Pro Micro (цифровой пин 21 (PF4) Arduino) и к VCC. Включение светодиода указывает на работу MouseMover. Хотя без светодиода и можно обойтись, если он есть, он позволяет точно знать о том, работает устройство или нет. Тут можно использовать любой светодиод, который есть под рукой. Я пользовался резистором на 330 Ом (0,25 Вт), но тут, что зависит от светодиода, подойдёт любой резистор с сопротивлением от 100 Ом до 1 КОм. Существуют и светодиоды со встроенным резистором, наподобие Lumex SSL-LX3044GD-5V (Digikey 67-1062-ND), которые рассчитаны на подключение прямо к 5В-выводу модуля. Если воспользоваться именно таким светодиодом — задача его подключения к плате упростится. Достаточно будет припаять выводы светодиода к соответствующим пинам. Какой бы светодиод вы ни использовали — обращайте внимание на его полярность. А именно — катод подключается к пину A3, а анод, через резистор, к VCC.

Компиляция прошивки и загрузка кода


Создайте папку MouseMover в папке Arduino и поместите в неё файл MouseMover.ino из репозитория проекта. Сделайте двойной щелчок по этому файлу для запуска Arduino IDE и выполните следующие настройки в разделе Tools:
  • Board: Arduino Leonardo (эту настройку можно использовать и для Pro Micro).
  • Port: COMxx (номер порта, назначенный устройству операционной системой).
  • Programmer: ArduinoISP.

Если плата Pro Micro уже использовалась на компьютере, на котором установлена Arduino IDE — это значит, что после того, как файл будет открыт в IDE, для загрузки кода на плату достаточно будет нажать на кнопку Upload. А если же плату впервые подключили к компьютеру — надо будет ещё установить для неё драйверы.

Подробности о подключении Pro Micro к компьютеру можно найти в PDF-файле с документацией в репозитории проекта. Там же есть сведения об изменении номера COM-порта и решении проблем, которые могут возникнуть при первом подключении Pro Micro к компьютеру.

Работа над проектом велась в Arduino IDE 1.8.5. Всё должно хорошо работать и в более новых версиях IDE (включая самую свежую — 1.8.15).

Команды


Контроллер принимает команды по последовательному порту. В ответ на эти команды он способен выполнять различные действия и возвращать сведения о текущем состоянии настроек. Для отправки команд нужно открыть порт на любой скорости (кроме 1200 бод) (формат 8-N-1) в программе наподобие Hyperterminal или Tera Term, или в терминале Arduino IDE (или в вашем любимом терминале). Потом можно создавать batch-файлы для автоматизации отправки команд на устройство через COM-порт.

После того, как вы убедитесь в том, что соединение с MouseMover успешно установлено (можно отправить ?, нажать Enter, после чего должны появиться справочные сведения), можно отправлять устройству команды и, если нужно, настраивать его параметры.

Ниже приведена таблица команд, поддерживаемых MouseMover. Команды для чтения значений состоят из одной буквы, а команды для записи значений — из одной буквы, за которой следует число. За командами идёт <CR> или <CR><LF>. Например, команда может выглядеть как X<CR> или как X20<CR> (ещё она может выглядеть как X=20<CR>). <CR> — это то же самое, что нажатие на клавишу Enter.


Обратите внимание на то, что, при первом перемещении указателя, к его текущей позиции (X, Y) будет добавлено столько пикселей, сколько указано в соответствующих параметрах. При втором перемещении те же значения будут вычтены из новых координат указателя. Потом эта последовательность увеличения и уменьшения координат повторится.

Если вы хотите поменять значения переменных X, Y, T, R и сохранить их так, чтобы они использовались бы при следующем включении устройства как значения, применяемые по умолчанию, просто запишите в них новые значения, а после этого вызовите команду E2<CR>. Для возврата их к исходным значениям, применяемым по умолчанию, вызовите команду E0<CR>, а потом — команду E2<CR>.

Интеграция с системой


После того, как в модуль Pro Micro записана прошивка MouseMover, его можно использовать в системе с разным уровнем интеграции в неё.

Самый простой сценарий использования устройства заключается в том, что его просто подключают к USB-порту компьютера на то время, когда нужно, чтобы оно работало. А когда нужды в нём нет — его отключают. После каждого подключения к компьютеру MouseMover будет использовать параметры, записанные в EEPROM, в состав которых входит и параметр, задающий продолжительность работы устройства. После того, как MouseMover проработает это время, устройство отключится и компьютер сможет перейти в режим сна или блокировки. Если же устройство просто отключить от компьютера, а потом подключить снова — отсчёт времени начнётся с нуля. Это позволяет пользователю задать время работы устройства, а потом, после каждого подключения к компьютеру, например, выполняемого каждое утро, устройство проработает именно это время.

Пакетные файлы Windows и автоматизация работы с MouseMover


Вместо того, чтобы постоянно подключать и отключать MouseMover, можно создать batch-файл (пакетный файл) в Windows и ярлыки к нему, позволяющие вызывать его с параметрами, и, например, включать и выключать устройство. Ещё можно создать в Windows задачу, вызывающую этот файл в заданное время или при входе в систему. Следующий пример рассчитан на Windows 7 и Windows 10, но тот же функционал можно реализовать и для macOS, и для Linux или Unix.

Можно создать пакетный файл, отправляющий на MouseMover команду R. Вот как может выглядеть этот файл:

@echo off
rem MoverPort - это имя COM-порта в формате \\.\COM# (впишите сюда свой номер порта)
set MoverPort=\\.\COM4
rem R=<количество минут> (9 часов=540) (0=выключено)(%1=получить из командной строки)
echo R=%1 >%MoverPort%

Обратите внимание на то, что в этом примере batch-файла используется порт COM4, а у вас это может быть порт с другим номером, поэтому вам может понадобиться отредактировать этот файл для использования его в своей системе.

Этот файл можно назвать MouseMover.bat.

Его вызывают с параметром. Например:

  • MouseMover 540 (время работы устройства будет установлено в 540 минут).
  • MouseMover 0 (устройство будет выключено).

После того, как создан файл MouseMover.bat, можно создать ярлык, двойной щелчок по которому позволит вызвать этот файл с параметром. Для того чтобы создать ярлык — надо щёлкнуть правой кнопкой мыши по файлу и выбрать в появившемся меню команду Создать ярлык. Будет создан ярлык, которому можно дать какое-нибудь понятное имя, вроде StartMouseMover или StopMouseMover. После переименования ярлыка (если решено было поступить именно так), можно отредактировать его свойства, введя время работы устройства после команды, которая уже имеется в поле Объект вкладки Ярлык. Можно создать и ещё один ярлык, предназначенный для выключения MouseMover. Для этого можно скопировать уже существующий ярлык и ввести 0 там же, где ранее вводилась продолжительность работы устройства. Теперь с помощью одного из этих ярлыков можно будет включить устройство на заданное время, а с помощью другого — отключить.

Для дальнейшей автоматизации работы с Mouse Mover можно воспользоваться задачами Windows. Например, задача может вызывать batch-файл для включения устройства в определённое время или при входе в систему. Для создания задач можно воспользоваться либо графическим интерфейсом планировщика заданий, либо — соответствующими инструментами командной строки. Подробности об этом смотрите в PDF-файле с документацией в репозитории проекта.

В моём случае лучше всего показал себя автоматический запуск устройства с помощью задачи, выполняющейся при входе в систему (а не применение задачи, запускающей устройство в определённое время). При использовании этого метода компьютер будет постоянно работать, не блокируя экран, с того момента, как пользователь войдёт в систему. А после того, как это время истечёт, MouseMover отключится и компьютер, если за ним нет пользователя, может «уснуть» или заблокировать экран. Использование batch-файлов и задач в Windows позволяет вообще не отключать MouseMover от компьютера и попросту забыть об этом устройстве. При этом входить в систему придётся не после каждого небольшого перерыва, а лишь раз в день.

Итоги


Я надеюсь, что MouseMover поможет всем желающим избавиться от одного из неудобств, вызванных корпоративными требованиями к информационной безопасности. Главное — прежде чем пользоваться подобным устройством на работе — почитайте дисклеймер, который можете найти в начале статьи. Конечно, если в этом есть смысл, вы можете пользоваться MouseMover и дома.

Планируете ли вы сделать себе MouseMover?


Adblock test (Why?)

[Перевод] Какие изменения нужны языку Rust, чтобы писать асинхронный код стало проще


Асинхронное программирование — мощный инструмент. Но экосистема Rust продолжает активно развиваться, и пока язык далёк от идеала. В частности, по этой причине многие считают, что асинхронное программирование в Rust — это боль. Однако некоторые не только критикуют, но и предлагают. Среди таких людей автор данной статьи. 

Здесь я расскажу о некоторых ранее предложенных идеях и свяжу их с новыми предложениями. Я проведу некий мысленный эксперимент и постараюсь ответить на вопрос «Что мы могли бы сделать с асинхронным программированием в Rust, если бы нам дали полный карт-бланш?». 

Непродуманное внесение изменений в Rust может разрушить его. Поэтому всё нужно делать аккуратно, учитывая плюсы и минусы. Допускаю, что некоторые предложения могут вызвать негативную реакцию. Я отношусь к этому с пониманием и прошу читателя подойти к изучению этого материала максимально непредвзято.

Потоки vs Асинхронность


Писать асинхронный код зачастую сложнее, чем просто использовать потоки. Но с потоками мы не можем получить выигрыш в производительности, так как они слишком прожорливые. В процессе переключения между разными потоками и обмена данными между ними возникает много накладных расходов. Даже поток, который сидит и ничего не делает, использует ценные системные ресурсы. Чаще всего, асинхронный код работает гораздо быстрее. Но не всегда:

Например, этот echo server написан с использованием потоков. Он работает быстрее своей асинхронной версии — для случая, когда количество одновременных подключений не превышает 100.
На мой взгляд, лучший аргумент в пользу асинхронности таков:

  • она позволяет эффективно моделировать сложный процесс управления потоком исполнения. 

Например, приостановку или отмену операции на лету будет сложно реализовать, не сделав эту операцию асинхронной. Или в случае, когда несколько потоков (одно соединение на один поток) конкурируют за ограниченный ресурс, приходится использовать примитивы синхронизации. Применяя концепцию асинхронности, мы можем добиться более высокой производительности, работая с несколькими соединениями в одном потоке.

Главная проблема с асинхронностью в Rust


Поначалу кому-то может показаться, что писать асинхронный код на Rust легко. Но его мнение изменится после первых трудностей, которые связаны с подводными камнями, не описанными в документации. Энтузиасты пытаются сами вести учёт и предлагать решения. Копать нужно сразу в нескольких местах, но на мой взгляд, самая большая проблема с асинхронностью в Rust связана с нарушением принципа наименьшего удивления.
Если назначение элемента или сочетания неясно, то его поведение должно быть наиболее ожидаемым. Код должен вести себя так, как ожидает программист.

В этой статье я буду много раз приводить пример с неким Аланом, который начал изучать Rust и сталкивается с первыми сложностями. 

Итак, Алан прочитал книгу по Rust и доки Tokio. Он хочет написать свой чат-сервер. Алан выбирает простой линейный протокол и для шифрования строк использует префиксный код. Его функция парсинга строк выглядит так:

async fn parse_line(socket: &TcpStream) -> Result<String, Error> {
    let len = socket.read_u32().await?;
    let mut line = vec![0; len];
    socket.read_exact(&mut line).await?;
    let line = str::from_utf8(line)?;
    Ok(line)
}

Этот код очень похож на обычный, не асинхронный, код Rust, за исключением ключевого слова async и вызова .await. Хотя Алан никогда раньше не писал на Rust, он уверен, что знает, как работает эта функция. Как мы увидим позже, он ошибается. При локальном тестировании его чат-сервер работает без ошибок, поэтому Алан отправляет ссылку Барбаре. К сожалению, после небольшой переписки в чате сервер вылетает с ошибкой «invalid UTF-8». Теперь Алан не понимает, в чём дело: он проверяет код и не находит ошибок.

Так в чем проблема? Оказывается, под капотом, в стеке вызовов, используется макрос select! 

Макрос futures::select запускает несколько футур (асинхронных вычислений) одновременно и передаёт управление пользователю, как только любая из футур завершится.

loop {
    select! {
        line_in = parse_line(&socket) => {
            if let Some(line_in) = line_in {
                broadcast_line(line_in);
            } else {
                // соединение закрыто, выходим из цикла
                break;
            }
        }
        line_out = channel.recv() => {
            write_line(&socket, line_out).await;
        }
    }
}

Предположим, что сообщение пришло в чат (через channel) именно в то время, когда parse_line всё ещё занят обработкой данных. Но select! прерывает операцию parse_line, не дав ей завершить парсинг. На следующей итерации цикла parse_line вызывается снова и начинает парсить с середины фрейма, что приводит к чтению тарабарщины.

В этом и заключается проблема: любая асинхронная функция Rust может перестать работать в любое время, так как её могут просто прервать. И это ситуация не является чем-то из ряда вон выходящим. Каким местом должен думать начинающий Rust-разработчик, чтобы понять причину такого поведения? 

Да никаким. Нужно просто изменить это поведение — внести изменения в сам язык. 

Изменение #1: Используем футуры с гарантированным завершением


Если поведение языка не соответствует ожиданиям и интуитивным представлениям, нужно подсказать ученику правильное направление, а не молчать. А по-хорошему, необходимо свести к минимуму вот такие неприятные сюрпризы в процессе обучения, особенно на раннем этапе.

Давайте начнём с исправления проблемы неожиданной отмены (или прерывания) асинхронных операций. Сделаем так, чтобы они выполнялись полностью (впервые эта идея была предложена здесь). Используя футуры с гарантированным завершением, мы добавляем в асинхронный Rust немного блокировок, но оставляем ключевые слова async и await. Создание порождённых задач (с помощью spawn) добавляет параллелизма, а асинхронные каналы (тип Channel) обеспечивают взаимодействие между потоками и обмен задачами. Поэтому передадим в select! каналы или «канальные типы» (например, JoinHandle).

Вот как изменится код из первых двух примеров:

async fn handle_connection(socket: TcpStream, channel: Channel) {
    let reader = Arc::new(socket);
    let writer = reader.clone();
    
    let read_task = task::spawn(async move {
        while let Some(line_in) in parse_line(&reader).await {
            broadcast_line(line_in);
        }
    });
    
    loop {
        // 
        select! {
            res = read_task.join() => {
                // соединение закрыто, выходим из цикла
                break;
            }
            line_out = channel.recv() => {
                write_line(&writer, line_out).await;
            }
        }
    }
}

Теперь все асинхронные операции должны выполняться полностью, select! принимает только канальные типы, вызов parse_line () перемещается внутрь  порождённой задачи. Эти небольшие изменения в коде могли бы предотвратить проблему, с которой столкнулся Алан. Если Алан попытается вызвать parse_line () внутри  select!, он получит ошибку компилятора с рекомендацией создать задачу, чтобы внутри неё вызывать эту функцию. 

При использовании канальных типов внутри select! можно не переживать, что какие-то ветки не выполнятся. Каналы могут хранить значения атомарно. От того, что какие-то ветки не проработают, данные не потеряются.

Отмена асинхронной операции


Что произойдет, если при записи возникнет ошибка? В приведённом выше коде read_task продолжит работать. Но вместо этого Алан хочет, чтобы ошибка приводила к корректному закрытию соединения и всех задач. К сожалению, здесь мы уже начинаем сталкиваться с проблемами проектирования языка. 

Если бы мы могли прервать любую асинхронную операцию в любой момент, всё бы решалось принудительным завершением футуры. Но теперь-то мы ввели футуры с гарантированным завершением! Возвращаться назад мы не будем, придётся внести в Rust новые изменения. 

Возможность отменить операцию на лету — одна из главных причин использования асинхронного подхода. Попробуем использовать метод cancel ():

async fn handle_connection(socket: TcpStream, channel: Channel) {
    let reader = Arc::new(socket);
    let writer = reader.clone();
    
    let read_task = task::spawn(async move {
        while let Some(line_in) in parse_line(&reader).await? {
            broadcast_line(line_in)?;
        }
        
        Ok(())
    });
    
    loop {
        // 
        select! {
            _ = read_task.join() => {
                // соединение закрыто либо будет прервано из-за ошибки,
                // выходим из цикла
                break;
            }
            line_out = channel.recv() => {
                if write_line(&writer, line_out).await.is_err() {
                    read_task.cancel();
                    read_task.join();
                }
            }
        }
    }
}

Но что тут может сделать один cancel ()? Он не может немедленно прервать задачу, потому что мы используем футуры с гарантированным завершением. А мы хотим, чтобы отменённая задача прекратила работу и завершилась как можно скорее. К сожалению, вместо этого она просто вернёт ошибку «interrupted». Дальнейшие попытки использования ресурсов в этой задаче также приведут к ошибкам. 

В итоге задача зависает на неопределённое время, продолжая выдавать сообщения об ошибках. Правда, в какой-то момент она всё-таки завершается.

Обнаружив такое странное поведение, Алан мог бы попытаться выяснить, что именно происходит, пока задача висит. Для этого можно добавить в код оператор println! или использовать другие способы отладки.

Явные и неявные вызовы .await


Без ведома Алана, его чат-сервер избегает большинства системных вызовов с помощью io_uring (это интерфейс взаимодействия с ядром Linux, позволяющий асинхронно отправлять и получать данные). Асинхронный Rust может прозрачно использовать io_uring API благодаря футурам с гарантированным завершением. Когда Алан сбрасывает значение TcpStream в конце handle_connection (), сокет должен асинхронно закрыться. Реализация AsyncDrop для TcpStream  выглядит так:
impl AsyncDrop for TcpStream {
    async fn drop(&mut self) {
        self.uring.close(self.fd).await; // тут await вызывается НЕЯВНО!
    }
}

И как быть, когда .await вызывается неявно? Этот вопрос остаётся открытым. Сегодня для асинхронного ожидания завершения футуры требуется вызов .await. В этом случае трейт AsyncDrop добавляет ещё один подводный камень, когда управление выходит за пределы области видимости асинхронного контекста. Такое поведение нарушает принцип наименьшего удивления. Зачем нужны неявные вызовы .await, если наряду с ними используются явные?

Напрашивается решение проблемы в лоб: 

  • все вызовы .await сделать явными.

my_tcp_stream.read(&mut buf).await?;
async_drop(my_tcp_stream).await;

А если, например, пользователь забудет сделать вызов async_drop(my_tcp_stream).await — что произойдет? Заметьте, что в приведённом выше фрагменте кода есть ошибка: оператор ? пропустит вызов async_drop, если чтение выполнится некорректно. Компилятор Rust может выдать предупреждение, указывающее на проблему, но как решить её?

Изменение #2: Отказываемся от .await


А что, если вместо требования явно вызывать async_drop (...).await, мы вообще удалим ключевое слово await? Тогда его не придётся писать после вызова каждой асинхронной функции (например, socket.read_u32 ().await). Однако, тогда при вызове асинхронных функций (с ключевым словом async) все вызовы .await становятся неявными.

Такой ход мыслей может показаться непоследовательным. И это так. Но все наши предложения и гипотезы нужно проверять. Неявный .await имеет ограниченное применение и зависит от контекста, поскольку встречается только в асинхронных операциях. Алану достаточно взглянуть на определение функции (на ключевое слово async), чтобы понять, что он находится в асинхронном контексте. Более того: легче станет не только Алану, но и анализаторам кода.

Отказ от явных вызовов .await имеет ещё одно преимущество: код становится больше похож на Rust без асинхронности. И тогда единственным заметным отличием становится необходимость аннотировать определённые функции ключевым словом async. В этом случае и проблема «ленивых футур» (которые запускаются только по необходимости) тоже отпадает сама собой, поэтому Алан не сможет «случайно» написать такой код и удивиться, почему «two» печатается первым.

async fn my_fn_one() {
    println!("one");
}

async fn my_fn_two() {
    println!("two");
}

async fn mixup() {
    let one = my_fn_one();
    let two = my_fn_two();
    
    join!(two, one);
}

Один из RFC-запросов в своё время действительно вызвал некую дискуссию по теме неявных вызовов .await. В то время наиболее убедительным аргументом против было то, что неявные вызовы .await увеличивают количество непредвиденных ситуаций, в которых асинхронная операция может быть прервана. Но в случае с футурами с гарантированным завершением этот аргумент теряет силу. 

Как бы то ни было, отказ от явных вызовов .await — это очень серьёзное изменение, и к нему нужно подходить осторожно. Соответствующие исследования должны выявить, насколько плюсы перевешивают минусы.

Изменение #3: Отказываемся от Arc и используем scoped tasks


Теперь Алан может разработать свой чат-сервер с помощью асинхронного Rust, не заглядывая под капот и не сталкиваясь с неожиданным поведением. Компилятор рекомендует ему использовать канальные типы и добавить async к своим функциям, и эти рекомендации действительно работают. Он показывает свой код Барбаре и спрашивает, нужно ли использовать Arc для сокета (let reader = Arc::new(socket);).

Барбара вместо этого предлагает ему посмотреть в сторону scoped tasks. Это асинхронный эквивалент scoped threads. Задачи такого типа способны заимствовать данные, принадлежащие своему «родителю». 

async fn handle_connection(socket: TcpStream, channel: Channel) {
    task::scope(async |scope| {
        let read_task = scope.spawn(async || {
            while let Some(line_in) in parse_line(&socket)? {
                broadcast_line(line_in)?;
            }

            Ok(())
        });
        
        loop {
            // 
            select! {
                _ = read_task.join() => {
                 // соединение закрыто либо будет прервано из-за ошибки,
                // выходим из цикла
                    break;
                }
                line_out = channel.recv() => {
                    if write_line(&writer, line_out).is_err() {
                        break;
                    }
                }
            }
        }
    });
}

Такое решение должно гарантировать выполнение асинхронных операций полностью. Но у него есть недостаток: для использования scoped tasks придётся сделать метод Future::poll небезопасным, поскольку теперь мы не сможем опрашивать футуру до её завершения. Разработчикам языка придётся добавить в язык небезопасную реализацию типажа Future. Придётся реализовать такие трейты, как AsyncRead и AsyncIterator. Но я считаю, что это достижимая цель.

Гарантия завершения асинхронных операций также позволит передавать указатели из scoped task в ядро Linux ​​при использовании io_uring или при интеграции с футурами C++. 

Изменение #4: Отказываемся от FuturesUnordered


Сегодня в асинхронных Rust приложениях можно обеспечить параллелизм, порождая новую задачу, используя select! или FuturesUnordered. До сих пор мы много говорили про первые два варианта. Я и дальше предлагаю не говорить про FuturesUnordered, так как это частый источник ошибок. При использовании FuturesUnordered легко создавать задачи, ожидая, что они будут работать в фоновом режиме, а затем удивиться, что они не показывают никакого прогресса.

«Имитировать» FuturesUnordered можно с помощью тех же scoped tasks и TaskSet. Это гораздо надёжнее.

let greeting = «Hello».to_string();

task::scope(async |scope| {

    let mut task_set = scope.task_set();

    

    for i in 0..10 {

        task_set.spawn(async {

            println!(»{} from task {}», greeting, i);

            

            i

        });

    }

    

    async for res in task_set {

        println!(«task completed {:?}», res);

    }

});

Каждая порождённая задача выполняется параллельно, заимствуя данные из порождающей задачи, а TaskSet предоставляет API, аналогичный FuturesUnordered. Такие примитивы, как buffered stream, также могут быть реализованы за счёт scoped tasks.

Текущая модель асинхронного Rust не позволяет исследовать другие примитивы параллелизма. Это могло бы стать возможным, если бы мы сделали Rust с гарантированным завершением асинхронных операций (к которому мы пришли в этой статье).

Изменение #5: Добавляем опцию #[abort_safe]


В начале статьи я утверждал, что использование асинхронного программирования позволяет нам эффективно моделировать сложное управление потоком исполнения. Самый эффективный примитив, который у нас есть сегодня, — это select!.. Я ранее предложил в этой статье использовать его, правда только с канальными типами. Но тогда нужно порождать две задачи для каждого соединения — для одновременного чтения и записи. Порождённые задачи действительно помогают предотвратить ошибки при отмене (прерывании) операции. Но попробуем найти более эффективное решение и переписать операцию чтения для случая её неожиданного прерывания.

Например, mini-redis при парсинге фреймов сначала сохраняет полученные данные в буфере. При прерывании операции чтения данные не теряются, потому что они находятся в буфере. Следующий вызов чтения возобновится с того места, где мы остановились. Такую реализацию можно назвать «abort_safe».

Что, если вместо использования select! для канальных типов мы применим abort_safe операции. Такие операции, как приём данных из канала или чтение из буферизованного дескриптора ввода-вывода по умолчанию являются abort_safe. Нам повезло. Но вместо этого мы потребуем, чтобы разработчик явно указывал #[abort_safe] при реализации соответствующей функции. Это более выигрышная стратегия.

#[abort_safe]

#[abort_safe]
async fn read_line(&mut self) -> io::Result<Option<String>> {
    loop {
        // взять всю строку из буфера
        if let Some(line) = self.parse_line()? {
            return Ok(line);
        }

        // в буфере недостаточно данных для парсинга всей строки
        if 0 == self.socket.read_buf(&mut self.buffer)? {
            // удалённый сервер закрыл соединение.
            if self.buffer.is_empty() {
                return Ok(None);
            } else {
                return Err("connection reset by peer".into());
            }
        }
    }
}

Вместо того, чтобы использовать операции abort_safe (с безопасным прерыванием), по умолчанию, мы сделаем это опцией (можно сравнить с opt-in в маркетинге). На такую опцию можно как бы добровольно «подписаться». Когда разработчик знакомится с таким кодом, аннотация сообщает ему, что те и вот эти функции должны быть abort_safe. Компилятор Rust может даже выдавать дополнительные проверки и предупреждения для функций, помеченных #[abort_safe].

Теперь Алан может использовать свою функцию read_line () с «select!», но без канальных типов.

loop {
    select! {
        line_in = connection.read_line()? => {
            if let Some(line_in) = line_in {
                broadcast_line(line_in);
            } else {
                // соединение закрыто, выходим из цикла
                break;
            }
        }
        line_out = channel.recv() => {
            connection.write_line(line_out)?;
        }
    }
}

Учтите, что в коде можно использовать сочетание функций с опцией #[abort_safe] и без неё. Вызов abort_safe функции всегда возможен как из безопасного, так и из небезопасного контекста. Обратное неверно: компилятор Rust предотвратит вызов небезопасных функций безопасного контекста, и выведет соответствующее сообщение об ошибке.
async fn must_complete() { ... }

#[abort_safe]
async fn can_abort() {
    // Invalid call => compiler error
    must_complete();
}
 
async fn must_complete() { ... }

#[abort_safe]
async fn can_abort() {
    // Valid call
    spawn(async { must_complete() }).join();
}

Разработчик всегда может создать новую задачу, чтобы связать небезопасную функцию с безопасным контекстом.

Включение двух разновидностей асинхронных функций усложнит язык, но эта сложность появится на поздних этапах обучения. Нужно начинать изучение асинхронного Rust в небезопасном контексте (без учёта abort_safe). Из этого контекста обучающийся может вызывать асинхронные функции независимо от данной опции. Информация о ней будет доступна в последних, продвинутых, главах руководства по асинхронному Rust. 

По крайней мере, вот так я себе это всё представляю.


Для перехода от текущей асинхронной модели с abort_safe операциями по умолчанию к модели с гарантированным завершением потребуется существенно доработать Rust. Допустим, все работы будут завершены к 2026 году. Обычные футуры будут изменены на футуры с гарантированным завершением. Вместо этого старые (обычные) футуры в версии 2026 года будут жить под именем AbortSafeFuture.

Именно добавление #[abort_safe] к асинхронным функциям приведёт к появлению AbortSafeFuture вместо старой Future. Любая асинхронная функция, написанная в версиях Rust до 2026 года, должна иметь возможность использовать AbortSafeFuture. Это сделает весь существующий асинхронный код совместимым с новой версией (напомним, что abort_safe функция, может быть вызвана из любого контекста).

Обновление старой кодовой базы языка потребует добавления #[abort_safe] ко всем асинхронным функциям. Это механический процесс, можно легко автоматизировать его. Чтобы добавить поддержку асинхронного Rust с гарантированным завершением в среду исполнения Tokio, её тоже придётся основательно переработать.


Я рассказал о нескольких изменениях, которые, как мне кажется, помогут упростить асинхронное программирование в Rust:
  1. Используем футуры с гарантированным завершением
  2. Отказываемся от .await
  3. Отказываемся от Arc и используем scoped tasks
  4. Отказываемся от FuturesUnordered и расширяем возможности параллелизма
  5. Добавляем опцию #[abort_safe]

Они также помогут усовершенствовать сам механизм выполнения асинхронных операций. Но прежде чем принимать какие-либо решения, нам нужно больше экспериментальных данных. Какой процент сегодняшнего асинхронного кода защищён от нежелательных прерываний?

Можем ли мы провести достаточно исследований, чтобы оценить потенциальную пользу от этих изменений? И наоборот: насколько тяжелее будет изучать и программировать на Rust, если появится два вида асинхронных функций (с опцией abort_safe и без неё)?

Надеюсь, что эта статья также вызовет дискуссию, и, возможно, вы предложите альтернативные решения. Пришло время пробовать самые смелые идеи.



VDS/VPS хостинг с быстрыми NVMе-дисками и посуточной оплатой. Загрузка своего ISO.

Adblock test (Why?)

Дружимся с ESP

Здравствуйте, коллеги и энтузиасты!

Последние пару лет практически все прототипирование несложных IoT-устройств я делаю на NodeMCU, хотя зачастую она и великовата по размеру, и дороговата, и избыточна по функционалу. А все потому, что имела неудачный опыт с ESP-01, которая совершенно не поддавалась прошивке. Сейчас пришло время преодолеть этот барьер и освоить другие железки, от которых мне нужно следующее - Wi-Fi и пины для подключения периферии.

В этой статье разберем подключение к платформе Интернета вещей наиболее популярных плат с интерфейсом Wi-Fi. Их можно использовать, чтобы управлять своим устройством дистанционно или чтобы снимать показания с сенсоров через интернет.

Несколько представленных в статье модулей (ESP-01, ESP-07, ESP-12E, ESP-12F) и плат (Goouuu Mini-S1, WeMos D1 mini и NodeMCU V2) базируются на контроллере ESP8266, использование которого позволяет простым и дешевым способом добавить в своё устройство беспроводную связь через Wi-Fi. 

Так выглядит модельный ряд модулей на базе чипа ESP8266. 

Последняя плата из тех, о которых я расскажу (ESP32 WROOM DevKit v1), построена на контроллере семейства ESP32 - более продвинутой по своим возможностям версии ESP8266. 

Все представленные модели можно программировать и загружать прошивки через Arduino IDE точно так же, как при работе с Arduino.

Настройка среды программирования Arduino IDE

По умолчанию среда IDE настроена только на AVR-платы. Для платформ, представленных ниже, необходимо добавить в менеджере плат дополнительную поддержку.

1) Открываем среду программирования Arduino IDE.

2) В пункте меню File (Файл) выбираем Preferences (Настройки). В окне Additional Boards Manager URLs вводим через запятую адреса http://arduino.esp8266.com/stable/package_esp8266com_index.json и https://dl.espressif.com/dl/package_esp32_index.json.

http://arduino.esp8266.com/stable/package_esp8266com_index.json, https://dl.espressif.com/dl/package_esp32_index.json

3) Нажимаем OK.

4) В пункте меню Tools (Инструменты) -> Board (Плата) выбираем Boards manager (Менеджер плат).

Находим в списке платформы на ESP8266 и нажимаем на кнопку Install (Установить).

6) Надпись INSTALLED сообщает, что дополнения успешно установлены.

7) Аналогичным образом устанавливаем дополнение для ESP32.

8) Теперь нам доступны к программированию платформы с модулем ESP8266 и ESP32.

9) Для подключения плат к платформе Интернета вещей используем библиотеку EspMQTTClient. Чтобы ее установить, в пункте меню Tools (Инструменты) выбираем Manage Libraries (Управлять библиотеками). Находим и устанавливаем библиотеку EspMQTTClient. Может появиться сообщение об установке дополнительных библиотек. Выбираем “Install all”.

Примечание - Также для работы с платами понадобится установить драйверы CH340 (WeMos и Goouuu) и CP2102 (для остальных). Их отсутствие повлияет на то, найдет ли Arduino IDE COM-порт, к которому подключена плата.

Код прошивки

Для прошивки всех используемых ниже модулей используем один и тот же код.

Основные функции:

  1. Установка Wi-Fi соединения

  2. Подключение к объекту на платформе Rightech IoT Cloud по протоколу MQTT

  3. Отправка рандомных значений по температуре ("base/state/temperature") и влажности ("base/state/humidity") каждые 5 секунд (PUB_DELAY)

  4. Получение сообщений о переключении света ("base/relay/led1")

#include "Arduino.h"
#include "EspMQTTClient.h" /* https://github.com/plapointe6/EspMQTTClient */
                           /* https://github.com/knolleary/pubsubclient */
#define PUB_DELAY (5 * 1000) /* 5 seconds */

EspMQTTClient client(
  "<wifi-ssid>",
  "<wifi-password>",

  "dev.rightech.io",
  "<ric-mqtt-client-id>"
);

void setup() {
  Serial.begin(9600);  
}

void onConnectionEstablished() {
  client.subscribe("base/relay/led1", [] (const String &payload)  {
    Serial.println(payload);
  });
}

long last = 0;
void publishTemperature() {
  long now = millis();
  if (client.isConnected() && (now - last > PUB_DELAY)) {
    client.publish("base/state/temperature", String(random(20, 30)));
    client.publish("base/state/humidity", String(random(40, 90)));
    last = now;
  }
}

void loop() {
  client.loop();
  publishTemperature();
}

Работоспособность кода будем проверять на платформе Rightech IoT Cloud, именно поэтому в качестве адреса MQTT-брокера указан dev.rightech.io. Идентификаторами клиентов служат идентификаторы объектов, созданных на платформе. Под каждую проверку я завела на платформе отдельный объект, именно поэтому во всех скринах кодов, которые будут далее представлены, отличается только строка <ric-mqtt-client-id>. 

Прим. - Можно подключаться и к одному и тому же объекту, тогда можно использовать один и тот же код для прошивки всех плат без изменений, однако следите, чтобы в таком случае платы не подключались к одному и тому же объекту одновременно, иначе случится коллизия.

Модули на базе ESP8266

Для работы с модулями на базе ESP8266 есть два варианта:

  1. Работа с AT командами (в стандартной прошивке Wi-Fi модуль общается с управляющей платой через «AT-команды» по протоколу UART);

  2. Wi-Fi модуль как самостоятельный контроллер (все представленные модули очень умные: внутри чипа прячется целый микроконтроллер, который можно программировать на языке C++ через Arduino IDE).

В статье будем рассматривать второй вариант - прошивка модулей в виде самостоятельного полноценного устройства. Здесь также есть два варианта прошивки с точки зрения железа:

  1. Через плату Arduino;

  2. ЧерезUSB-Serial адаптер.

Рассмотрим второй вариант - использовать адаптер на базе чипа CP2102 (например, такой https://www.chipdip.ru/product/cp2102-usb-uart-board-type-a?frommarket=https%3A%2F%2Fmarket.yandex.ru%2Fsearch%3Frs%3DeJwzSvKS4xKzLI&ymclid=16146772489486451735000001). Обязательно обратите внимание на то, чтобы адаптер позволял выдавать выходное напряжение 3.3 В, не больше!

1. ESP-01

ESP-01 - самый популярный модуль на ESP8266. PCB антенна обеспечивает дальность до 400 м на открытом пространстве. 

Внешний вид

Питание

Родное напряжение модуля — 3,3 В. Его пины не толерантны к 5 В. Если вы подадите напряжение выше, чем 3,3 В на пин питания, коммуникации или ввода-вывода, модуль выйдет из строя.

Подключение периферии

2 порта ввода-вывода общего назначения

Распиновка

Подключение к IoT

Аппаратная часть

1) Собираем схему

ESP-01

USB-Serial

VCC

VCC

CH_PD

VCC

TX

RX

RX

TX

GND

GND

GPIO 0 - сначала не подключен, но будет использоваться для перевода в режим программирования далее, поэтому к нему уже подведен провод

RST, GPIO 2 - не подключены

RTS, CTS - не подключены

2) Переводим в режим программирования (необходимо каждый раз выполнять перед прошивкой модуля)

2.1) Отключаем питание от модуля

2.2) Подключаем пин GPIO 0  к GND

ESP-01

USB-Serial

VCC

VCC

CH_PD

VCC

TX

RX

RX

TX

GND

GND

GPIO 0

GND

RST, GPIO 2 - не подключены

RTS, CTS - не подключены

2.3) Подключаем модуль к питанию

2.4) Железо готово, приступаем к программной части.

Программная часть

1) Выбираем плату: Tools (Инструменты) -> Board(Плата) Generic ESP8266 Module.

2) Вставляем подготовленный код.

3) Задаем данные для подключения Wi-Fi и идентификатор своего объекта на платформе.

4) Компилируем и загружаем скетч на плату.

5) Для обычной работы модуля (не для режима прошивки) пин GPIO 0 должен быть свободен, поэтому отключаем его от GND.

6) Переподключаем питание ESP-01 (например, вытаскиваем и вставляем обратно адаптер).

7) Видим появление данных на платформе.

Средняя цена

~ 100 рублей

Где купить

Прим. - Здесь и далее даны ссылки на магазины, из которых я либо заказывала сама, либо мне их рекомендовали. Это не реклама, а просто желание помочь быстрее найти нужную железку. Вы можете заказывать в любых других понравившихся магазинах =)

В России

В Китае

2. ESP-07

Особенности этого модуля - керамическая антенна и разъем для внешней антенны, металлический экран.

Внешний вид

Питание

3 - 3,6 В

Подключение периферии

  • 9 портов ввода-вывода общего назначения

  • 1 аналоговый вход

Распиновка

Подключение к IoT

Аппаратная часть

Работа с этим модулем, к сожалению, прошла не слишком гладко. Ни один из возможных вариантов подключения не сработал, и я, уже отчаявшись, решила удалять его описание из статьи. Но тут мне дали новый модуль и сказали попробовать еще раз - о чудо, он заработал с первого раза! В чем было дело и как сломался первый модуль, который я мучила, - неизвестно, но скорее всего он был убит нещадной статикой. Мораль этого лирического отступления такова - если у вас что-то не заработало по инструкции, написанной ниже, не вините инструкцию - сначала прозвоните и проверьте все контакты, а потом попробуйте на другом модуле.

1) Собираем схему

ESP-07

USB-Serial

VCC

VCC

CH_PD (рекомендуется через резистор)

VCC

TX

RX

RX

TX

GND

GND

GPIO 15 (рекомендуется через резистор)

GND

GPIO 0 - сначала не подключен, но будет использоваться для перевода в режим программирования далее, поэтому к нему уже подведен провод

все остальные контакты не подключены

RTS, CTS - не подключены

На фото этого и следующего модуля уже можно заметить резисторы. После неведомой поломки уже решила перестраховаться и поставила килоомники, хотя и без них все должно работать.

2) Переводим в режим программирования (необходимо каждый раз выполнять перед прошивкой модуля)

2.1) Отключаем питание от модуля2.2. Подключаем пин GPIO 0  к GND

2.2) Подключаем пин GPIO 0  к GND

ESP-07

USB-Serial

VCC

VCC

CH_PD

VCC

TX

RX

RX

TX

GND

GND

GPIO 15 

GND

GPIO 0

GND

все остальные контакты не подключены

RTS, CTS - не подключены

2.3) Подключаем модуль к питанию

2.4) Железо готово, приступаем к программной части.

Программная часть

1) Выбираем плату: Tools (Инструменты) -> Board(Плата) Generic ESP8266 Module.

2) Вставляем подготовленный код.

3) Задаем данные для подключения Wi-Fi и идентификатор своего объекта на платформе.

4) Компилируем и загружаем скетч на плату.

5) Для обычной работы модуля (не для режима прошивки) пин GPIO 0 должен быть свободен, поэтому отключаем его от GND.

6) Переподключаем питание ESP-07 (например, вытаскиваем и вставляем обратно адаптер).

7) Видим появление данных на платформе.

Средняя цена

~ 160 рублей

Где купить

В России

В Китае

3. ESP-12E

Внешний вид

Питание

3 - 3,6 В

Подключение периферии

  • 17 портов ввода-вывода общего назначения

  • 1 аналоговый вход

Распиновка

Подключение к IoT

Аппаратная и программная часть абсолютно такая же, как и в двух вариантах выше.

1) Выбираем плату: Tools (Инструменты) -> Board(Плата) Generic ESP8266 Module.

2) Вставляем подготовленный код.

3) Задаем данные для подключения Wi-Fi и идентификатор своего объекта на платформе.

4) Компилируем и загружаем скетч на плату.

5) Для обычной работы модуля (не для режима прошивки) пин GPIO 0 должен быть свободен, поэтому отключаем его от GND.

6) Переподключаем питание ESP-12 (например, вытаскиваем и вставляем обратно адаптер).

7) Видим появление данных на платформе.

Средняя цена

~ 170 рублей

Где купить

В России

В Китае

4. ESP-12F на Wi-Fi Troyka-модуль

Внешний вид

Разберемся с этим модулем на примере его распайки на Wi-Fi Troyka-модуль производства Амперки. Хоть он и дороже, но взаимодействовать с ним гораздо приятнее. Уже есть ножки, распаянные со со стандартным шагом 2,54 мм, дополнительные защиты, регуляторы напряжения, которые помогают избежать неожиданного поведения и поломок при первых опытах. К слову, когда у меня в далекие времена не получалось подружиться с ESP-01, а время уже поджимало, я взяла этот модуль, и все дальше пошло гладко.

Питание

Рабочее напряжение ESP8266 — 3,3 вольта. Но на Troyka-модуле предусмотрен стабилизатор уровня напряжения, поэтому он работает и от 5 В.

Подключение периферии

5 портов ввода-вывода общего назначения

Максимальный ток с пина: 12 мА

Распиновка

Подключение к IoT

Аппаратная часть

Опять же подключаем через адаптер. На сайте Амперки есть прекрасная схемка. 

1) Собираем схему

Troyka

USB-Serial

VCC

VCC

TX

RX

RX

TX

GND

GND

все остальные контакты не подключены

RTS, CTS - не подключены

2) Переводим в режим программирования (необходимо каждый раз выполнять перед прошивкой модуля)

2.1) Зажимаем кнопку PROG

2.2) Нажимаем и отпускаем кнопку RESET

2.3) Отпускаем кнопку PROG

Программная часть

1) Выбираем плату: Tools (Инструменты) -> Board(Плата) Generic ESP8266 Module.

2) Вставляем подготовленный код.

3) Задаем данные для подключения Wi-Fi и идентификатор своего объекта на платформе.

4) Компилируем и загружаем скетч на плату.

5) Переподключаем питание (например, вытаскиваем и вставляем обратно адаптер).

6) Видим появление данных на платформе.

Текущая цена

~ 850 рублей

Где купить

В России

Платы на базе ESP8266

Если с модулями приходилось немного повозиться, то все представленные ниже платы можно сразу подключать к USB-порту компьютера.

1. Goouuu Mini-S1

Внешний вид

Питание

5 В (Крайне не рекомендуется запитывать через вывод 3V3. Входящее напряжение будет поступать на чип ESP8266 напрямую, минуя все защиты от перенапряжения и короткого замыкания.)

Подключение периферии

  • 11 цифровых входов/выходов

  • 1 аналоговый вход

Выходы питания 3.3 В и 5 В.

Распиновка

Подключение к IoT

1) Выбираем плату: Tools (Инструменты) -> Board(Плата) Wemos D1 R1 (или Generic ESP8266 Module, так тоже работает).

2) Вставляем подготовленный код.

3) Задаем данные для подключения Wi-Fi и идентификатор своего объекта на платформе.

4) Компилируем и загружаем скетч на плату.

5) Видим появление данных на платформе.

Средняя цена

~ 300 рублей

Где купить

В России

В Китае

2. WeMos D1 mini

Внешний вид

Питание

5 В

Подключение периферии

  • 11 цифровых входов-выходов

  • 1 аналоговый вход

Выходы питания 3.3 В и 5 В.

Распиновка

Подключение к IoT

1) Выбираем плату: Tools (Инструменты) -> Board(Плата) Wemos D1 R1 (или Generic ESP8266 Module).

2) Вставляем подготовленный код.

3) Задаем данные для подключения Wi-Fi и идентификатор своего объекта на платформе.

4) Компилируем и загружаем скетч на плату.

5) Видим появление данных на платформе.

Средняя цена

~ 220 рублей

Где купить

В России

В Китае

3. NodeMCU V2

Внешний вид

Питание

5 - 10 В

Подключение периферии

  • 11 портов ввода-вывода общего назначения

  • 1 аналоговый вход

Максимальный выходной ток пина 3V3: 600 мА

Распиновка

Подключение к IoT

1) Выбираем плату: Tools (Инструменты) -> Board(Плата) NodeMCU 1.0 (или Generic ESP8266 Module).

2) Вставляем подготовленный код.

3) Задаем данные для подключения Wi-Fi и идентификатор своего объекта на платформе.

4) Компилируем и загружаем скетч на плату.

5) Видим появление данных на платформе.

Средняя цена

~ 240 рублей

Где купить

В России

В Китае

Плата на базе ESP32

ESP32 WROOM DevKit v1

Внешний вид

Питание

5 - 14 В

Подключение периферии

  • Цифровые входы/выходы: 21 пин 1–5, 12–19, 21–23, 25–27, 32 и 33Контакты ввода-вывода общего назначения. Пины могут быть настроены на вход или на выход. Логический уровень единицы — 3,3 В, нуля — 0 В. Максимальный ток выхода — 12 мА.

  • Цифровые входы: 4 пина 34–36 и 39Контакты ввода общего назначения. Могут быть настроены только на вход.

  • ШИМ: все пины ввода-выводаПозволяет выводить аналоговые значения в виде ШИМ-сигнала с разрядность 16 бит. Максимальное количество каналов 16.

  • АЦП: 15 пинов 2, 4, 12–15, 25–27, 32–36 и 39Позволяет представить аналоговое напряжение в цифровом виде с разрядностью 12 бит.

  • ЦАП: пины 25(DAC1) и 26(DAC2)Аналоговый выход цифро-аналогового преобразователя, который позволяет формировать 8-битные уровни напряжения.

Максимальный выходной ток пина 3V3: 1 А

Распиновка

Подключение к IoT

1) Выбираем плату: Tools (Инструменты) -> Board(Плата) DOIT ESP32 DEVKIT V1.

2) Вставляем подготовленный код.

3) Задаем данные для подключения Wi-Fi и идентификатор своего объекта на платформе.

4) Компилируем и загружаем скетч на плату.

5) Видим появление данных на платформе.

Средняя цена

~ 520 рублей

Где купить

В России

В Китае 


Надеюсь, что данная инструкция станет полезной для всех, кто начнет работать с представленными модулями или их аналогами, поможет в выборе, а также сократит время на поиски алгоритмов подключения.

Ссылка на видеоинструкцию >>> https://youtu.be/7XzaUGr3-BA

Adblock test (Why?)