USB устройство своими руками
Мы хотим сделать так, чтобы наши устройства управлялись с компьютера программой и можно было использовать возможности компьютера для управления машиной. Для этого нам надо организовать связь по USB между нашим устройством и программой на компьютере.
Прежде чем приступить к этому вы должны были в предыдущей статье ознакомится с Управлением машиной и получить знания о том, что такое микроконтроллер AVR. Если этого не было, сделайте это.
Далее нам надо для связи по USB сделать устройство, программу для микроконтроллера AVR и программу для компьютера.
USB управление для своего устройства
Берем кабель USB и с одной стороны срезаем провода, видим 4 провода, которые нам нужны — красный, чёрный, жёлтый (бывает зеленым) и белый. Красный провод — это плюс питания +5V, чёрный провод — это минус питания. Этими проводами запитываем наше устройство. А другие 2 провода — жёлтый D+ и белый D- используются для обмена данными по USB.
Схема USB устройства на микроконтроллере AVR
На рисунке показана схема простого самодельного USB устройства. Оно выполнено со всеми требованиями стандарта USB и при корректной сборке отлично работает. Встроенной частоты, на которой может работать USB в микроконтроллере AVR нет, поэтому потребуется установить внешний генератор частоты в 12 МГц, а для сглаживания сигнала от него еще два конденсатора по 20 пФ. По документации на используемый микроконтроллер AVR узнаем куда подключается внешний генератор частоты на том микроконтроллере, который мы используем. В данном случае это линии PA1 и PA0, в других же микроконтроллерах побольше обычно есть линии XTAL, тут их нет, поэтому подключаем куда написано вместо них.
Красным и чёрным проводом запитываем микроконтроллер — эти линии просто подключаются к VCC и GND. Линии с данными USB — это D+ и D- подключаются к линиям микроконтроллера, не к случайным, а к тем что заданы в программе для микроконтроллера, которую позднее будем делать, сразу скажу что это будут линии PD2 и PD4. Просто так нельзя подключать их, надо на пути поставить резистор на 68 Ом по требованию стандарта USB и еще снизить напряжение на данных линиях с 5V до 3.6V. Для резисторов посчитаем их мощность — ток USB задается в программе для микроконтроллера и мы его зададим на уровне 0.05 A, значит мощность резисторов 0.05 A * 5 V = 0.25 Вт. Такие и берем. Напряжение снижается параллельным подключением дидов Зенера 3V6 как показано на рисунке, эти диоды надо воткнуть правильной стороной, напомню что чёрная полоска на диоде с одной стороны должна быть направлена в сторону линий D+ и D-, а обратная сторона к минусу питания. И последнее, чтобы работало устройство USB, надо резистором в 1.5 кОм указать режим его работы, подключаем его к D-, это означает низкоскоростной режим, который нам нужен, поскольку мы не планируем передавать большие объемы данных, а только будем посылать простые сигналы, низкоскоростной режим нам нужен. Чтобы увидить что наше устройство работает, подключим светодиод к линии PB0, длинной плюсовой стороной к линии, а другой стороной к минусу питания.
Также воспользуемся вспомогательными инструментами для удобства — это зажим на 20 гнезд, чтобы легко извлекать микроконтроллер для перепрограммирования. И это 2 клеммника, чтобы прикрутить провода USB к макетной плате. Вообщем для сборки устройства нам потребуется сделать такой закуп:

Это: Микроконтроллер
Контакты: 20
Программа: 2 Kb

Сопротивление: 68 Ом
Мощность: 0.25 Вт

Пропускает: 3.6 В
Тип: Понижающий

Сопротивление: 1.5 кОм
Мощность: 0.25 Вт

Частота: 12 МГц
Тип: пассивный

Емкость: 20 pF
Тип: Керамический
Макс. напряжение: 50 V

Цвет: Белый
Напряжение: 3 V

Гнезда: 10 x 10

Контактов: 2
Зажим: прикрутка

Интерфейс: USB 2.0
Длина: 100 см

Размер: 63 x 2 горизонтальных линий и 4 вертикальные линии

Тип: Навесные
Количество: 40

Количество: 140
Собранное готовое к работе USB устройство выглядит так:
USB устройство своими руками
Программа на микроконтроллер AVR для USB связи
1) Скачиваем исходные коды OpenRoboFW и распакуйте архив на диск C:\, я собрал этот архив из файлов проекта V-USB, настроил их на Attiny2313A и тактовую частоту 12 МГц (эти настройки меняются в файле Makefile, если используется другой микроконтроллер), упростил код для внесения изменений. V-USB дает нам исходники программ с идентификаторами VID и PID, которые нужны для распознания USB устройства компьютером. На всякий случай вот ссылка на проект . После распаковки архива содержимое директории выглядит так:
![]() |
Назначение важных файлов: main.c — главный файл программы на языке C, она осуществляет обработку информации, пришедшей по USB, и в ней программируется реакция микроконтроллера на USB пакеты с компьютера Makefile — параметры сборки, тип микроконтроллера (взяли — attiny2313a), частота, информация по фьюзам для других микроконтроллеров, при использовании другого микроконтроллера, в этом файле его нужно прописать в строке DEVICE (например — atmega16a) usbconfig.h — параметры USB, порт подкючения линии D-, ток |
Откройте main.c и обратите внимание на 2 области кода, которые там выделены — программа реакции на USB пакет и настройка портов. В этих областях надо вставлять свой код, остальное можно не трогать. Для примера там уже стоит код, его можно менять. В приходящем пакете USB с компьютера есть 2 параметра — p1 и p2, которые передаются из программы в виде параметров, в зависимости от их значений можно менять состояние линий микроконтроллера (портов) в программе реакции.
2) Скачиваем программу WinAVR и устанавливаем, она нужна для создания HEX-прошивки микроконтроллера AVR, сайт WinAVR
3) Запускаем командную строку Windows, которая находится тут c:\Windows\System32\cmd.exe появляется чёрное окно. В этом окне вводим 2 команды (набираем команду, нажимаем enter):
Переходим в директорию OpenRoboFW
Запускаем подготовку программы для микроконтроллера
Подготавливаем программу МК
После чего в директории C:\OpenRoboFW забираем файл main.hex и прошиваем его в микроконтроллер. Если в процессе появилась ошибка типа warning unused variable, а также can not set period, или нечто подобное, что не имеет большого значения, ничего страшного, все в порядке, используем полученный файл, он полностью нормальный и рабочий. Главное если файл появляется, значит программа была успешно сделана и может быть использована. Напоминаю Как прошивать.
Также надо прошить fuse-биты настроек микроконтроллера, чтобы изменить его тактовую частоту на совместимую с USB стандартом. Встроенной подходящей частоты нет, поэтому применяется внешний источник тактовой частоты 12 МГц. Для прошивки настроек fuse-битов устройство с программатором надо доработать, подключить к микроконтроллеру внешний кварцевый генератор 12 МГц и 2 конденсатора 20 пФ по схеме как на устройстве USB, т.е. в случае с ATTiny2313A к линиям PA1 и PA0, и также соединить это всё с минусом питания, вообщем как на схеме USB устройства, смотрите на фото ниже как подключено. Это нужно для того, чтобы устройство продолжило работу после установки для него нового источника тактового сигнала, именно этот источник 12 МГц и подключаем. Не забудьте кроме программы также прошить fuse-биты.
Меняем настройки программатором

