Задачу минимум мы выполнили – протестировали, как работает мотор AKKO AM72E по интерфейсу RS485. Теперь мы можем повелевать солнечным светом, посылая электроны по проводам. Очевидный следующий шаг – это переход от управления при помощи элементарных частиц к управлению при помощи вибраций, т.е. радиоволн. Заклинания, которые мы будем при этом использовать, зависят от магии, которую мы выберем.
Любая беспроводная технология подошла бы для наших целей, но мне захотелось управлять шторами со смартфона. При этом желательно не устанавливать никаких дополнительных программ. Буду подключаться к домашней сети WiFi и управлять электрокарнизом при помощи браузера. Привод, через переходник RS485-UART подключу к ESP8266. Вы вполне можете пойти своим путём и использовать, например, WiFi роутер.

ESP-01 на сегодня, является самым бюджетным модулем с WiFi. Стоит он настолько мало, что, если понадобится управлять несколькими моторами, мы можем не тянуть провода от одного мотора к другому, а просто подключить каждый к своему модулю. При этом нам не нужно будет задавать каждому AM72E свой адрес – можно обращаться по адресу ESP-01. Нам ESP8266 интересен не только своей низкой ценой и небольшим размером, но и тем, что ресурсов на нём очень мало и придётся приложить немало усилий, чтобы впихнуть в него что-то, что будет работать.
Я не буду описывать, как подключить и обновить прошивку ESP8266. О том, как правильно это сделать, можно посмотреть здесь.
Под Windows, чтобы запрограммировать ESP8266, можно использовать либо Arduino IDE, и тогда мы пишем на C (ну, почти), либо NodeMcu, и писать можно на Lua. Другие варианты тоже есть, но нам они не подходят.
Нет, не торопимся заливать NodeMcu. Прошивку нужно подготовить. Ресурсов на ESP-01 недостаточно для того, чтобы мы могли забывать о них, если хотим поднять Web сервер. На плате есть flash ROM – место, где будут храниться все наши файлы — 512 кбайт. Это уже крайне мало, но упираться в нехватку ресурсов мы начнём не во-флеше, а в ОЗУ. SoC ESP8266 имеет область RAM 64 кбайт для кода программ, и 96 кбайт для данных. При старте данные из флеша загружаются в ОЗУ. Если мы зальём стоковую прошивку NodeMcu и посмотрим на величину доступной памяти, то увидим вот что:
image
21 кбайт! При таких объёмах придётся экономить каждый байт! Ещё видим после строки «Can’t autodetect firmware, because proper answer not received» какой-то мусор. Это отладочная информация, выдаётся на скорости 74 880, затем скорость меняется. Вот, как это выглядит на нужной скорости:

Ничего интересного.
Вначале увеличим объём доступного ОЗУ. Сделать это существенно, можно самостоятельно пересобрав прошивку. Исходные коды доступны, но перелопачивать весь проект только ради тестирования совсем не хочется. К тому же это придётся делать под Linux. Не то, чтобы это очень сложно, но если мы будем отвлекаться – мы никогда не закончим. Скорректировать прошивку можно по ссылке: frightanic.com/nodemcu-custom-build.
Я переставил флажок на dev096 и в окне выбора подключаемых модулей поставил дополнительную галочку возле 1-ware. Этот модуль я включил из-за одной функции — расчета CRC16. Вот так:

Вы, разумеется, можете включить или убрать те модули, которые вам нужны. Теперь вводим в форму email и жмём кнопку «Check the build status». Одноразовый email тоже подойдёт. Ждём несколько минут, и получаем письмом ссылку на файлы с прошивкой. Прошивка, в которой можно работать только с целыми числами сэкономит вам во flash с десяток килобайт. Я такую и заливал. Но вы можете сделать другой выбор. Посмотрим, зачем же мы так старались:

