Когда я собрал USB-реле на плате metaboard [1], появилась идея подключить Wi-Fi модуль ESP-01 (на основе чипа ESP8266 [2]). Поначалу казалось, все должно быть не очень сложно - описание системы команд модуля ESP-01 есть [3], достаточно подключить модуль через порт UART к микроконтроллеру и научиться им управлять. Но на деле пришлось повозиться, решая неожиданно возникающие проблемы.
[Постановка задачи]
Интерфейс USB. Интерфейс виртуального COM-порта (USB CDC) решил оставить, потому что его удобно использовать для вывода отладочных сообщений. Т. е. весь функционал, который был в USB-реле [1], должен остаться. Консоль виртуального COM-порта должна предоставлять возможность настройки (SSID, пароль доступа к Wi-Fi, скорость UART и т. п.), управление состоянием реле, управлением модулем ESP-01 с помощью AT-команд и другие сервисные функции.
Хранение настроек в EEPROM. Настраиваемые параметры (SSID, пароль доступа к Wi-Fi, скорость UART, IP, порт telnet и т. п.), текущее состояние реле должны храниться в энергонезависимой памяти, и восстанавливаться при передергивании питания.
Режим работы Wi-Fi. В документации на модуль ESP-01 было написано, что он может работать и как точка доступа Wi-Fi, и как станция Wi-Fi. Я выбрал из этих 2 вариантов работу как станции Wi-Fi, т. е. модуль ESP-01 при включении питания должен автоматически по указанному SSID и паролю должен устанавливать радиосвязь с точкой доступа.
Режим сетевого обмена данными. Поскольку реле должно управляться по радио, то нужно как-то посылать ему команды через модуль ESP-01. Есть 2 варианта - либо ESP-01 работает как telnet-клиент, подключаясь к серверу TCP, либо как сервер telnet, когда к нему могут подключаться клиенты. Оба варианта (пример их работы описан в статье [4]) теоретически могут обеспечить двусторонний канал связи для передачи команд и получения информации о состоянии контроллера реле, и у каждого есть свои ограничения, достоинства и недостатки. Также для ESP-01 заявлена возможность использования протокола UDP, но этот вариант я отбросил, потому что он требовал применения на стороне хоста специального программного обеспечения.
Например, если выбрать для ESP-01 режим клиента TCP, то можно применить прозрачный режим передачи данных, что упрощает программное обеспечение на стороне микроконтроллера. Однако это требует на стороне сервера специализированного программного обеспечения, которое также предстоит написать. Если применить режим сервера для ESP-01, то клиентское программное обеспечение уже писать не надо, можно применить putty и получить управляющую консоль терминала, аналогичную консоли с виртуальным COM-портом, и это большой плюс. Однако в этом режиме режим прозрачной передачи данных не работает (я в этом убедился на опыте, по крайней мере с моей прошивкой ESP-01 было именно так), и придется для обмена данными применять систему AT-команд. Все-таки решил остановиться именно на этом варианте, как самом простом для пользователя.
Итак, Wi-Fi реле должно обладать следующими функциями:
1. Предоставлять консоль для управления реле и изменения настроек через интерфейс USB CDC (виртуальный COM-порт). 2. Предоставлять аналогичную консоль для управления реле через стандартное telnet-подключение. 3. Не требуется никакое специализированное программное обеспечение, для консолей должны использоваться традиционные терминальные программы (я использовал putty, но можно применить и другие программы, например TerraTerm, SecureCRT, HyperTerminal и т. п.). 4. Все настройки и состояния реле должны храниться в энергонезависимой памяти, защищаться контрольной суммой и загружаться при включении питания. 5. Настроенное Wi-Fi реле должно автоматически подключаться к выбранной точке доступа, запускать TCP-сервер telnet и обслуживать клиентские подключения.
[Схема]
Как видите, схема довольно простая, она совпадает со схемой USB-реле [1], только добавлено подключение модуля ESP-01. Модуль обменивается информацией с микроконтроллером по последовательному каналу связи (UART, скорость 9600 бод, 8 бит данных, один стоп-бит, без контроля четности). Пунктирными линиями показаны необязательные соединения - это цепи сброса ESP-01, перемычка для обновления его прошивки (не используется), и тестовый светодиод, который использовался для отладки.
[Программное обеспечение metaboard (firmware)]
Программа микроконтроллера ATmega328P состоит из 5 основных частей и взаимодействия между ними.
1. Интерфейс USB, реализованный на основе библиотеки V-USB. Он работает как виртуальный COM-порт (класс USB CDC), и при подключении к нему терминальным клиентом дает управляющую консоль. Эта консоль предоставляет текстовый интерфейс для изменения и сохранения настроек, управления состоянием реле (см. скриншоты ниже).
2. Интерфейс UART и низкоуровневый обмен с модулем ESP-01.
3. Обработка AT-команд, отслеживание состояния модуля ESP-01 и управление им. Основная цель - при включении питания прочитать из EEPROM настройки и обеспечить подключение к точке доступа Wi-Fi, настроить для модуля нужный IP-адрес и запустить сервер telnet на указанном порту TCP.
4. Организация обмена данными между сетевым клиентом telnet и кодом декодирования команд. В результате имеется возможность передавать через telnet-подключение в обе стороны текстовую информацию, и организовать консоль, аналогичную консоли для виртуального COM-порта. Т. е. состоянием реле можно одними и теми же командами управлять как через консоль виртуального COM-порта, так и через консоль telnet-подключения. Для выборки текста из ответа ESP-01 применена библиотека регулярных выражений SLRE (выражаю благодарность автору Sergey Lyubka).
5. Код декодирования команд консоли. Он принимает команды пользователя и от виртуального COM-порта, и от telnet-подключения, обрабатывает их и выдает пользователю ответ.
Программа написана в среде AVR Studio с использованием библиотек avr libc, и занимает примерно половину памяти программ и немного больше половины оперативной памяти микроконтроллера ATmega328P.
AVR Memory Usage
----------------
Device: atmega328
Program: 16436 bytes (50.2% Full)
(.text + .data + .bootloader)
Data: 1105 bytes (54.0% Full)
(.data + .bss + .noinit)
Build succeeded with 0 Warnings...
Исходный код, документацию и прошивку можно скачать в архиве [].
[Программное обеспечение на стороне хоста]
На стороне хоста можно применять стандартное, готовое программное обеспечение, обеспечивающее командную строку через подключение к серверу telnet (putty, SecureCRT, TerraTerm, и т. п.). На скриншоте показан командный интерфейс WiFi реле на экране бесплатной утилиты putty.
Команды для управления реле остались такими же, как и в проекте USB реле [1], добавились только команды, касающиеся настройки модуля ESP-01 и отправки ему AT-команд.
[Проблемы, с которыми пришлось столкнуться]
Конечно, пришлось подробно изучить систему AT-команд модуля ESP-01 [3]. Благодаря примерам [4] это удалось без особого труда, однако на каждом шагу приходилось сталкиваться с не описанными в руководстве проблемами. Например, потребовалось с помощью осциллографа определять скорость работы модуля (она оказалась 9600 бод). По непонятным причинам в режиме сервера TCP отказался включаться прозрачный режим. Также были проблемы с символом возврата каретки \r. Для декодирования ответов ESP-01, чтобы выбрать полезный текст из данных, пришлось применить регулярные выражения. В общем, повозиться пришлось, но в конечном счете все проблемы удалось или обойти, или решить.
1. Питание модуля ESP-01. Как выяснилось, модуль ESP-01 может потреблять довольно большой ток (порядка 200 мА от 3.3V), и при этом капризен к качеству питания. Поэтому отнеситесь особенно тщательно к выбору стабилизатора напряжения (он должен с запасом выдавать нужный ток) и к цепям развязки, устраняющим пульсации по питанию.
2. Модуль ESP-01 очень капризная и нежная штука. Не пытайтесь применять его горячее подключение - это может вывести его из строя. Я испортил один такой модуль, он стал на все AT-команды выдавать ошибку.
3. Передача текста с помощью команды AT+CIPSEND работает не так, как ожидалось по описанию [3]. Код возврата каретки (CR, \r, 0x0D) нельзя передавать последним, это приводит к зависанию команды AT+CIPSEND на ожидании дополнительного символа (получается, что символ \r игнорируется, если он последний в команде). Кроме того, код возврата каретки не проходит через модуль до интерфейса UART. Чтобы обойти это ограничение, пришлось применить специальную обработку в firmware контроллера.
Чтобы осуществлялся возврат курсора консоли в начальную позицию строки, нужно воспользоваться настройкой сессии терминала putty: Terminal -> поставить галочку "Implicit CR in every LF". Тогда удается обойти проблему с непрохождением символа возврата каретки \r (к сожалению, стандартный клиент telnet.exe в составе Windows такой опции не предоставляет).
4. Для обработки ответов модуля ESP-01 при получении текста через интерфейс UART пришлось применить регулярные выражения.
5. Если вся конструкция получает питание от USB, то нужно выбрать максимально толстый и минимальный по длине кабель USB. Иначе при включении реле броски тока могут привести к провалам питающего напряжения, и это может неблагоприятно повлиять на надежность работы модуля ESP. Идеальный вариант - питать всю конструкцию не от USB, а от внешнего источника постоянного напряжения +12V (для этой цели у платы metaboard имеется специальный коннектор для джека и перемычка, переключающая источник питания).
[Что можно еще доработать]
Пока что telnet-консоль ограничена только самыми необходимыми командами (help, управление реле). Программа обрабатывает только одно одновременное подключение telnet-клиента, хотя telnet-сервер модуля ESP-01 допускает до 5 одновременных подключений.
[Ссылки]
1. USB реле на плате metaboard. 2. ESP8266: микросхема Wi-Fi. 3. ESP8266: справочник по командам AT. 4. ESP8266: пример тестирования команд AT. 5. 160410usb-relay-mega328-ESP8266.zip - исходный код, прошивка микроконтроллера, документация. |