Микроконтроллеры: AVR

Частота: 12 МГц
Тип: пассивный

Емкость: 20 pF
Тип: Керамический
Макс. напряжение: 50 V

Размер: 17 x 2 горизонтальных линий

Гнезда: 10 x 10
При этом установите такие биты конфигурации:
Для ATtiny2313A (наш случай):
CKSEL0..3=1111 SUT0..1=10 CKOUT=1 CKDIV=1 RSTDISBL=1 BODLEVEL2..0=101 WDTON=1 SPIEN=0 EESAVE=1 DWEN=1
Установите В справочнике эти fuse-биты и прошейте их в микроконтроллер полученной строкой через программу AVR dude, о том Как прошить тут. Также дам на всякий случай fuse-биты для других микроконтроллеров.
Для ATmega8A:
CKSEL0..3=1111 SUT0..1=10 BODEN=0 BODLEVEL=1 BOOTRST=1 BOOTSZ0..1=00 EESAVE=1 CKOPT=0 SPIEN=0 WDTON=1 RSTDISBL=1
Для ATmega16A:
CKSEL3..0=1111 SUT0..1=10 BODEN=0 BODLEVL=1 BOOTRST=1 BOOTSZ0..1=00 EESAVE=1 CKOPT=0 SPIEN=0 JTAGEN=1 OCDEN=1 LB1..2=00 BLB=0000
Теперь когда программа написана и записана в микроконтроллер, можно проверить правильность сборки устройства. Напишите программу на компьютер для USB связи, читайте далее как это сделать и при этом в процессе будет установлен фильтр для возможности опознания устройства. Подключите устройство к USB порту компьютера, установите фильтр как далее будет описано, если все правильно было собрано и установлено, то оно будет обнаружено и опознано как LEDCtlHID. Если этого не произошло, то ищите проблему и ошибки при сборке устройства или при установке программ, еще раз внимательно все сверьте и проверьте, что ничего не пропущено и что все контакты соединены или запаяны как надо. Бывает проблема тут, если пайка была совершена с неконтактами, с не правильными контактами или не всеми контактами, а также что элементы схемы были повреждены высокой температурой паяльника, и устройство поэтому не работает. Важно собирать устройство именно на макетной плате первый раз.
Программа на компьютер для USB связи
Для начала сделаем простую консольную программу, потом будем делать программу с окнами.
1) Скачиваем исходные коды консольной программы OpenRobo, которые собраны из исходников проектов V-USB и LibUSB. Распаковываем архив на диск C:\, после чего содержимое директории C:\OpenRobo должно выглядеть так:
![]() |
Назначение файлов: include и lib — это драйверы LibUSB для доступа к USB из программы set-led.c — это исходник нашей программы |
2) Скачиваем программу LibUSB, которая нужна для работы с устройством из программы. Устанавливаем. Сайт разработчика LibUSB. После установки подключите собранное устройство к USB. Запустите через меню Пуск/Программы/LibUSB-Win32/Filter Wizard. В открывшейся программе выберите для установки фильтра на порт, в следующем списке выберите только что подключенное устройство, его можно найти по vid:16c0 pid:05df. Нажмите кнопку Install. Если устройства в списке нет, значит вы либо не правильно собрали устройство и оно не опозналось, либо драйверы уже были установлены. В случае смены порта подключения устройства, надо опять заходить и устанавливать фильтр, иначе программа не сможет распознать устройство. Обязательно подключайте устройство USB к тому же порту USB, что был подключен при установке фильтра!
3) Скачиваем программу MinGW, которая нужна для сборки программы из исходника. Устанавливаем. Сайт разработчика MinGW. После установки зайдите в Панель управления, Система, Дополнительные параметры системы, Дополнительно (вкладка), Переменные среды (кнопка), Системные переменные (список), Переменная Path (найти в списке, выделить, нажать кнопку Изменить). Дописываем в поле Значение переменной в конце ;c:\MinGW\bin\ и нажимаем ОК, надеюсь вы установили MinGW в C:\MinGW, иначе надо путь другой прописать.
Настраиваем системную переменную Path для MinGW
4) Запускаем командную строку Windows, которая находится тут c:\Windows\System32\cmd.exe
В этом окне вводим 2 команды (набираем команду, нажимаем enter):
Переходим в директорию OpenRobo
Запускаем подготовку программы для компьютера
Если выходит ошибка, что команды make нет, значит вы не установили выше указанную программу WinAVR, сделайте это. Если выходит ошибка, что команды gcc нет, значит не прописан правильно путь в системную переменную Path, сверьте со скриншотами то как прописано у вас, также возможно командная строка была запущена до прописывания пути, надо перезапустить.
Подготовка программы ПК
5) Теперь смотрим в директорию C:\OpenRobo, там появился готовый файл программы set-led.exe. Не выходим из cmd, здесь же теперь мы можем набрать команды запуска программы и получить результаты:
Включает светодиод
Отключает светодиод
Показывает включен или отключен светодиод
7) Если все сделано правильно, то при подключении USB устройства и наборе команд в консоле, светодиод будет включаться и выключаться.
Изменяем программы под наши нужды
Берём под контроль все порты, прибавляем свои функции. И так, теперь в C:\OpenRobo размещены исходные коды программы для компьютера, а в C:\OpenRoboFW исходные коды программы для микроконтроллера. Их можно изменять, но после каждого изменения надо их занова пересобирать (и перепрошивать микроконтроллер), делать это теперь вы умеете — см. выше пример — пересобрать обе программы можно 4-мя командами в cmd:
Переходим в директорию OpenRoboFW
Запускаем подготовку программы для микроконтроллера
Переходим в директорию OpenRobo
Запускаем подготовку программы компьютера
Нам нужно подключить к управлению все порты микроконтроллера Attiny2313. Свободных линий портов у нас получается 13 штук, под контролем находится сейчас только 1 линия, светодиод подключен к ней. Возьмём под контроль все 13 линий.
Изменение программы для микроконтроллера
1) Открываем файл C:\OpenRoboFW\main.c, находим там область кода, обозначенную как настройка портов, надо установить все свободные порты на вывод командами DDR, меняем содержимое области на следующий код. Код для main.c:
Настроили порт B на вывод записав единицы в DDR
Порт D не весь настраиваем, а по одному биту вбиваем единицы таким образом на биты 0, 1, 3, 5 и 6
Небольшое пояснение этого кода — порт B полностью свободен, все его разряды сразу ставим на вывод, порт A полностью занят, его не трогаем, порт D частично занят, поэтому на вывод ставим только свободные разряды, которые тут и перечисляем — 0, 1, 3, 5, 6.
2) Открываем файл C:\OpenRoboFW\main.c, находим область кода, обозначенную как программа реакции на USB пакет, сделаем, чтобы по команде зажигались светодиоды на всех свободных линиях. Меняем содержимое области на. Код для main.c
Если первое число пришло 1
Записываем единицы в порт B и в части порта D
Если первое число пришло другое
Записываем нули в порт B и в части порта D
Пересобираем и перепрошиваем, убеждаемся, что светодиод работает на всех линиях.
К тому же неплохо бы научится вставлять свои функции, которые будут выполняться по вашим командам, пока есть только on, off, status, нужно добавить еще команд, например добавим команду discoteka, по которой будет вызываться какая-нибудь наша функция в микроконтроллере, например — светодиоды горят через один на порте B. Добавим в микроконтроллере обработку дополнительных кодов, пусть это будет код 2, т.к. 1 и 0 уже используются для функций on и off, из программы для компьютера будем посылать потом микроконтроллеру код 2 функцией, вызываемой по команде discoteka. Опять меняем файл C:\OpenRoboFW\main.c, область реакции. Код для main.c
Если пришла единица
Включить весь порт B
Если пришла двойка
Включить биты порта B через один
Если пришло другое
Вылючить весь порт B
Вставляем обработку кодов таким образом, старые коды 1 и 0 как видите сохранили свои функции (зажечь / потушить светодиоды) и появился еще новый код 2, по которому на порте B выставляется состояние, при котором светодиоды через один горят. Таким же образом можно сюда поставить любые другие коды и написать для них необходимые функции.
Изменение программы для компьютера
1) Открываем файл C:\OpenRobo\set-led.c
2) Надо научиться отправлять микроконтроллеру более сложные сообщения, при приеме которых он будет выполнять нужные функции. Сейчас отправляется только 2 сообщения в переменной isOn — 0 = выключить светодиод, 1 = включить светодиод. Научимся отправлять также код 2 = выставить светодиоды через один на порте B (в предыдущем примере мы подготовили микроконтроллер для обработки этого кода, теперь просто пошлём его программой с компьютера).
3) Редактируем файл set-led.c вставляем сверху от строчки
следующий код, который добавляет новый код вызова 2 для функции микроконтроллера
Код отправляет команду 2 микроконтроллеру, что вызывает там запуск дискотеки. Пересобираем программу для компьютера и нам становится доступна новая команда — discoteka. Таким образом можно вставить любые другие коды и функции для них. В C++ есть функция Sleep(1000); она задаёт задерку выполнения в милисекундах, например 1000 — это 1 секунда. Она полезна, с ней также можете сделать светодиоды мигающими. В будующем эта функция пригодится.
Обратите внимание на функцию usb_control_msg, в ней можно передать 2 изменяемых параметра (в первом у нас передаётся 2 или переменная isOn, которая равна 1 или 0), следующее число (там стоит 0) может передать еще 1 значение, например, 1 переменная может быть всё также быть изначальной командой на on или off, а второй переменной можно передать, например, номер порта, который следует включить. Получить доступ к этим параметрам в программе для микроконтроллера можно по именам p1 и p2, для этого примера p1=2, p2=0.
Как сделать программу для Windows
Чтобы создать программу для Windows, скачайте бесплатное средство разработки программ для Windows . На указанной странице найдите в середине где-то по названию продукт Microsoft Visual C++ 2010 Express и установите его. Но перед этим проверьте, что у вас не установлена программа .NET Framework версии выше 4. Если такая установлена в вашей системе — перед установкой удалите ее. В комплекте будет поставлен фреймворк нужной версии 4 автоматом. Иначе у вас не будут работать проекты, будет возникать ошибка — Microsoft Resource File To COFF Object Conversion не работает при попытке компиляции проекта. Windows update автоматом попытается поставить последнюю версию .NET Framework, нужно такую установку отменить — не перезагружать компьютер с новыми обновлениями, а зайти в Windows Update и снять галочку напротив фреймворка.
1) Заходим на сайт, выбираем русский язык, нажимаем INSTALL NOW.
2) После установки запускаем, нажимаем Создать проект. Для начала создадим простую программу с 1 кнопкой — нажимаем эту кнопку, текст в ней меняется.
3) Выбираем шаблон Приложение Windows Forms, внизу вводим название программы, нажимаем OK.
4) Перетаскиваем справа элемент Button на центральное окно с формой и оставляем его внутри формы.
5) Кликаем на форму и на кнопку, при этом справа внизу есть окно Свойства, его содержимое меняется. В этом окне задаём необходимые свойства элементов — текст кнопки и окна. Редактируем свойство Text, пишем там любой текст, например, Моя кнопка. Текст на кнопке меняется, это видно на форме в центральном окне.
6) Теперь сделаем так, чтобы при нажатии на эту кнопку, ее свойство, которое определяет текст на ней менялось на другое. Так же можно менять любые другие свойства.
7) Делаем двойной клик на кнопке Моя кнопка, которая находится в форме в центральном окне, попадаем в файл кода Form.h (его можно выбрать в любое время слева в меню). В этом файле после двойного клика была создана функций button1_Click (остальной код автоматом был создан по шаблону при создании проекта), курсор находится внутри нее, нажмите Enter, чтобы создать пустую строку, куда и будем писать код.
8) Как можно видеть в этом же файле чуть повыше есть разделы — button1 и form1, там заданы начальные установки для элементов — кнопки и формы. Воспользуемся ими, скопируем внутрь нашей функции клика по кнопке (это место отмечено красной стрелкой) строчку, где устанавливается название кнопки, а именно this->button1->Text = L»Моя кнопка»; Только текст Моя кнопка изменим на Работает!
9) Нажимаем на кнопку с зеленым треугольником, через некоторое время наша программа запустится (если вы не совершили ошибок) и при нажатии на кнопку, текст внутри меняется с Моя кнопка на Работает!
10) Забрать готовую программу (файл .exe) можно в директории текущего пользователя
Весь процесс показан на картинках.
Делаем свою программу для Windows, из которой будем управлять устройством USB
Перенос программы для USB в Windows Forms. Я перенес программу управления из консольного приложения в приложение с окнами Windows и немного улучшил её — сделал управление шаговым двигателем в дополнение к управлению светодиодом, добавил горячие клавиши запуска двигателя в определенном направлении с заданным количеством шагов, управляющие сигналы драйвера шагового двигателя подключены к портам PB7 (шаг), PB6 (направление), PB5 (питание), светодиод подключен к порту PB0. Вы можете просто скачать мой проект для Microsoft Visual C++ 2010 Express Edition (русская версия) и посмотреть как я это сделал.
Сделаем простой AVR микроконтроллер
Меня часто спрашивают: «Чем отличается микроконтроллер от ПЛИС?» Ну что тут можно ответить? Это как бы разные вещи. Микропроцессор последовательно выполняет команды, описанные в его программе. Работа ПЛИС в конечном счете определяется принципиальной электрической схемой, реализованной внутри чипа. Архитектура микроконтроллера, то есть тип процессора, количество портов ввода вывода, интерфейсы, определяется производителем. Микросхема микроконтроллера изготовлена на заводе и изменить ее нельзя. Можно только написать программу, которую он будет исполнять. ПЛИС — это свобода для творчества. Архитектура реализуемого устройства может быть почти любая, лишь бы поместилась вся логика в чип. В ПЛИС можно, например, попробовать реализовать даже и микроконтроллер! Попробуем?
Один из самых распространенных микроконтроллеров — это 8-ми разрядные RISС процессоры семейства AVR компании Atmel. В этой статье я расскажу как реализовать «почти» совместимый с AVR микроконтроллер внутри нашей ПЛИС на плате Марсоход.
Прежде, чем начинать делать свою реализацию микроконтроллера, конечно, следует изучить внутренности контроллера AVR. Нужно как минимум знать систему команд микропроцессора AVR. На нашем сайте можно скачать его описание:
Система команд микроконтроллера AVR ( 703303 bytes )
Мы не будем ставить себе целью полностью повторить поведение чипа Atmel, мы хотим сделать наш микропроцессор лишь частично совместимым. Полностью повторить можно, но нужна ПЛИС гораздо большего объема. У нас на плате Марсоход стоит CPLD EPM240T100C5, значит у нас есть всего-навсего 240 триггеров и логических элементов.
Кроме триггеров и логики в нашей ПЛИС имеется последовательная флеш память UFM объемом 512 слов по 16 бит. В этой флеш памяти мы будем хранить программу микроконтроллера. Удобно, что слова, хранимые во флеш, имеют разрядность 16. Все команды процессора AVR также шестнадцатиразрядные. Кое-что про UFM мы уже писали на нашем сайте. У нас был проект для ПЛИС платы Марсоход, который выполнял чтение из UFM памяти.
«Оперативной памяти» в нашей ПЛИС нет. Ну значит не будет памяти у нашего микроконтроллера, жаль но это нас не остановит.
У микроконтроллера AVR имеется 32 восьмиразрядных регистра общего назначения. Нижняя группа регистров r0-r15 может быть использована только в командах с операндами-регистрами. Верхняя группа регистров r16-r31 может использоваться в командах и с непосредственными операндами. Поскольку места внутри нашего чипа на плате Марсоход действительно не много, нам придется реализовать только некоторые регистры. Это довольно существенное ограничение, и его нужно будет учитывать при написании программ для нашего микроконтроллера.
Мы реализуем только 7 регистров: r16-r22:
- Первые 4 регистра r16. r19 — это просто регистры.
- Регистр r20 — это тоже обычный регистр, только его биты мы подключим к 8-ми светодиодам платы Марсоход.
- Регистр r21 — это тоже обычный регистр, но его биты мы подключим к выводам управления шаговых двигателей на плате Марсоход.
- Регистр r22 — только для чтения. К нему подключены входы от 4-х кнопочек платы Марсоход.
Схема нашего микроконтроллера создана в среде Altera QuartusII и выглядит вот так (нажмите на картинку, чтобы увеличить):
Наш микроконтроллер работает по простому алгоритму:
- Считывает из флеш памяти UFM очередную команду.
- Декодирует команду и выбирает для нее нужные операнды из регистров или непосредственно из кода команды.
- Выполняет команду в арифметико-логическом устройстве.
- Запоминает результат исполнения команды в регистре приемнике, определяемом командой.
- Переходит к исполнению следующей команды.
У нас сейчас нет цели сделать высокопроизводительный микроконтроллер, мы не будем делать конвейерную обработку данных. Это объясняется тем, что команды из флеш памяти чипа мы можем считывать только в последовательном формате, то есть на чтение одной команды нужно как минимум 16 тактов. Быстрее здесь сделать нельзя (да нам и не нужно сейчас).
Ход выполнения программы может изменяться в зависимости от результата исполнения команд. Специальные команды переходов позволяют переходить к нужной операции в нужных условиях.
Перечислим команды микроконтроллера AVR, которые мы собираемся реализовать:
ADD 0000 11rd dddd rrrr
SUB 0001 10rd dddd rrrr
AND 0010 00rd dddd rrrr
EOR 0010 01rd dddd rrrr
OR 0010 10rd dddd rrrr
MOV 0010 11rd dddd rrrr
CP 0001 01rd dddd rrrr
LSR 1001 010d dddd 0110
SUBI 0101 KKKK dddd KKKK
ANDI 0111 KKKK dddd KKKK
ORI 0110 KKKK dddd KKKK
CPI 0011 KKKK dddd KKKK
LDI 1110 KKKK dddd KKKK
BREQ 1111 00kk kkkk k001
BRNE 1111 01kk kkkk k001
BRCS 1111 00kk kkkk k000
BRCC 1111 01kk kkkk k000
Слева написаны названия команд, а справа — их бинарное представление (кодирование). Так буква «r» обозначает регистр источник, буква «d» — регистр приемник, «K» — это непосредственно операнд.
Конечно — это только малая часть от «настоящей системы команд», но уже и эти команды позволять писать вполне работающие программы.
У нас будет упрощенное АЛУ (Арифметико-Логическое Устройство). Оно реализует только некоторые, наиболее употребительные команды, а так же всего 2 флага для условных переходов: «Z» и «C».
Флаг «Z» устанавливается, если результат АЛУ это ноль. Если результат из АЛУ не нулевой, то флаг «Z» сбрасывается. Флаг «C» устанавливается при возникновении переноса в арифметических операциях ADD и SUB/SUBI или сравнения CP/CPI. Флаги влияют на исполнение команд условных переходов: флаг «Z» влияет на BREQ, BRNE, а флаг «C» влияет на BRCS, BRCC.
Вообще всеь проект мы уже реализовали и его можно взять здесь:
Ядро микропроцессора Atmel AVR ( 109584 bytes )
.
Исходный текст нашего ядра AVR написан на языке Verilog и его можно посмотреть здесь.
Теперь посмотрим, как мы сможем написать программу для нашего микроконтроллера? Для написания программы на языке ассемблер воспользуемся средой разработки компании Atmel AVRStudio4. Эту среду разработки можно скачать прямо с сайта компании Атмел (после регистрации), вот здесь. Или поищите в яндексе — наверняка найдете в свободном доступе.
Создаем проект в AVRStudio4 и пишем простую программу. Программа будет моргать светодиодом на плате Марсоход и опрашивать состояние нажатых кнопочек. Если нажать одну кнопочку, то моргающий светодиод «побежит» в одну сторону, а если нажать другую кнопочку, то светодиод «побежит» в другую сторону. Вот исходный текст на ассемблере для нашего примера:
.include «1200def.inc»
.device AT90S1200
;initial one bit in register
ldi r16,$80
;read port (key status)
mov r17,r22
cpi r17,$0f
;go and blink one LED if no key pressed
breq do_xor
cpi r17,$0e
;go and right shift LEDs if key[0] pressed
breq do_rshift
cpi r17,$0d
;go and left shift LEDs if key[1] pressed
breq do_lshift
;jump to read keys
or r16,r16
brne rd_port
do_rshift:
cpi r16,1
breq set80
lsr r16
mov r20,r16
brne pause
set80:
ldi r16,$80
mov r20,r16
or r16,r16
brne pause
do_lshift:
cpi r16,$80
breq set1
lsl r16
mov r20,r16
brne pause
set1:
ldi r16,$01
mov r20,r16
or r16,r16
brne pause
do_xor:
eor r20,r16
pause:
ldi r18,$10
cycle2:
ldi r19,$FF
cycle1:
or r19,r19
or r19,r19
subi r19,1
brne cycle1
subi r18,1
brne cycle2
or r16,r16
brne rd_port
Видите? Чтение состояния кнопочек — это чтение из регистра r22. Изменение состояния светодиодов — это запись в регистр r20.
Настройте AVRStudio так, что бы выходной формат был «Generic». Это в свойствах проекта, «Assembler Options», настройка «Hex Output Format».
После компиляции программы получается вот такой текстовый файл с кодами программы:
Этот файл нам почти подходит для QuartusII. В нашем проекте для ПЛИС есть файл avr_prog.mif (Memory Initialization File), куда мы и вставляем полученный из AVRStudio код (только нужно добавить точку с запятой в конце каждой строки). Таким образом, после компиляции QuartusII эти коды попадут во флеш UFM нашей ПЛИС.
Теперь можно компилировать и пробовать наш проект в плате Марсоход. Вот видеоролик, демонстрирующий работоспособность нашего процессора:
Все работает так как и задумывалось!
Обратите внимание, что после компиляции, весь проект занимает только 205 логических элемента из 240 имеющихся в нашей ПЛИС. Это значит, что наш микроконтроллер можно и дальше усложнять или добавить какую-то новую логику. Так что проект может быть полезен для создания Ваших устройств.
Микропроцессор своими руками-5. По поводу начала проекта встроенного в FPGA микроконтроллера
Ответ здесь очень простой. Когда-то автор писал о тех сюжетах, которые были ему более всего понятны и интересны. Но потом оказалось, что они интересны еще и довольно большому числу читателей. По их письмам и выбирались темы для продолжения статей. Поэтому появился цикл статей «Микроконтроллер своими руками». А теперь к читателям еще добавились слушатели. Они попросили меня рассказать «про встроенные в FPGA микроконтроллеры». Собрались вечером на кафедре ЦВТИ Университета телекоммуникации. Не могу сказать, что удалось полно ответить на все заданные в тот вечер вопросы. Но один из них показался мне довольно серьезным, а ответить на этот вопрос мне удалось только частично. Студент Алексей Литвинов спросил: «А как вы начинаете проект»?
И еще один тезис: в 2000 и 2002 годах, когда вышли первые мои статьи о встроенных в FPGA микроконтроллерах, сама тема была новой и малоизученной. Поэтому для читателей были интересны, в первую очередь, статьи, описывающие сам микроконтроллер как таковой. Сейчас, в 2007 году, ситуация значительно изменилась. Описания и исходные коды различных реализаций микроконтроллеров вполне доступны и большей частью достаточно хорошо изучены. Но вот «сопутствующие» проблемы остались, и они совершенно не представлены в публикациях.
Поэтому изменилась и направленность статей. Теперь надо расскзать читателям не о каком-то конкретном образце микроконтроллера, более важно показать то, как сделать выбор между теми или иными реализациями микроконтроллеров. А там, где есть проблема выбора, уже десятком строк кода не «отделаешься», приходится долго и обстоятельно описывать все «за» и «против». Вот поэтому и в этой статье, большая часть которой посвящена проблемам выбора и оптимизации, так мало кодов и много аргументов «за» и «против». Конечно, о некоторых из проблем, затронутых в этой статье, уже приходилось бегло упоминать и раньше. Но именно бегло и кратко, поскольку основное внимание было уделено, так сказать, фактической стороне дела — описаниям самих процессоров. А в данной статье все проблемы, которые возникают «ДО ТОГО КАК» объединены вместе и рассмотрены подробно.
Дело еще и в том, что проблемы разработки конкретного изделия по уже готовому и разработанному техническому заданию (ТЗ) решаются исполнителями или, скажем так, средним звеном. Таких инженеров достаточно много и, соответственно, много статей на эту тему. А вот первые шаги в проекте обычно выполняют руководящие работники: ведущие специалисты, топ-менеджеры проектов, директора фирм. Таких специалистов в десятки и сотни раз меньше, чем исполнителей, да и делиться своими знаниями и опытом они обычно не любят. Вот именно поэтому статей на тему о том, как начинать проект, очень и очень мало. При этом еще раз хочу подчеркнуть, что тема начала проектирования чрезвычайно важна, поскольку проблема выбора возникает на самых первых этапах проекта. А ведь известно, что чем раньше в проект закрадывается ошибка и чем позднее она исправляется, тем дороже и сложнее оказываются ее исправления и тем больший ущерб делу наносит эта ошибка.
Начало проекта — что это и как делать
Про «микроЭВМ», микроконтроллеры, «однокристалки» написано уже неимоверно много. Так о чем же будет данная статья, и чем она отличается от стандартного курса «по микроЭВМ»?
Есть множество учебников и академических изданий, посвященных этому курсу. То, что там написано, можно образно представить вот в таком стиле: «У нас есть вот это» и «вот как это работает». Это называется Анализ. Далее приводятся многочисленные подробные и не очень подробные описания различных микропроцессоров и микроконтроллеров, но редко когда эти описания связываются с тем, как именно эти самые микроконтроллеры работают в конкретном приложении. Да это и не удивительно. Не удивительно, ибо методики разработки, методики тестирования и вся прочая «кухня» — а это именно то, что называется «ноу-хау» и это «ноу-хау» бережется как зе-ница ока. «Мы дадим вам полное описание пользователя для этого микроконтроллера, но никогда не объясним, почему мы ввели в набор именно эти команды и почему мы выбрали именно эту архитектуру» — вот лозунг фирм, продающих микроконтроллеры и микроконтроллерные ядра.
Ну а то, что написано здесь, это почти то же самое — «про микроконтроллеры», но только совершенно «с другого конца». «Вот наша задача»— «а вот как ее решить…» А это называется Синтез. И так же как и в теории цепей, известно, что синтез намного труднее анализа, так и здесь: довольно тяжело исчерпывающе все описать и даже осветить все разделы полностью. Многое будет изложено кратко и, к сожалению, часть материала даже придется опустить. Основная трудность синтеза в том, что реализация задачи не всегда предполагает однозначное решение. Решений может быть несколько, а может и не быть ни одного. Такое тоже часто бывает. Поэтому здесь мы только рассмотрим методику постановки задачи и главное, на чем будет сосредоточено внимание читателя — это именно на методике синтеза проекта.
Так как же начать проект?
Начнем с разработки технического задания (ТЗ). Давайте обсудим, что такое разработка, что такое ТЗ и причем тут «поле дураков». Что хочет заказчик? Что он может рассказать о своих потребностях? Недавно в «Электрониксе» проводилось обсуждение «плохих» заказчиков. Вот, мол, пришел человек, принес бумажку, в которой просит Х каналов АЦП, Y каналов ЦАП, все равно какой микроконтроллер и «чтобы было все в шоколаде», как сейчас говорят… И разработчик, поместивший пост в телеконференцию, начинает всячески клеймить этого заказчика за такое непонятное ему задание на разработку. Конечно, это не задание на разработку. И даже не эскиз задания, а скорее филькина грамота, но в этом листке показаны намерения человека стать заказчиком. И прежде чем ругать его, хочется пару слов сказать о задании на разработку, о самой разработке и совсем немного о бизнесе.
Для многих, даже можно смело сказать— для большинства тех, с кем приходилось общаться раньше, понятие «разработка» сводилось к микроконтроллеру, операционной системе, слоям в печатной плате, припою, микросхемам и программным инструментам. Но на самом деле сейчас это не совсем так. Как и для большинства инженеров «старой закалки», так и для автора этих строк было время, когда «работала» вот такая цепочка синонимов: электроника-разработка-схемы-микроконтроллеры-FPGA и т. д. И надо сказать, что для определенной части знакомых и бывших сослуживцев эти термины и до сих пор являются синонимами их деятельности. Но ведь жизнь не стоит на месте и задает все новые и новые уроки. Поэтому для автора этих строк теперь «заработала» вот такая цепочка синонимов: электроника-люди-бизнес-деньги и т. д. Под словом «деньги» здесь понимается не то, что «налом», а то, что служит инструментом для производства. А куда же делись «схемы-микроконтроллеры-FPGA»? Эти термины, конечно, остались, но из цели они превратились в средство. Нет, автор не превратился в бизнесмена, торгующего проектами вразвес или оптом. Просто теперь поменялись приоритеты. И далее автор попытается подробней объяснить этот тезис. Безусловно, и при «старом режиме» наши «отцы-командиры» объясняли нам: главное, это чтобы все чертежи и схемы были в архиве, и чтобы они были выполнены на кальках с соответствующими подписями. А для справки могу сказать, что комплект конструкторской документации (КД) только на одну стойку управления, в который входили все документы, начиная от технического задания, технических условий, схем и кончая инструкцией по упаковке изделия, так вот такой комплект КД представлял собой стопку документов высотой почти в человеческий рост. Но главное отличие от тех дней в том, что в то время можно было «согласовать», «откорректировать» и иногда перенести сроки, а теперь, в ряде случаев, это уже невозможно. Да и предприятия тогда не закрывались из-за невыполненных в срок проектов.
И еще одно замечание о том, как «тогда» и как «сейчас». Вот, мол, «тогда» любой технарь мог стать директором завода, а «сейчас» — только менеджеры да экономисты. Да, известно много примеров когда в директора заводов «выходили» из слесарей, не имея экономического образования. Но при этом не надо забывать, что заводами тогда еще руководили министерства, Госплан и, зачастую, ЦК. И денег добавляли «по личному распоряжению», и задания могли установить «сверх плана». Именно там экономисты планировали что, куда и сколько. Как они это делали, и насколько это было эффективно — сейчас об этом нет смысла рассуждать. Только можно сказать одно — ракеты в космос были запущены и атомные подводные лодки отправлялись в походы. А сегодня, когда предприятия уже никто не опекает «сверху», не имея экономического образования и опыта — просто нельзя браться за дело.
Итак, сейчас главная линия — это «люди-бизнес-деньги. Про деньги здесь рассуждать не будем, остановимся только на первых двух пунктах: люди и бизнес. С чего начинается любой бизнес? С того, что люди договариваются о совместной деятельности. Так вот, очень важно понять то, что любой договор— это документ о том, что люди вступают во взаимоотношения. В данном случае мы будем говорить о трудовых взаимоотношениях. Ну, а когда люди вступают в трудовые взаимоотношения, то они должны договориться о том, что надо сделать, в какие сроки и за какое вознаграждение. И, соответственно оформить конкретный договор об этой деятельности. Правила составления договоров мы здесь тоже обсуждать подробно не будем, это прерогатива юристов. Главное, это то, чтобы в договоре было четко обозначено:
- То, что надо сделать.
- То, как изделие будет испытываться на работоспособность.
- Критерии, по которым изделие (партии изделий) будут считаться соответствующими п. 1.
- Что делать в том случае, если все изделие или его часть не соответствует пп. 1–3.
- Порядок оплаты за выполненную работу.
- Ответственность сторон.
- Чтобы в новом проекте реализовать заданную последовательность действий можно либо каждый раз заново создавать конечный автомат, либо взять уже готовый микроконтроллер, адаптировать его к заданным условиям и, написав небольшую программу для выполнения последовательности команд, запустить. Причем написание программы для микроконтроллера намного проще написания и отладки конечного автомата на языках HDL.
- Чтобы исправить ошибку в конечном автомате, необходимо переработать весь проект, в котором описан автомат, а в варианте микроконтроллера можно только переписать программу. В случае применения автомата фиттер перекладывает проект каждый раз по-новому. А при применении микроконтроллера меняется только память программ, поэтому ядро процессора может быть принудительно привязано к определенным ресурсам в кристалле, и таким образом могут быть исключены ошибки, зависящие от перекладки цепей внутри микросхемы.
- Конечный автомат должен иметь ограниченное количество состояний, так как это требует дополнительных логических ячеек, в то время как микроконтроллер по количеству состояний ограничен только объемом памяти программ, а это на несколько порядков больше.
- Конечный автомат при увеличении количества состояний становится все более и более медленно действующим, так как рост числа дополнительных логических ячеек приводит к увеличению времени прохождения сигнала. Каждое изменение автомата может привести к необходимости повторной верификации проекта.
- Команды, выполняемые микропроцессором, определены по времени выполнения и не зависят от программы, выполняемой на данном процессоре. Поэтому микропроцессор обычно выполняется с требуемым быстродействием, и оно не зависит от конкретного применения, изменений или доработок программы при отладке.
- Отладка автомата путем добавления состояний или изменения алгоритма работы должна производиться только путем полной или частичной перекомпиляции проекта с последующей перезагрузкой FPGA. В случае применения микроконтроллера целесообразно иметь режим загрузки памяти программ контроллера. При этом нет необходимости производить компиляцию проекта. Достаточно только выполнить действия по ассемблированию программы и ее загрузке.
- И последнее, но очень существенное примечание. Если к ядру процессора добавить узел внутрисхемной отладки, то пользователь может получить уровень отладки программы, принятый при отладке ASIC-процессоров. Это возможность прочитать-записать данные в регистр, сделать останов, изменить ход выполнения программы.
| «Ядра — чистый изумруд» и «Ядерные колхозы» В конце 1990-х годов эпоха расцвета специализированных микросхем завершилась. Сегодня вряд ли можно себе представить начинку сотового телефона, состоящую из отдельных микросхем процессора, сигнального процессора, отдельного контроллера дисплея и т. д. Развитие технологии по значительному увеличению ресурсов микросхем приводит к кардинальным изменениям в проектировании устройств. Сегодня «горячая тема» — разработка программной модели ядер устройств. Описания ядер на языках группы VHDL позволяет компоновать проекты из готовых и отлаженных частей. Далее все части собираются в один проект для создания «системы на кристалле». Фирмы-производители микросхем предлагают различные ядра, оптимизированные под их продукцию, для встраивания в проекты пользователя. Части проекта, которые могут быть повторно использованы, становятся товаром. Появился рынок по перепродаже проектов и их частей — http://www.hellobrain.com/. Но вместе с тем существуют и развиваются некоммерческие центры, такие как http://www.fpgacpu.org/. Далее о «ядерных колхозах». Как только появились ядра процессоров как товарные продукты, так тут же в игру вступили фирмы, разработчики программного обеспечения. Это в первую очередь операционные системы реального времени, компиляторы языков высокого уровня, отладчики, симуляторы и т. д. Не остались в стороне и фирмы, разработчики вспомогательного оборудования. Здесь можно упомянуть о производителях как «стартовых наборов», так и змерительного и испытательного оборудования. Таким образом, весь комплекс средств для разработки, отладки и производства систем со встроенными микроконтроллерами становится товарным продуктом, что позволяет значительно ускорить темпы разработки и сократить трудоемкость разрабатываемого проекта. (Цитата из статьи «Микроконтроллер для встроенного применения — NIOS. Конфигурация шины и периферии». «Компоненты и технологии». 2002. № 2–5) |
- Квадрига Аполлона и микропроцессоры // Компоненты и технологии. 2006. № 4, 5.
- http://en.wikipedia.org/wiki/SystemC
- http://www.mentor.com/products/c-based_design/index.cfm
- http://www.celoxica.com/products/dk/default.asp
- http://www.impulsec.com/
- www.altera.com/c2h
- Микропроцессор своими руками. Часть 1 // Компоненты и технологии. 2002. № 6, 7.
- Микроконтроллер для встроенного применения — NIOS. Конфигурация шины и периферии // Компоненты и технологии. 2002. № 2–5.
- http://www.xilinx.com/ipcenter/processor_central/picoblaze/picoblaze_user_resources.htm
- Микропроцессор своими руками-2. Битовый процессор // Компоненты и технологии. 2003. № 6, 7.
- Tomaszewski E. Explicitly Parallel RISC (EPRISC), http://www.opencores.org/articles.cgi/view/4
- http://www.jwdt.com/~paysan/4stack.html
- Chapman K, Creating Embedded Microcontrollers (Programmable State Machines). Part 1, 2, 3, 03/28/2002, www.xilinx.com
- An Overview of the ADSP-219x Pipeline. Engineer To Engineer Note. EE-123. www.analog.com
- U17135EJ1V1UM00.pdf; V850E2 32-bit Microprocessor Core Architecture. http://www.eu.necel.com
- ADuC7024_25_PrD.pdf, www.analog.com
- http://www.trash.net/~luethi/study/silverbird/silverbird.html
Очередной этап сделайсама: микроконтроллеры + JS
Привет, Хабр! Сегодня мы поговорим о том, как сделать систему управления отоплением в загородном доме своими руками, используя легкодоступные микроконтроллеры и свободное ПО… причем сделать её так, чтобы можно было запрограммировать работу нужных устройств при помощи моего любимого JavaScript. Под катом — разбор трех вариантов решения этой задачи (включая тот самый, который я выбрал), а также масса рассуждений о преимуществах и недостатках данного подхода. Всех любителей сделайсамов и очумелых ручек приглашаю под кат.

