Теперь, когда мы уже немного понимаем, как работает язык, приступим к подробному описанию всех его команд. Начнем с самого простого:
ESP выводит информацию в uart. Как минимум, при старте — это свойство чипа, с котоым ничего поделать нельзя. Если нужно, чтобы в uart никогда ничего не летело, имеет смысл использовать альтернативные пины uart (TX=15,RX=13 вместо 1 и 3), переключив на них вывод командой «SERIAL.swap 1» Так можно избежать в консоли мусора при старте, но в новую консоль все равно будет сыпаться информация во время работы чипа и процедур фреймворка. И вот её можно регулировать все сразу (ALL) или по группам. Группы логов:
LOG [имя] [n] —
Лог с именем [имя] включить (n=1) или выключить (n=0), пример:
— style='color:, пример:#0000BB'><?php
— {1}, пример:{2}
pinmode [пин] [режим] —
Установить gpio [пин] в один из режимов: OUTPUT (выход), INPUT (вход), INPUT_PULLUP (вход, подтянутый к питанию), пример:
pinmode 5 OUTPUT ; pinmode 4 INPUT_PULLUP
blink (pin) —
поменять значение gpio пин pin с 0 на 1 и наоборот, если пин не указан, по умолчанию пин 2 (лампочка на корпусе, но учтите, что она обратная — 0 горит, 1 потушена), пример:
repeat 10 blink 5 ; sleep 200
pin [пин] [значение] —
записать в gpio пин значение 0 или 1, пример:
pin 5 0
pwm [пин] [значение] —
шим (analog_write) в пин, пример:
pwm 5 100
tone [пин] [значение] —
тон в пин, пример:
tone 5 433
АРИФМЕТИКА И ОПЕРАТОРЫ ПРИСВАИВАНИЯ
Арифметика в нашем языке находится в зачаточном состоянии. Но её, тем не менее, вполне достаточно, чтобы выполнять несложные арифметические вычисления. Наши правила:
— Имена переменных могут быть латинскими, русскими, заглавными, строчными и неограниченной длины, и только пробел они содержать не могут.
— Вычисления можно производить только в операторе присваивания типа X = {Y} / 3 На лету арифметика не работает, нельзя написать «echo {Y} / 3»
— В строке мы перечисляем числа, имена переменных (в фигурных скобках), знаки математических операций, и всё это разделяем одним пробелом.
— В операторе присваивания = можно делать сразу несколько вычислений: X = {Y} / 3 + 1 * {K}, при этом порядок выполнения будет последовательным, без приоритета операций. Чисто физически наш интерпретатор имеет аккумулятор, значение которого в конце присвоит переменной, и двигается вперед по строке, производя с аккумулятором всё новые действия.
— У нас нет скобок. Извините за временные неудобства.
— Все незаданные пока переменные считаются пустыми строками, поэтому если их использует арифметика, то это будет 0.
— Все вычисления в ESP производятся с типом double (4 байта, фиксированная точка — 2 знака после запятой). Я точно не помню параметры, но можно оперировать достаточно громадными числами, не боясь вылезти за рамки. Плавающей точки нет — точка фиксированная: ровно два знака после запятой. «X = 3.1415925 ; echo {X}» даст 3.14 В принципе, этой точности нам должно хватать.
ОПЕРАТОРЫ ПРИСВАИВАНИЯ
[переменная] = [формула] —
Присвоить переменной значение, которое может быть числом, другой переменной или результатом вычисления формулы. Внимание! Имя переменной в момент присваивания указываем без фигурных скобок как в sh! Скобки понадобятся позже — когда мы читаем значение переменной, пример:
# примеры простых и сложных присваиваний
G = 9.8
Radius = 10
Тракторов-или-велосипедов = 3
X = 2 * 3.14 * {Radius} / {G}
echo результат: {X} для {Тракторов-или-велосипедов} единиц транспорта
# результат: 6.41 для 3 единиц транспорта
set [переменная] = [строка] —
Присвоить переменной текстовую строку. Никаких вычислений не производится, пример:
<?php
set Y = 10 + {LIMIT} + {X} * 10
echo результат: {Y}
# результат: 10 + {LIMIT} + {X} * 10
[переменная] ~ [значение] —
Присвоить переменной инвертированное число или переменную (тип word 16 бит). Никаких дальнейших вычислений здесь быть не может, пример:
<?php
X ~ 2
Y ~ {X}
echo X={X} Y={Y}
# X=65533 Y=2
[переменная] unsigned [значение] —
Присвоить переменной значение целочисленный unsigned int — без учета знака и дробной части. Никаких дальнейших вычислений здесь быть не может, пример:
<?php
X unsigned -1.11111
Y unsigned 3.1415
echo X={X} Y={Y}
# X=65535 Y=3
ОПЕРАТОРЫ МАТЕМАТИКИ
+ —
сложение, пример:
X = 2 + 2
— —
вычитание, пример:
X = 2 — 2
* —
умножение, пример:
X = 2 * 2
/ —
деление, пример:
X = 2 / 2
+= —
добавление, пример:
X += 2 # увеличили X на 2
-= —
довычитание, пример:
X -= 2
*= —
доумножение, пример:
X *= 2
/= —
доделение, пример:
X /= 2
% —
остаток от деления, пример:
X = 10 % 7 # 3
ПЛАНИРОВАНИЕ ВРЕМЕНИ, ЦИКЛЫ, ЗАПУСК ЗАДАЧ
В системе можно устанавливать циклы, которые будут выполнять определенные действия через определенное количество секунд — регулярно, однократно или некоторое заданное число раз. В качестве действий указывается СТРОКА — это может быть имя файла (тогда будет исполняться он) или одна команда, или последовательность команд, разделенных ; (для команд, исполняемых по сети в GET-запросе можно также использовать разделитель |) Однако можно указать небольшой скрипт в несколько строк, разместив его в фигурных скобках, соблюдая пробелы — примерно как мы видели в примере выше с командой mainloop { ... }
[filename] —
Исполнить скрипт filename, пример:
/MOTOR_STOP
run [filename] —
То же самое, но в отличие от предыдущего примера, с этой командой можно делать вызовы сложнее, пример:
if {N} < 5 N += 1 else N = 0
run /SCRIPT_{N}.TXT
loop (номер) [time] [действия] —
Выполнять действия с интервалом time, который задается в секундах. Все отложенные таймеры и циклы задаются в секундах, меньше нет смысла. Если указан номер для цикла, то циклу присваивается конкретный номер, чтобы его можно было изменить, остановить или посмотреть, сколько осталось до срабатывания. Цикл номер 1 изначально зарезервирован под обновление софта. Чтобы отключить обновление используйте команду loop.del 1, пример:
loop 1 0
loop 10 blink 4 ; blink 5 ; if {gpio3} = 1 exit
loop 1 84600 /UPGRADE.txt
loops [количество] (n) [time] [действия] —
Запустить loop на определенное количество повторов, пример:
{2}
at [time] [действия] —
Выполнить действия однократно через отложенное время. Это можно записать через команды loop, но так удобней и короче., пример:
at 10 /MOTOR-STOP
at 0 play DRM
now [действия] —
Выполнить действия безотлагательно сразу после завершения данного скрипта (то же, что at 0). Полезно во время прерываний и во всех прочих случаях, когда не хочется тратить время сейчас, а задачу запустить надо., пример:
now play DRM
loop.del [n] —
Удалить цикл номер n, пример:
loop.del 1 # остановить запросы на обновления
loopfile [скрипт] —
Установить скрипт в качестве основного цикла (выполняющегося без задержек), пример:
loopfile /my_loop.txt
loopfile { if {gpio4} == 1 blink 3 }
sleep [секунды] —
выполнить паузу в несколько секунд. Внимание! Не рекомендуется использовать эут команду, потому что останавливаются все процессы! Лучше запустить отложенную задачу командой at., пример:
{2}
delay [миллисекунды] —
выполнить паузу (1000 миллисекунд = 1 секунда), также можно использовать синоним delay — usleep, пример:
delay 200
exit —
прекратить сейчас выполнение этого скрипта, пример:
if {k} = 0 exit
stop —
прекратить не только выполнение скрипта, но и его повторный запуск, если он циклически повторялся по таймеру, пример:
if {k} > 300 { stop } else { exit }
repeat [N] [действия] —
повторить N раз действия, пример:
repeat 10 echo привет!
repeat 10 {
k += 1
echo привет! k={k}
}
break —
прекратить repeat досрочно, пример:
{2}
echo [строка] —
Напечатать строку в Serial-консоль, пример:
{2}
settime [UnixTime] (Hour:Min:Sec) —
Установить время, пример:
settime 1524235234 23:01:59
ping (timeout) [url] —
выполнить скрипт, получив его с сервера url. Если первым аргументом указан timeout в мс (по умолчанию 3000), то использовать его, пример:
if {gpio4} = 1 ping http://lleo.me/robot?signal=была-нажата-кнопка-4
РАБОТА С ПЕРЕМЕННЫМИ
В нашем языке короткая конструкция в фигурных скобках без пробелов — это всегда кандидат на подстановку значения. Имя переменной должно состоять из латинских букв не менее 8 символов, обязательно содержать заглавные и строчные, цифру и хотя бы один специальный символ... Да шучу, шучу! Имя может быть любым, даже кириллицей, лишь бы не было пробелов. Но учтите, что память у чипа куцая, и чем короче имя, тем ему легче.
[имя] = [выражение] —
Присвоить переменной результат вычисления числового значения. При вычислении можно использовать операторы =, +, -, *, /, а также +=, -=, *=, /=. К сожалению, ни приоритет операций, ни обработка скобок пока не сделаны. Разбивайте на несколько переменных., пример:
LIMIT = {gpioA0} * 4 — 1024 + {MAXIMUM}
set [имя] [текст] —
Задать переменной текстовое значение, оно может содержать даже пробелы, пример:
set server = http://lleo.me
set
УСЛОВИЯ
if [ARG1] [условие] [ARG2] [действия] —
сравнить два аргумента, допустимы условия =, ==, !=, >, >=, <, <= Учтите, что = и == не различаются. В качестве аргумента может быть что-то в фигурных скобках — имя переменной, служебная константа, системные данные., пример:
if {gpioA0} >= 300 {
echo Ток превышен, насос перегружен!
if {gpioA0} > 800 echo Возможно, он заржавел и его вообще заело?
} else {
if {gpioA0} < 100 echo Слабая нагрузка, возможно, в колодце кончилась вода?
else echo Насос работает в штатном режиме...
}
else [действия] —
если не выполнилось условие предыдущего if, пример:
{2}
if.empty [arg] [действия] —
выполнить действия если аргумент равен пустой строке, пример:
{2}
if.!empty [arg] [действия] —
выполнить действия если аргумент не равен пустой строке, пример:
{2}
ifrand [N] [действия] —
выполнить действия если случайно выпал 1 шанс из N, пример:
ifrand 100 echo Вы попали в 1% счастливчиков!
if.WIFI [действия] —
выполнить действия если установлено соединение с местным WiFi, пример:
ifwifi ping http://myserver.ru?say=WiFi_connected
if.!WIFI [действия] —
выполнить действия если подключиться к WiFi не удалось, пример:
ifnowifi pin 4 1 # зажечь сигнальный светодиод gpio4
РАБОТА С ФАЙЛОВОЙ СИСТЕМОЙ
Здесь почти все самые необходимые команды для работы не только с файлами, а также с файлами-списками и файлами-данными. В качестве данных удобно использовать формат файла, где каждая строка записана через пробел как «КЛЮЧ ЗНАЧЕНИЕ». Так можно делать небольшие ьбазы данных, например, список бесконтактных карт с именами владельцев.
if.FILE [filename] [command] —
Если файл существует, выполнить команду, пример:
{2}
if.!FILE [filename] [command] —
Если файл не существует, выполнить команду, пример:
if.!FILE 1.txt FILE.save 1.txt 123
FILE.save [filename] [text] —
Записать файл, состоящий из строки или текста в фигурных скобках, пример:
<?php
FILE.save 1.txt {
0001 товары и услуги
0002 объекты и кредиты
}
FILE.add [filename] [text] —
Дописать к файлу текст, пример:
FILE.add /1.txt 0003 реклама и рассылки
FILE.add.ln [filename] [string] —
Дописать строку к файлу, заменив в ней \n на перевод строки FILE.add /1.txt 0004 недвижимость\n0005 ремонт, пример:
{2}
FILE.save.text [filename] [string] —
Записать файл, состоящий из строки, заменив в ней \n на перевод строки, пример:
{2}
FILE.add.text [filename] [string] —
Дописать к файлу строку, заменив в ней \n на перевод строки, пример:
{2}
FILE.del [filename] —
удалить файл, пример:
{2}
FILE.rename [from] [to] —
переименовать файл, пример:
FILE.rename /1.txt /2.txt
FILE.copy [from] [to] —
скопировать файл, пример:
FILE.copy /ESP.jpg /mainfoto.jpg
FILE.string.del [filename] [string] —
удалить из файла строку по началу до пробела, если такая была, пример:
FILE.string.del /1.txt 0002 объекты и кредиты
FILE.string.add [filename] [string] —
добавить в файл строку, если такого начала (до пробела) не было, пример:
FILE.string.add /1.txt 0002 объекты и кредиты
FILE.key.add [filename] [key] [value] —
Обновить в файле значение value для ключа key (формат файла — в каждой строке первое слово — ключ, через пробел — его значение), если строки с таким ключом (первым словом) не существует, то добавить ее в конец файла, пример:
FILE.key.add /1.txt 0001 товары и продукты
FILE.key.del [filename] [key] —
Удалить из файла запись о ключе key, пример:
FILE.key.del /1.txt 0001
{KEY:[filename] [key]} —
Напомним, что так можно получить value по значению key из файла, пример:
echo Цена для «морковь» = {KEY:/baza-cen.txt морковь} руб.
РАБОТА С ПРЕРЫВАНИЯМИ ОТ GPIO
INTERRUPT.add [pin] [mode] [script] —
Включить аппаратное прерывание по пину pin в режиме mode: 1 или RISING, 0 или FALLING или 2 или CHANGE. При возникновении прерывания будет исполняться скрипт. Важно учесть, что в прерывании нельзя исполнять сложных и долгих операций, код скрипта (или файла, который будет исполняться) должен быть максимально краток, например обновить значение какой-то своей переменной. Все затратные действия следует задать на исполнение в следующую секунду — командой at 1 [скрипт или имя файла]., пример:
<?php
INTERRUPT.add 12 CHANGE blink {sound.pin}
INTERRUPT.del [pin] —
Отключить аппаратное прерывание по пину pin, пример:
INTERRUPT.del 12
РАБОТА С ВНУТЕННИМИ ФУНКЦИЯМИ ESP
ESP.restart — выполнить ESP.restart();
ESP.reset — выполнить ESP.reset();
SPIFFS.format — отформатировать карту памяти, удалив все файлы
ESP.deepSleep [microsec] [mode] — Уснуть на несколько микросекунд, возможные режимы mode: WAKE_RF_DEFAULT, WAKE_RFCAL, WAKE_NO_RFCAL и WAKE_RF_DISABLED. Контакт GPIO16 должен быть соединен с RST, чтобы вывести чип из режима глубокого сна.
РАБОТА С WIFI
WIFI [network] (password) — подключиться к сети
WIFI.reconnect — Чип отключается от точки доступа и делает повторное подключение.
WIFI.disconnect (true) — SSID и пароль на null, отключить станцию от точки доступа. Если добавлен аргумен «true», это выключит режим станции.
WIFI.APdisconnect (true) — Выставляет SSID и пароль на null, отключает станцию от точки доступа. Если true, это выключит режим станции.
if.WIFI [команда] — Выполнить, если установлено соединение с интернетом
if.!WIFI [команда] — Выполнить, если не установлено соединение с интернетом
WIFI.persistent (false) — сохранять ли на флеш-память каждый раз пароль, по умолчанию false — не сохранять
WIFI.autoconnect (true) — Чтобы при включении питания автоматически подключался к последней использованной точке доступа. Если false, автоматическое подключение будет деактивировано, иначе активировано
if.WIFI.autoconnect [команда] — выполняет команду, если у модуля активировано автоматическое подключение
WIFI.autoreconnect (true) — Если параметр true, модуль делает повторное подключение, а если false, то нет
WIFI.waitconnect — Ждет, когда модуль подключится к точке доступа, очень нужная функция сразу после WIFI
WIFI.diag — WiFi.printDiag(Serial)
WIFI.hostname [name] — Устанавливает WiFi.hostname
WIFI.mode [mode] — устанавливает WiFi.mode: STA — станция, AP — точка доступа, AP_STA — и то и другое
WIFI.config [ip] [gateway] [mask] (dns1) (dns2) — Ручная установка параметров
WIFI.AP [name] [password] (channel) (hidden) — поднять свою точку доступа WIFI.AP: логин, пароль, также можно указать номер канала и флаг true — скрывать
WIFI.APconfig — [ip] [gateway] [mask]
WIFI.dns (flag) — поднять свой DNS-сервис если флаг true (по умолчанию) и отключить если false
WiFi.scanNetworks (true) —
Запустить фоновую процедуру сканирования сетей, есkb true — то скрытые сети показывать тоже. Результат можно получить, читая переменную {WiFi.scanComplete}, пока вместо «wait» она не вернет список сетей, каждая строка соответствует сети и содержит через пробел:
— style='color:
—
{1} WiFi.scanDelete — Очистить результат последнего сканирования (не надо, это автоматически происходит)
echo {WIFI.scan} — Вернуть список сетей одной командой (с ожиданием, устаревший способ)
РАБОТА С UDP и NTP (синхронизация часов)
NTP.update (url) —
Синхронизировать время по WiFi или LAN, url можно указать (по умолчанию time.nist.gov), порт всегда 123, пример:
<?php
NTP.update mysite.com
NTP.update 192.168.100.200
loop 600 NTP.update
?>
UDP.send [url:port] [Data] —
отправить пакет Data по UDP на url:port, ответ не принимать, пример:
UDP.send 10.8.0.72:8313 The Text Of Packet for Sending
UDP.ping [url:port] [Data] —
отправить пакет Data по UDP на url:port, в ответ принять консольные команды и выполнить их процедурой MOTO(), пример:
UDP.send 10.8.0.72:8313 Ask
UDP.get [url:port] [Data] —
отправить пакет Data по UDP на url:port, в ответ принять некие данные и сохранить их в переменной UDP_result, при получении выполнить процедуру UDP_func, пример:
<?php
set UDP_result =
set UDP_func = {
if {UDP_result} = OK play D.R.M
else play mmm
}
UDP.get mysite.com:8813 Erase_all
?>
РАБОТА С MDNS
MDNS.begin [name] — Запустить сервис https://[name].local или остановить если указано пустое имя. Скажем прямо — бессмысленная вещь в реальной жизни.
РАБОТА СО ЗВУКОМ
play (pin) [music] —
сыграть ноты music на пине pin (если не указан, берется по умолчанию soundpin), музыка кодируется в формате гаммы: DRMFSLCdrmfslc Точка и запятая обозначают паузы длинную и короткую. Если pin не указан (в нормально написанных скриптах его не надо указывать), то используется ранее установленная переменная {sound.pin}. Важно заметить, что переменная {sound.pin.0} указывает, в какое состояние вернуть pin по окончании звучания — по умолчанию это 0, но для устройств, которые используют, например, инвертер для звука, это важно., пример:
play 4 M,d,d,d,d,dd.C,C,r,r,d,C,CC.L,L,L,LS,F,MM.d,dCCC.drddd...M,d,d,d,d,dd.C,C,r,r,d,C,CC.L,L,L,LS,F,MM.d,M,M,L,CCCCC
playip (пин) —
высвистеть последние три цифры полученного IP в местной сети в пине (если не указан, то soundpin)"), например для 10.9.0.203 это эквивалентно цепочке команд: repeat 2 play 4 M, ; play 4 .. ; repeat 0 play 4 L, ; play 4 .. ; repeat 3 play 4 d,, пример:
{2}
mp3 [файл.mp3] —
Воспроизвести в эмулированном пине RX файл mp3. Увы, только очень короткие файлы можно, иначе катастрофически не хватает памяти., пример:
mp3 /pes.mp3
mp3stop —
Остановить воспроизведение mp3, пример:
mp3stop
mp3web [урл] —
Отключено, потому что чип, скомпилированный в Ардуине, да еще со всем остальным фреймфорком, висящим в памяти, банально не тянет., пример:
mp3web http://radio.4duk.ru/4duk128.mp3
РАБОТА С SERIAL
SERIAL.begin (speed) —
инициализировать Serial с нужной скоростью, есмлит не указана, то 115200 по умолчанию, пример:
SERIAL.begin 9600
SERIAL.end —
остановить Serial, пример:
SERIAL.end
SERIAL.flush —
очистить буффер, пример:
SERIAL.flush
SERIAL.swap (конфигурация) —
переключить GPIO Serial с RX=3,TX=1 (конфигурация 0) на RX=13,TX=15 (конфигурация 1) и обратно, но также можно строго указать номер конфигурации, пример:
SERIAL.swap 1 # RX=13,TX=15
SERIAL.swap 0 # RX=3,TX=1
echo [string] —
напечатать строку, пример:
echo Только что пришла по Serial строка: {SERIAL}
РАБОТА С СЕРВО
attach [номер серво] [пин] —
подключить сервопривод к gpio [пин], пример:
attach 1 5
detach [номер серво] —
отключить сервопривод к gpio [пин], пример:
detach 1
go [номер серво] [градус] —
повернуть сервопривод в нужное положение, пример:
go 1 180
Считыватель бесконтактных карт WIEGAND
WIEGAND.start [pin0] [pin1] [mode] —
Активировать считыватель Wiegand. pin0 — gpio для получения 0, pin1 — gpio для получения 1, mode — битность 26 или 34, пример:
WIEGAND.start 2 3 34
WIEGAND.end —
Отключить считыватель WIEGAND, пример:
WIEGAND.end
{WIEGAND} —
Переменная, из которой считывается полученный код, если есть, пример:
<?php
set CARD = {WIEGAND}
if.!empty {CARD} echo Введена карта, ее номер: "{CARD}"!
РАБОТА С NFC-СКАНЕРОМ БЕСКОНТАКТНЫХ КАРТ RFID-RC522
RC522.init —
Активировать сканер карт RC522, подключенный как RST=GPIO5, SDA(SS)=GPIO4, MOSI=GPIO13, MISO=GPIO12, SCK=GPIO14, GND=GND, 3.3V=3.3V, пример:
RC522.init
{RC522.ver} —
чтение байта версии в 16-ричном коде (обычно 91 или 92), пример:
if {RC522.ver} != 91 {
echo Кажется, наш сканер подвис, тихонько перезапустим его
RC522.init
}
{RC522.card} —
чтение карты: возвращает пустое знаечние, если карта еще не была поднесена, или ее номер, если недавно была поднесена, пример:
<?php
set CARD = {RC522.card}
if.!empty {CARD} echo Введена карта, ее номер: "{CARD}"!
{KEY:[filename] [key]} —
Простой способ организовать элементарные базы данных (и не только для NFC-сканнера). Если в файле filename найдется строка, первое слово которой — ключ key, то вернуть значение (остальную часть строки), иначе вернуть пустое значение. ВАЖНО: при извлечении даже цифровых переменных всегда используйте оператор set. set X = {KEY:...}, а не просто X = {KEY:...}, пример:
<?php
set CARD = {RC522.card}
if.!empty {CARD} {
echo Поднесли карту номер: "{CARD}"
set NAME = {KEY:/keybasa.txt {CARD}}
if.empty {NAME} echo Ключа нет в списке доступа!
else {
echo Добро пожаловать, уважаемый {NAME}!
/DOOR_OPEN_ENGINE
}
}
РАБОТА MQTT
MQTT.connect [url:port] [login] [password] — соединиться с сервером MQTT, если порт не указан, то 1883. Параметры при вызове этой процедуры также запоминаются в системных переменных
MQTT_server, — MQTT_port,
MQTT.reconnect — выполнить пересоединение с MQTT
MQTT.publish [topic] [string] — Публикация в топике
MQTT.subscribe [topic] — подписка на топик
MQTT.unsubscribe [topic] — отписка от топика
РАБОТА MODBUS/TCP SLAVE
MODBUS.begin — запустить иницилизацию
MODBUS.add [reg] (value) — создать регистр (номер от 1 до 9999), можно указать ему сразу значение для инициализации
MODBUS.save [reg] (value) — записано новое значение в созданный ранее регистр
РАБОТА C ДАТЧИКАМИ
DS18B20.begin —
запустить инициализацию датчика температуры DS18B20, датчик поключают по onewire к GPIO4, и только к нему, уж извините. Схема подключения:, пример:
— style='color:, пример:#0000BB'><?php
— {1}, пример:{2}
РАБОТА C АНАЛОГОВЫМ ВХОДОМ A0
calibrate [пин] [N] [имя] —
Провести калибровку: рассчитать среднее арифметическое от N измерений пина (конечно он всегда A0) каждые 10 мс и сохроанить в переменную с указанным именем, пример:
calibrate A0 20 SREDNEE
echo Сейчас среднее значение измерений = {SREDNEE}
MOTORSTOP [N] —
Установить значение внутренней переменной для срабатывания для системы контроля мгновенной остановки мотора, пример:
{2}
TIMER.start (ms) —
Запустить таймер кольцевой записи параметров всех пинов. Это сложная процедура, которая проводит очень частые (можно указать время в ms, по умолчанию 50) проверки состояния пинов. При этом проводится вычисление Z-фильтра на появление пиков, а также обработка некоторых случаев с вызовом соответствующих процедур., пример:
TIMER.start 50
TIMER.stop —
Остановить кольцевую запись пинов, пример:
TIMER.stop
set.FLT [lag] [TOL] [THRESHOLD] [INFLUENCE] —
Установить параметры сглаживающего фильтра измерений, пример:
set.FLT 15 64 6 1.5
echobuf [N] —
Выдать содержимое кольцевого буфера измерений, начиная с N, пример:
echobuf 0
Операции текстовых строк
{GET:[url]} —
загрузить страницу из сети (очень короткую! памяти не хватит!) по адресу url, также можно первым аргументом перед url через пробел указать таймаут в мс: {GET: 500 http://lenta.ru/robots.txt}, если не указан, то по умолчанию 5000мс., пример:
set unixtime = {GET: 2000 http://lleo.me/ESP8266/index.php?unixtime=1}
{FILE:[файл]} —
Загрузить (с внутренней флешки) содержимое файла с именем «файл», пример:
set num = {FILE:/numer.txt}
{FILEMD5:[файл]} —
подсчитать хэш MD5 файла с именем «файл», пример:
set md5string = {FILEMD5:/ESP.jpg}
{PARSE:[переменная] [шаблон]} —
ищет в строковой переменой данные по шаблону, где нужный кусок обозначен * Также понимает обозначения: \n \r, пример:
set time = 06:40
set h = {PARSE:time *:}
set m = {PARSE:time :*}
echo m={m} h={h}
{TAKE:[name] [num] [sep]} —
Разобрать текстовую переменную с именем [name] на аргументы по сепаратору [sep] (если не указан, то разделить по пробелам) и взять аргумент номер [num], пример:
{2}
{SET} —
вывести дамп всех переменных в формате «имя = [значение]\n», пример:
{2}
{INFO} —
вывести полное инфо, как /info, пример:
{2}
{dir} —
дать список всех файлов на внутренней флешке в формате «[имя] [размер]\n», пример:
{2}
{WIFI.scan} —
дать список WiFi-сетей вокруг в формате «[доступ] [имя сети]\n», где доступ «free» для открытых и «pass» для закрытых, пример:
{2}
Служебные переменные
Команда формата {имя} покажет значение пользолвательской переменной.
Но в системе есть различные предопределенные переменные, динамические значения, результаты сложных взаимодействий с внешними устройстами и так далее. У них есть свои имена, вот они:
GPIO
{gpio[N]} — прочесть значение gpio 1,2,3,4,5,12,13,14,15,16 и A0
Сеть
{ip} — полученные IP WiFi.localIP().toString()
{ip_mask} — WiFi.subnetMask()
{ip_gateway} — WiFi.gatewayIP()
{macAddress} — WiFi.macAddress()
{ip_connected} — 1 или 0 WiFi.isConnected() ? 1 : 0
{ip_autoconnect} — 1 или 0 WiFi.getAutoConnect() ? 1 : 0
{ip_dns} — WiFi.dnsIP(0) + WiFi.dnsIP(1)
{ip_hostname} — WiFi.hostname()
{ip_status} — WiFi.status()
{ip_ssid} — WiFi.SSID()
{ip_psk} — WiFi.psk()
{ip_bssid} — WiFi.BSSIDstr()
{ip_rssi} — WiFi.RSSI()
{softAPIP} — WiFi.softAPIP()
{softAPmacAddress} — WiFi.softAPmacAddress()
{softAPgetStationNum} — WiFi.softAPgetStationNum()
{mdns} — return String(mdns);
{LAN.started} — Есть ли внешний Ethernet через подключенное устройство
Внутренние параметры чипа ESP
{ESP_TYPE} — тип ESP, например: ESP-12, ESP-32, ESP32S2, ESP32S3, ESP32C3
{FreeHeap} — ESP.getFreeHeap()
{FreeSketchSpace} — ESP.getFreeSketchSpace()
{SketchSize} — ESP.getSketchSize()
{chip} — ESP.getChipId() HEX
{FlashChipId} — ESP.getFlashChipId()
{FlashChipSize} — ESP.getFlashChipSize()
{FlashChipRealSize} — ESP.getFlashChipRealSize()
{FlashChipSpeed} — ESP.getFlashChipSpeed()
{cycles} — ESP.getCycleCount()
{CoreVersion} — ESP.getCoreVersion()
{FullVersion} — ESP.getFullVersion()
{BootVersion} — ESP.getBootMode()
{BootMode} — ESP.getCycleCount()
{CpuFreq} — ESP.getCpuFreqMHz()
{FlashChipSizeByChipId} — ESP.getFlashChipSizeByChipId()
{getSketchMD5} — ESP.getSketchMD5()
{ResetReason} — ESP.getResetReason()
{ResetInfo} — ESP.getResetInfo()
{flashmode} — ESP.getFlashChipMode() — возвращает QIO, QOUT, DIO, DOUT, UNKNOWN
{vcc} — ESP.getVcc()
Файловая система
{Files} — Список всех файлов внутренней флешки в формате " [имя]"
{Files_count} — число файлов внутренней флешки
{SPIFFStotal} — общее количество байт в файловой системе
{SPIFFSused} — количество занятых байт в файловой системе
{SPIFFSfree} — количество свободных байт в файловой системе
Прошивка и ее опции
{VER} — номер версии прошивки (число)
{VERNAME} — имя версии прошивки
{MOTORSTOP} — флаг остановки мотора
{NBUF} — константа — размер буфера
{NLOOP} — константа — максимальное количество циклов
{NSET} — константа — максимальное количество переменных
{NSERV} — константа — максимальное количество серв
{EchoMOTO} — return EchoMOTO;
Обработка данные аналогового входа A0
{MaxA0} — Значение максимума для срабатывания прерывания по максимуму
{MinA0} — Значение минимума для срабатывания прерывания по минимуму
{FltA0} — Значение фильтра
Время
{UnixTime} — текущее время UnixTime (начинает тикать с 0 в момент старта, нопозже можно записать настоящее время)
{hh} — текущие часы
{mm} — текущие минуты
{ss} — текущие секунды
{dn} — день недели, номер 0-6
{ddn} — день недели su mo tu we th fr sa
{Time} или {hhmmss} — время в формате hhmmss
{millis} — число миллисекунд millis();
Внешние устройства
{MQTT} — если сервис MQTT поднят, то 1, иначе 0
{DS18B20} — считать показания температурного датчика Dallas
{WIEGAND} — код последней введенной беспроводной карты
{RC522.ver} — версия прошивки считывателя rc522 ( 0x91 или 0x92 )
{RC522.card} — код последней прочитанной беспроводной карты со считывателя rc522
{SERIAL} — прочесть строку из внутреннего Serial, если была
MODBUS
{MODBUS.started} — если сервис ModBus уже был инициализирован, то 1, иначе 0
{MODBUS.last} — показать дамп последнего запроса
{MODBUS:[reg]} — значение регистра reg
ПРИМЕРЫ
{LOOP:[N]} —
Число оставшихся секунд до срабатывания цикла по его номеру, пример:
echo До обновления сфота осталось {LOOP:1} секунд
{LOOP:[действия]} —
Возвращает число оставшихся секунд до срабатывания цикла по его исполняемой команде (если ее помним или это было имя файла, неудобная команда), пример:
echo {LOOP:/MOTOR_STOP.txt}
{LOOP} —
вывести дамп всех циклов в формате «Loop #[N] [count] of [value] [тело] ONE\n» ONE добавляется — если цикл однократный, пример:
{LOOP}
Системная часть — edge
Также есть системная веб-часть по обращению к веб-сайту чипа, например http://192.168.4.1/info
GET /FM?a=login&password=MYPASSWORD — логиниться админом, получить в ответ hash пароля — доступно всем, не только админу
GET /FM?a=loop&n=3 — показать сколько осталось секунд до выполнения цикла номер (например 1) — доступно всем, не только админу
GET /FM?a=WIFIconn1 — переконнектиться по WiFI если сеть была «ESP-HELP», передает «net»+«pass», записывает их в «wifi_last.txt» — доступно всем, не только админу
GET /info — страница полной информации о чипе и системе
GET /dir — список файлов на флешке
POST /upload — загрузка файлов на флешку методом POST
POST / — выполнить скрипт, которые передается методом POST
GET /MOTO?script — выполнить скрипт, в котором разделители строк заменены на знак «
GET /MOTO?hash=5fd310ef5fd7e6ab523&script — то же, но выполнить скрипт от незалогиненного пользователя, указав правильный парольный hash
Авторизация
Система позволяет выполнить произвольный скрипт на устройстве, но для этого надо знать пароль, установленный в config.txt («set password = ...»). Сам пароль используется только во время логина, при этом чип возвращает 32-символьный hash MD5, который зависит не только от пароля, но и от уникального серийного номера каждого чипа (для ESP12 это серийный номер чипа и памяти, для ESP32 — МАК-сдрес). В дальнейшем система считает запрос от админа, если правильный хэш передан в куках «ESP=...», либо указан в строке параметров «hash=...»
Вот один из способов управлять устройством с компьютера, зная лишь IP и пароль админа. Сперва надо получить хэш, затем исполнять скрипты — их можно передавать методом POST на эндпоинт «/», либо в строке запроса на эндпоинт «/MOTO», заменяя переводы строк на знак «|».
#!/bin/sh# change password
hash=`wget -q -O - "http://10.9.0.133/FM?a=login&password=Zyablik123"`
wget -q -O - "http://10.9.0.133/MOTO?hash=${hash}&echo Old Password:{FILE:wifi_last.txt}|
FILE.save.text wifi_last.txt kv121\\nPassword12345|echo New Password{FILE:wifi_last.txt}|pinmode 4 OUTPUT|play 4 DRM"