(с) 2017-2018 Леонид Каганов lleo@lleo.me, Telegram: lleokaganov, +79166801685

Документация на систему фреймворка LLeo для ESP8266

Вступление

Что такое ESP8266? Это маленький чип стоимостью 2 доллара, который ставится в системы умного дома и прочую электронику. Если вы не интересуетесь разработкой мелкой электроники и у вас нет опыта ее программирования, дальше читать нет смысла. Для остальных продолжим. Чип питается от 3.3V (но достаточно прожорлив из-за WiFi), имеет на борту процессор 40/80 MHz и WiFi-модуль, позволяющий коннектиться в местную сетку или создавать свою точку доступа, внутреннюю операционку, которая корректно рулит процессами, в том числе позволяя создавать вебсайтик внутри чипа, некоторое количество памяти для программы и память-флешка на 4Mb для данных. Для программирования чипа я использую среду разработки Arduino с плагином работы для 8266. Несмотря на то, что чип этот гораздо сложнее AVR и имеет на борту свою операционную систему, в среде Arduino для него всё уже давно весьма удобно и надежно устроено — можно программировать, не зная о системе и не задумываясь, как оно будет с ней взаимодействовать. Я пока не встречал задач (кроме воспроизведения MP3), которые бы требовали нативного компилятора и прямой работы с системой.

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

Суть фреймворка:
— Вебсайт на борту
— Организация циклов и команд при помощи текстовых файлов
— Запуск скриптов и команд по WEB
— Подключение к существующей сети WiFi или создание своей точки доступа (если не удалось), удобный поиск WiFi и конфигурация через браузер
— Файл-менеджер чипа через браузер
— Редактирование текстовых файлов чипа через браузер
— Автообновление файлов и прошивки с указанного сайта при включении (позволяет программировать чип удаленно)

Поддерживает команды:
— Работа с пинами (установка режима, чтение, запись)
— Работа с сервоприводами (включение, выключение, поворот на N градусов)
— Работа с файлами на внутренней флешке (запись, чтение, удаление, форматирование)
— Ожидание событий с пинов
— Команда обращения к произвольному серверу для получения инструкций

В ближайших планах:
— Движение сервомоторов с указанной скоростью и с разгоном по синусоиде
— Работа со сканерами карточек NFC (модель RC522) и RFID (модели с протоколом Wiegand)
— Работа с электрозамком (детектор застревания мотора, организация списков доступа)

В отдаленных планах:
— Работа с различными датчиками и устройствами (давление, влажность, вывод на дисплей и т.п.)
— Команда погружения чипа в сон

КОД, СКРИПТЫ И ДАННЫЕ

Посмотреть скетч Arduino: HOBOT-robot.ino (или скачать)

Скачать бинарник: firmware.bin

Как сделать свой сервер обновления?