Я понимаю, что в некоторых регионах зима уже подходит к концу (а в местах обитания некоторых хабрачитателей она вообще не начинается, если иметь в виду настоящую русскую зиму). Но это никак не отменяет того факта, что у каждого ИТ-шника рано или поздно возникает желание наладить удаленный мониторинг и управление отоплением (а в теории — и другими устройствами), которые работают в загородном доме.
Тут вы можете сразу же сказать, что систем управления умным домом и автоматизации интернета вещей существует великое множество. И совершенно не обязательно изобретать велосипед. Да, это так. Изобретать не обязательно, но очень хочется! К тому же для тех, кому доставляет удовольствие делать все самостоятельно, это сулит значительную экономию бюджета, а также исключительно широкие возможности самостоятельной тонкой настройки всего-чего-угодно. Так что поехали!
Постановка задачи
Есть у моего бати загородный дом. И когда он сидит зимой в своей квартире, ему хочется узнать: «а какая там температура на даче, не перемерзнет ли чего, включился ли обогреватель, когда нужно?» И чтобы сделать это, нужно как-то собирать информацию о температуре в помещении через микроконтроллер и пробрасывать все это через открытый интернет. Так можно издалека оценивать ситуацию и покидать свою уютную квартиру зимой только в случае экстренной необходимости.
В качестве основы проекта выбираем доступный микроконтроллер Arduino с модулем Wi-Fi (все-таки батин дом стоит не в глухой деревне, и интернет у нас подведен, подключение к нему относительно стабильное). Также докупаем совместимый и относительно дешевый датчик температуры/влажности DHT11. Ну и мини ЖК-экран в придачу, чтобы можно было локально вывести/посмотреть состояние в помещении («а почему бы и да», ведь можно дополнительно развлечься с настройкой сего «зоопарка»).
Решить задачу физического подключения контроллера к датчикам температуры/влажности и ЖК-дисплея достаточно несложно — просто втыкай провода в правильной последовательности и позаимствуй со стэковерфлоу какой-нибудь популярный блок кода на языке С (основной ЯП для контроллеров Arduino). Другое дело — попробовать подружить все это с языком JS, добавив возможность общения по открытой сети интернет! Задачка становится интереснее!
Приступаем к делу