Теперь нам доступно 35 кбайт ОЗУ.
Прежде, чем мы перейдём к программированию, вернёмся ненадолго к переходнику UART-RS485. К той его части, которая отвечает за переключение приём-передача. К резистору R1. При загрузке ESP8266 устанавливает все выводы GPIO в режим входов, и затем программа определяет, в каком режиме будет работать каждый GPIO. Оказалось, что в момент загрузки на контакте TX_UART (U0TXD) должен быть высокий уровень, иначе не стартует программа, записанная во-флеше. Без R1 при опросе контакта TX будет считан низкий уровень и произойдёт «подвисание» ESP8266 до тех пор, пока переходник не будет переподключен.
От всей схемы переключения приём-передача можно отказаться, задействовав при этом один из контактов GPIO. Но доступных GPIO на ESP-01 и без того мало, и возможно, в вашем проекте им найдётся другое применение. К тому же со схемой переключения, сделанный нами переходник можно использовать, например, с роутером, у которого нет GPIO.
Проект состоит из трёх файлов: data, index.html и init.lua. Правильнее считать это не проектом, а прототипом. К примеру, нет никакой авторизации, кроме как при подключении к роутеру. И я совсем не уверен, что сервер на ESP8266 способен противостоять атакам. Код никак не проверяет, кроме как при подключении, есть подключение к сети или оно пропало. Нет кода, который позволит автоматически перезапустить ESP8266, если программа зависла. Последние две задачи легко решаются, но проект при этом стал бы сложнее.
Файл data вам нужно отредактировать – вписать туда название и пароль вашей сети WiFi. Подключив ESP8266 к сети, мы получим возможность управлять шторами через интернет. После того, как завершите отладку init.lua, переменной debug присвойте значение false, либо вовсе её удалите. Так меньше мусора будет сыпаться в UART. Если этого не сделать, то привод может не работать. К тому же AKKO AM72E всё равно не сможет понять, что вы ему пишите. При этом функцию log и все строки, в которых она упоминается в init.lua можно также удалить.
Вернёмся к теме экономии ресурсов. Файл data, с моими названием сети и паролем, занимает в памяти 1643 байта. Если вы ещё не догадались, то этот файл — обычный файл lua. Его можно скомпилировать. После компиляции этот же файл занимает уже 1040 байт. То же самое вы можете сделать с init.lua. Размер файла можно ещё уменьшить. Нужно выкинуть из него все лишнее, прежде всего комментарии и пробелы. Файл при этом становится плохо читаемым, но если нам нужно больше места, на это придётся пойти. Это обычная практика. В конечном счёте, красивое и правильное оформление вашего кода никто не оценит. Ну, разве что конкуренты, когда ваш код попадёт к ним. Зато урезанный функционал будет сразу заметен. Особенно, если будет с чем сравнивать. Когда программируются устройства с небольшими ресурсами, приоритеты меняются. Часто именно поэтому программы, написанные на C для встраиваемых систем, плохо читаемы. Всё усложняется перекладыванием на препроцессор всего, что только можно. Если начав проект на C, вы отложите его на пару месяцев, то вам может потребоваться приличное время, чтобы разобраться в своём же коде. На сопровождение кода внимание обращается меньше, т.к. за три — пять лет появляется новое железо и всё приходится переписывать заново из-за изменившейся архитектуры.
После того, как я вручную удалил всё лишнее из файла data, он стал занимать 705 байт. При этом размер можно ещё сократить на несколько десятков байт, если переменным давать не осмысленные имена, а имена из одной буквы (да, да, это совсем не то, чему нас учат в школе). После его компиляции файл data.lc занимает во флеше 728 байт – упс! Даже так бывает!
Про index.htm сказать особенно нечего. У себя я ещё добавил к нему картинку в формате svg. Вы тоже можете это сделать. Просто залейте файл curtain.svg во флеш ещё одним файлом.
Init.lua – основной файл проекта. В самом файле есть комментарии и если что-то непонятно, можно запустить построчное выполнение и вообще экспериментировать до полного прояснения. Кроме UARTA, ещё есть переключение светодиода, подключенного к GPIO2. Файлы при отдаче сервером считываются из флеша и передаются блоками по 512 байт. Это снижает требования к размеру доступного ОЗУ.
В коде этого нет, но если возникнет необходимость посчитать CRC16, то делается это командой ow.crc16(buf, crc). К примеру, если набрать в командной строке:
=ow.crc16('\85\00\00\03\01', 0xFFFF)
Получим:
15593
Нужно только не забыть, первым отправить младший байт, а затем старший.
Вот, что в итоге получилось:
? Здесь должно быть видео )