Скрипт сервера автообновления (указанный в конфиге server_update=http://lleo.me/ESP8266/index.php): lleo.me/ESP8266/index.php

Рядом с ним вы создаете папку с именем группы устройств (указанная в конфиге soft=default), где размещаете комплект файлов для обновления внутренней флешки и бинарник firmware.bin для обновления кода, например:

показать

Также вы можете отдельно завести скрипт, который будет пингаться при включении для ведения логов или индикации, что устройство вошло в сеть (указан в конфиге server_ping=http://home.lleo.me/ESP8266/index.php):

показать home.lleo.me/ESP8266/index.php
<?php
header('Content-Type: text/plain');

$mode=(isset($_GET['mode'])?$_GET['mode']:'');
$CHIP=(isset($_GET['CHIP'])?preg_replace("/[^a-z0-9\-\_]+/si",'',$_GET['CHIP']):'default');

$g=fopen('start.txt','a+');
fputs($g,date('Y/m/d h:i:s').' ['.$_SERVER['REMOTE_ADDR'].'] chip: '.$_GET['chip'].' CHIP: '.$_GET['CHIP'].' ip: '.$_GET['ip']."\n");
fclose($g);

// if($_GET['chip']=='73294a') do_procedure_for('73294a');

die('OK');
?>

Показать лог стартовавших чипов с дефолтной прошивкой: start.txt

ПЕРВОНАЧАЛЬНАЯ НАСТРОЙКА

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

При первом включении чип с этой прошивкой обнаружит, что он чистый чип — в смысле, у него чиста флешка. Точнее, на ней нет файла config.txt Тогда он поднимет дефолтную вайфай-точку без пароля с именем типа: «ESP8266-xxxxxx»

Надо законнектиться к его вайфаю и открыть любую страницу не https (например http://lleo.me) Вместо нее чип выдаст страничку с окном настройки, где попросит прописать имя и пароль местного WiFi (достаточно некрасиво по дизайну, но красивые поиски WiFi будут потом, когда установятся файлы внутренней флешки).

Потом чип пойдет на http://lleo.me/ESP8266/index.php?ip={ip}&chip={chip}&CHIP={C[...] (в фигурных скобочках подставит сам) и сам скачает оттуда данные (всякий дизайн и конфиги дефолтные). И сообщит, какой у него IP в местной сетке — его можно найти в логах в конце: http://home.lleo.me/ESP8266/start.txt

После этого можно из своей сетки зайти уже прицельно на свой чип (например, http://192.168.2.60 ), и там будут все красоты и онлайн-редакторы.

ЯЗЫК КОМАНД

В простых текстовых скриптах используются простые мнемоники для выполнения разных функций. Я называю это язык MOTO.
— Команды записываются с новой строки или разделяются точкой с запятой (пробелы около нее не играют роли)
— Все, что после # считается комментарием

На данный момент (список обновляется) поддерживаются такие команды:

stop

Остановить исполнение основного цикла loop.txt

loop

Запустить исполнение основного цикла loop.txt

loop new123.txt

Запустить исполнение любого файла в качестве цикла

ping http://lleo.me/script/bot/alica/1.php?chip={chip}&ip={ip}&soft={sofs}

Сходить на удаленный сервер за инструкциями. Ответ сервера в том же текстовом формате MOTO. Если ответ пуст — инструкций нет.

attach 1 7

Присоединить серво 1 к пину 7.

detach 1

Отсоединить серво 1.

go 2 45

Повернуть серво 2 на 45 градусов.

pinmode 7 OUTPUT
pinmode 5 INPUT
pinmode 4 INPUT_PULLUP

Установить режим для пина.

pin 5 0

Установить значение пина 5 в 0

delay 500

Выполнить задержку в 500 мс. Все процессы будут приостановлены.

run File.TXT
# То же, что:
File.TXT

Выполнить инструкции из файла File.TXT

wait 2 = 0
wait 5 = 1

Остановить всё и ждать, пока значение на цифровом пине будет 0 или 1

wait A0 > 120
wait A0 >= 120
wait A0 < 1023
wait A0 <= 120

Остановить всё и ждать, пока значение на аналоговом пине A0 (в ESP есть только он) будет соответствовать условию.

Описание и примеры основных файлов чипа

Конфигурационный файл /config.txt

# название софта — по умолчанию default, просто у меня для разных типов устройств (коммутаторы умного дома, движущиеся куклы) на сайте предусмотрены свои версии софта для каждого устройства или группы одинаковых устройств.
soft=default

# автообновление при каждом включении — нужно отключить, если своя разработка
autoupdate=yes

# с какого сервера тянуть обновления
server_update=http://lleo.me/ESP8266/index.php?ip={ip}&chip={chip}&CHIP={CHIP}&soft={soft}

# на какой сервер отстукиваться при каждом включении (можно убрать)
server_ping=http://home.lleo.me/ESP8266/index.php?ip={ip}&chip={chip}&CHIP={CHIP}&soft={soft}  # пинг при успешном соединении

# если не соединились по WiFi, поднять свою точку доступа:
AP_name=ESP8266-{CHIP}
#AP_password=

startfile = init.txt # программа при запуске системы
loopfile = loop.txt # программа работы в цикле

Скрипт инициализации при включении /init.txt

Здесь ты описываешь, какие у тебя выходы как используются. Например:

# установить pin 2 в режим OUTPUT
pinmode 2 OUTPUT

# записать в pin2 ноль (включить синюю лампочку на корпусе)
pin 2 0

# подключить серву 1 к пину 12 (D6)
attach 1 12 # D6

# перевести серву 1 на 20 градусов
go 1 20

# отключить серву 1
detach 1

# подождать секунду
delay 1000

# записать 1 — выключить лампочку на корпусе
pin 2 1

Скрипт основного цикла работы чипа /loop.txt

Простой пример цикла, который стучится за инструкциями на внешний сервер раз в 2 секунды:

ping http://lleo.me/ESP-server/commands.php?chip={chip}&soft={soft}
sleep 2

В ответ сервер передает строку с инструкцией или инструкциями разделенными точкой с запятой, пример ответа:

pin 2 1 ; go 1 90 ; MOTO ; pin 2 0

Зажечь диод на корпусе, повернуть серву 1 на 90 градусов, выполнить скрипт из файла /MOTO, выключить диод.

В сочетании с голосовыми инструкциями API Яндекс-Алисы такой тип работы позволяет творить чудеса.

Другой пример — обычный файл loop.txt без получения внешних инструкций:

# запустить файл /FOTO (синтаксис такой же как у loop.txt, наличие слеша в имени файла здесь и далее никакого значения не имеет)
run FOTO

#повернуть серву 4 на 20 градусов
go 4 20

# выждать 800 милисекунд (без прерываний на WiFi)
delay 800

#снова повернуть серву 4 на 40 градусов
go 4 40

# заснуть на 1 секунду (разница между delay и sleep в том что sleep в секундах и не блокирует WiFi на это время)
sleep 1

# выполнить скрипт из файла с именем "LHup"
LHup

# ждать, пока на A0 (аналоговый вход) не появится значение больше 600 (допустимы сравнения: <div align=left><tt>&lt;, &gt;, &lt;=, &gt;=</tt></div>)
wait A0 <div align=left><tt>&gt;</tt></div> 600

# выполнить скрипт из файла с именем "SVET.txt"
SVET.txt

# ждать, пока на цифровом пине 3 возникнет 0
wait 3 = 0

Постепенно я планирую добавлять все прочие команды по мере необходимости. Например «посмотреть, появился ли код ключа на сканере ключей и если да, то выполнить файл с именем...»

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

Есть два важных файла:

stoplist.txt

Описывает, какие файлы нельзя обновлять с сервера, если автообновление включено. Пишешь их в столбик:

loop.txt
config.txt
LHup
SVET.txt

stopweblist.txt

Описывает, какие файлы нельзя показывать с веба. Это тоже важно, потому что по умолчанию все файлы можно открыть с веба, зайдя на чип. Если там есть пароли или еще что-то и у тебя во внутренней сетке ходят посторонние, то запрети первым делом /config.txt

Пишешь их в столбик:

config.txt
stopweblist.txt

Важно! Если автообновление включено, то что бы ты ни поменял в коде моей прошивки, чип выяснит при включении, что изменилась контрольная сумма, и обновит прошивку с дефолтного firmware.bin И все изменения перезапишутся. Так что после первичной настройки и автоскачивания файлов имеет смысл запретить автообновление.

Да, ну и разумеется, помимо скриптов и цикла, многие вещи можно вызывать простым http-запросом из сети к чипу.

ПРИМЕРЫ HTTP-ЗАПРОСОВ

Любой скрипт можно в любой момент вызвать на исполнение:

http://192.168.2.60/AJAX?a=MOTO&file=SVET.txt

Любую команду или последовательность команд можно выполнить:
{BC: http://192.168.2.60/AJAX?a=run&s=pin+2+1+%3B+go+1+90+%3B+MOTO+%3B+pin+2+0

Приостановить выполнение внутреннего loop.txt:

http://192.168.2.60/AJAX?a=run&s=stop

Запустить LOOP заново (если указан аргумент — то это имя файла, по умолчанию loop.txt):

http://192.168.2.60/AJAX?a=run&s=loop%20newloop2.txt

Выдать какой-то там номер такта (не помню точно) — используется просто как пинг, показывает, что система жива и процессы идут:

http://192.168.2.60/time

Выполнить ESP.reset();

http://192.168.2.60/reset

Выполнить ESP.restart(); — не помню, чем они отличаются, какой-то считается более мягким.

http://192.168.2.60/restart

Отформатировать внутреннюю флешку SPIFFS.format(); стереть все файлы:

http://192.168.2.60/format

РАБОТА С СЕРВАМИ

Подключить серву 1 к пину 2:

http://192.168.2.60/PIN?a=servo&n=1&mode=attach&d=2

Отключить серву 1 (при этом мотор точно остановится и не будет жрать энергию):

http://192.168.2.60/PIN?a=servo&n=1&mode=detach

Выставить серву 1 в 90 градусов:

http://192.168.2.60/PIN?a=servo&n=1&mode=go&x=90

Выставить серву 2 в 90 градусов:

http://192.168.2.60/AJAX?a=servo&id=2?x=90

РАБОТА С ПИНАМИ

Выставить пин (1,2,3,4 ... A0) в режим (OUTPUT, INPUT, INPUT_PULLUP):

http://192.168.2.60/PIN?a=pinmode&d=4&mode=INPUT_PULLUP

Выставить цифровой пин в значение 0 или 1:

http://192.168.2.60/PIN?a=pin&d=4&mode=0

Прочесть значение цифрового пина 12:

http://192.168.2.60/AJAX?a=read&d=12

Прочесть значение аналогового пина A0:

http://192.168.2.60/AJAX?a=aread

РАБОТА С ФРЕЙМВОРКОМ

Команды файлменеджера сложны, красивы и требуют рук оператора в браузере, но если уж очень надо, то можно и по запросу.

Прописать сетку LLeoNet с паролем и перегрузить чип ESP.restart();

http://192.168.2.60/FM?a=WIFIconn1&net=LLeoNet&pass=balalaika123

Сканировать сетки (ответ в формате фреймворка):

http://192.168.2.60/FM?a=WiFi

Cписок файлов на флешке (ответ в формате фреймворка):

http://192.168.2.60/FM?a=Files

Инфо о системе (ответ в формате фреймворка):

http://192.168.2.60/FM?a=Info

Сделать полный апгрейд софта:

http://192.168.2.60/FM?a=Upgrade

Залить с сайта прошивку (если не указано, то firmware.bin), указывается без .bin

http://192.168.2.60/FM?a=upgrade&file=firmware123

Перезалить на флешку файл loop.txt с сервера (сервер указан в переменной server_update файла config.txt) Если в качестве имени файла указано «all.list» — то перезалить все файлы. Если перезаливается именно loop.txt, то он сразу запустится на выполнение без перезагрузки.

http://192.168.2.60/FM?a=upload&file=loop.txt

Удалить файл:

http://192.168.2.60/FM?a=del&file=nenado.txt

Записать содержимое, создав файл или изменив существующий (POST-запрос):

POST http://192.168.2.60/FM?a=editsave&file=mynewfile.txt
[содержимое файла в теле POST-запроса]

Команды существующие во фреймворке, но для прямого запроса бесполезные:

http://192.168.2.60/FM?a=Restart — Выполнить ESP.restart(); (лучше вызывать просто /restart)
http://192.168.2.60/FM?a=edit&file=loop.txt — Вызвать файл на редактирование во фреймворке

WARNING: Данная система разработана мной под мои задачи и опубликована здесь для друзей в ознакомительных целях. Я ни в коем случае не навязываю ее никому и не предлагаю использовать: вы это делаете на свой страх и риск. Использовать мой код или его части вы можете совершенно свободно в любых своих проектах. По всем вопросам, замеченным ошибкам и предложениям свяжитесь со мной: lleo@lleo.me, Telegram: lleokaganov, +79166801685

 


Комментарии к этой заметке сейчас отключены, надеюсь на понимание.

посещений 498