Чтобы найти свое решение задачи, я выбрал знакомый мне контроллер Ardiuino Uno + Wi-Fi-модуль ESP8266, потому что с ними у меня уже был опыт базовых экспериментов с лампочками. Мы пробовали программировать как на C, так и на JS их включение/выключение, и выглядело все это очень даже неплохо. Можно сказать, воодушевило на новые эксперименты.
В качестве платформы для передачи данных я решил попробовать Yandex Cloud IoT Core MQTT Broker.

Путь для JS
Далее возникает вопрос: «Как именно добиться возможности использовать JavaScript для программирования этого контроллера и режимов его работы?» Я сознательно выбрал именно его, потому что имею более обширный опыт в данном ЯП, нежели в С, к тому же гуглинг показал, что использование JS в качестве основы является вполне рабочим решением.
Спойлер. в итоге я пришел к выводу, что лучше всё-таки использовать язык С, так как он является более «правильным» инструментом для выполнения моей задачи, но в этом случае рубрика бы не называлась «очумелые ручки» 🙂
1. Протокол Firmata + библиотека Johny-Five npm
Это неплохое решение. Реализованная на С библиотека Firmata позволяет легко общаться с контроллером через ПК. А Johny-Five — это абстракция, которая позволяет общаться с протоколом Firmata уже на JS.