Комментарии (11)


  1. Hellsy22
    15.12.2015 09:17
    +2

    21 кбайт! При таких объёмах придётся экономить каждый байт!

    А вы не заливайте стоковую прошивку. Заливайте последнюю из dev и будет у вас куда больше оперативной памяти.

    Насчет компиляции — она не всегда дает выигрыш в памяти. К сожалению, чтобы реализовать что-то серьезное — приходится заниматься, пардон, онанизмом с постоянной загрузкой-выгрузкой модулей. У меня самописный http-клиент, который умеет работать с dns, куками и редиректом — просто не влез в память, пришлось разбить его на шесть блоков. Он все равно жрет до 15к оперативки в процессе работы, но это уже не так критично.

    P.S.: Не очень понятно, почему выбран ESP-01. Разница в цене с ESP-12 — копейки, а возможностей у 12-го куда больше. Сам я пользуюсь преимущественно 07-ми, потому что металлический экран и хорошая антенна.


  1. GarryC
    15.12.2015 09:53
    +3

    На плате есть flash ROM – место, где будут храниться все наши файлы — 512 кбайт. Это уже крайне мало, но упираться в нехватку ресурсов мы начнём не во-флеше, а в ОЗУ. SoC ESP8266 имеет область RAM 64 кбайт для кода программ, и 96 кбайт для данных.
    Сначала я подумал, что это тонкий троллинг, потом понял, что таки да, теперь это считается крайне малыми значениями. Просто офигеть, насколько стали криворуки программисты, если для реализации стека WiFi им мало 512к программы и для такой задачи они выделяют 96-32=64к данных. Что вообще может занимать 64к в данном стеке? 20 буферов по 3к каждый? Ну а готовность автора ужиматься и постараться загнать в 32к данных задачу управления двигателем шторы вообще стоит рассматривать как пример геройского преодоленния трудностей. Просто нет слов, одни буквы и те хулиганские.
    А пассаж
    Последние две задачи легко решаются, но проект при этом стал бы сложнее.
    приводит в изумление, оказывается, смысл в том, чтобы делать проект попроще.


    1. Hellsy22
      15.12.2015 10:56
      +1

      Ну, на деле с TCP-стеком особо на 64к не разгуляешься. Нынче даже у одного соединения дефолтное выделение памяти раза в 4 выше. Но тут проблема в основном в LUA, полагаю.


  1. ilBEastli
    15.12.2015 09:55

    Подскажите, как можно проверить модуль ESP-01 на работоспособность при минимальных затратах времени и сил?

    Находил такой вариант: подключить VCC и CH_PD к 3.3V, GND к GND, после этого через некоторое время должна появиться новая сеть.

    Распиновка
    image


    1. Hellsy22
      15.12.2015 10:28

      Без подручных средств, полагаю, никак. Новая сеть появляется только у NodeMCU Dev Board.
      Но можно купить USB-UART или использовать для проверки другой контроллер — например, Arduino.


      1. SHVV
        15.12.2015 10:34

        Нет, у стандартной AT прошивки тоже появляется. У меня, по крайней мере, появлялась.


      1. ilBEastli
        15.12.2015 10:43

        Хорошо, есть Arduino Nano 5V в наличии.
        Тогда еще нужен будет преобразователь уровней 5V <-> 3.3V.
        Куда дальше?


        1. Hellsy22
          15.12.2015 10:55

          Дальше SoftwareSerial и трансляция обмена в обычный Serial, чтобы видеть, что там сообщает ESP.
          Скорость на большинстве дефолтных прошивок — 9600, но на старых попадается и 115200.


          1. ilBEastli
            15.12.2015 11:03

            Спасибо. Попробую в ближайшие дни.


            1. Hellsy22
              15.12.2015 11:16

              Пожалуйста. Вот вам еще ссылка, где заодно и вопрос преобразователя раскрыт.


  1. Speccyfan
    15.12.2015 10:44

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