Среди плюсов этого подхода — огромное количество дополнительных утилит, уже реализованная поддержка множества IoT-устройств, а также «наичистейший Node JS» в плане программирования прикладной логики на основе полученных данных от контроллера и настройки разнообразных сценариев. Короче, рай для JS-фуллстеков.
Однако есть и минусы. И самый большой из них — необходимость использовать локальное устройство-брокер для коммуникации с внешним миром, на котором и развернется NodeJS-сервер. Проще говоря, нужен какой-то мини-ПК под боком. В моем случае ничего такого в свободном доступе не нашлось. И мне пришлось просто откинуть этот вариант.
2. Espruino
Если еще не знакомы — знакомьтесь! Espruino — это целая экосистема для программирования микроконтроллеров на JavaScript. У нее, кстати, немало адептов в глобальной сети. В Espruino входит прошивка для микроконтроллеров с интерпретатором JS, а также среда разработки Espruino Web IDE. Еще в интернете можно купить платы Espruino и совместимые с ними устройства. Да и вообще вся документация доступна на www.espruino.com, заходите, не стесняйтесь.

Плюсов у решения поистине множество. В нем используется настоящий интерпретатор JS (да, с ограничениями, но незначительными). Уже создано немало библиотек для самых разных задач, имеется возможность подключения их через CommonJS.require(). Среда разработки IDE удобна и позволяет обновлять скрипты ОТА. Системой поддерживается достаточное количество устройств (хотя и не так много), но самое главное, что построенное на базе Espruino решение может работать автономно, ему не обязательно постоянное соединение с брокером-мастером (в отличие от Firmata). Кстати, стоит добавить, что в данном варианте мы используем как основной «мозг» системы не контроллер Arduino Uno, а конкретно его Wi-Fi-модуль ESP8266 (отсюда и название ESPruino). В моем случае, заказанная плата с aliexpress являлась платой 2 в 1: Arduino UNO + Wi-Fi-модуль ESP8266.
Но, как обычно, есть и подводные камни. Для нашего проекта их было два. Во-первых, нам не удалось подружить напрямую температурный сенсор DHT с ESP8266. И даже при том, что на форумах многие жаловались на эту проблему и были предприняты коллективные попытки что-то с этим сделать, побороть беду так и не вышло. Пришлось «костылить» проброс данных от Arduino UNO в ESP8266 через дополнительный провод. А во-вторых, оказалось, что соединение TLS пока что поддерживается только двумя платами (и, к сожалению, эта проблема оказалась фатальной). Наверное, ситуация скоро изменится, об этом также писали на форуме разработчики…но пока так. Яндекс Cloud IoT работает как раз через TLS, так что пускаем скупую слезу и отбрасываем Espruino тоже.
3. Mongoose OS + библиотека mJS
Это решение отличается от предыдущих и работает немного иначе. Мы устанавливаем специальную операционную систему Mongoose OS (не путать с Mongoose в Node JS для Mongo DB!) для работы с контроллерами низкого энергопотребления. А библиотека mJS позволяет использовать синтаксис JavaScript (хотя и сильно урезанный). Далее написанный код компилируется в С и загружается в Mongoose OS. Исходя из этого также имеется возможность подключать дополнительные модули-библиотеки, написанные на C и использовать их в mJS на основе абстракции интерфейсов FFI (foreign function interface).
Плюсы этого решения очевидны:
- легковесная и модульная система использует мало памяти (постоянной и оперативки);
- поддерживается TLS «из коробки»;
- имеется возможность подключать библиотеки на C и работать с ними через прослойку FFI (foreign function interface);
- кроме этого среда разработки IDE тоже очень удобна: обновления приходят «по воздуху», а автономная работа также возможна без подключения к брокеру;
- имеется удобный плагин для популярной IDE VSCode.
Есть, конечно, и минусы. Так, мне пришлось пошаманить с последней версией ОС, которая не хотела вставать на ESP8266 (в итоге взял более старую, но совместимую). Также нужно было адаптироваться к более «куцому» синтаксису mJS. В нем нет замыканий, деструктуризаций, стрелочных функций, а также базовых утилит, таких как String, Array, Object и так далее. Спасибо, правда, что не вырезали JSON. Впрочем, для базовых операций и нашей конкретной задачи «мангуст» оказался вполне съедобным.
Выбираем №3 и едем
Выбор в пользу третьего варианта с Mongoose OS был предрешен, потому что, как я уже говорил, для варианта №1 я не нашел свободного устройства-брокера и решил не переплачивать за сложности. Второй вариант отпал, потому что Yandex IoT Core поддерживает только MQTTS, что заставило отказаться от Espruino — у меня было устройство, в котором поддержка TLS отсутствовала, не покупать же новое!
На самом деле, я понимаю, что вариантов решения этой задачи существует целое множество, но мне хватило этих трех. К тому же, раз один подходит, зачем копаться дальше? В конце концов, можно было вообще отбросить «танцы с бубном» вокруг JS и использовать стандартный C напрямую. Но это явно менее прикольно!
В результате я реализовал следующую схему:

- Плата Arduino Uno (AT Mega 328P)
- работает на С (собственно, немного кода на С пришлось написать всё-таки для этой связки, но это точно не «rocket science»)
- собирает информацию с датчика DHT11,
- выводит информацию на ЖК-экран,
- отправляет данные на модуль ESP8266 по UART.
- MK ESP8266 WiFi
- работает под управлением Mongoose OS и кодом, написанном на урезанном JS,
- принимает информацию с Arduino Uno,
- отправляет данные по MQTTS в Yandex.Cloud.
Мне удалось создать MVP-прототип, реализовав:
- сбор данных на уровне датчиков и микроконтроллеров;
- подключение к сети интернет посредством Yandex Cloud IoT.
Далее, поток нескончаемых дел, к сожалению, навалился на меня и я так и не успел реализовать фронтальную часть проекта. Однако, успешная реализация «базы» показала мне, что проект вполне может быть доведен до конца. Возможно чуть позже я выпущу обновление статьи, в котором смогу представить «батин умный дом» целиком. А пока вы можете посмотреть, как выглядит микроконтроллер в рабочем состоянии на этом видео.
Спасибо за внимание и до новых встреч! Буду очень рад вашим комментариям.

