Внимание! Статья была отредактированна в сентябре 2023 года. Были исправлены битые ссылки, логи и опции утилиты esptool.py были приведены к современному виду. Было сделано множество уточнений и дополнений, добавлена информация про прошивку модулей ESP8266/ESP32 Микропитоном(MicroPython), а также по установке прошивки "умной розетки" Sonoff Tasmota. Старую версию статьи можно найти по следующему адресу: "перейти по ссылке".
Появившись в далеком 2014 году, модули на базе чипа ESP8266 наделали много шума, подняв настоящее цунами, которое переросло в IoT революцию в электронике. Производителем чипов была на тот момент никому неизвестная китайская фирма "Espressif Systems", зарегистрированная в Шанхае. Спустя некоторое время, многие фирмы представили на рынок аналогичные модули собственного изготовления, но по цене они были в два - пять раз дороже модулей на ESP8266, и с такими характеристиками "убийцы" ESP8266 сами быстро и без лишнего шума покидали рынок.
В 2016-ом году, фирма "Espressif Systems" представила на рынок ESP32, который существенно превосходил по своим возможностям ESP8266, и интерес к ESP8266 начал сходить на нет. В то время интернет быстро переходил на безопасный протокол HTTPS, который для слабого ESP8266 был не простой задачей.
ESP32 это двухядерный микроконтроллер или SoC, если угодно, работающий на частоте 240MHz и снабженный радио-интерфейсами: WIFI стандарта 802.11 bgn (2.4 GHz), с пропускной способностью до 150 Mbps, и BLE (Bluetooth Low Energy) стандарта 4.2, который был принят в 2014 году, спустя всего год после принятия спецификации 4.1. ЦПУ имеет архитектуру Xtensa, есть аппаратная поддержка чисел с плавающей запятой, 7-уровневый конвейер, 520 кБ ОЗУ, и многое другое (см. документацию: ESP32 Datasheet).
В 2020 году фирма "Espressif Systems" анонсировала чипы "ESP32-S2" - одноядерную версию ESP32, но с большим количеством GPIO, а также чип "ESP32-C3" на новой архитектуре RISC-V. В 2021 был представлен двухядерный чип ESP32-S3 с BLE 5 и векторными инструкциями для ускорения AI-функций. И не так давно, "Espressif Systems" презентовала чипы ESP32-C6 на RISC-V архитектуре с радиомодулями WiFi 6.0, BLE 5.0 и 802.15.4 субгигагерцевого (sub-1GHz) диапазона - ZigBee и Thread и ESP32-C2 с поддержкой нового протокола Matter.
Возвращаясь к ESP8266, он популярен в первую очередь за счет свое цены - около одного доллара. В этой ценовой категории он не имеет аналогов. В свое время модули на ESP8266 послужили основой для огромного количества "умных розеток" и им подобных устройств. Если говорить о ESP12 модулях производства "Ai-Thinker", то здесь имеется около 50 Кбайт ОЗУ, 4 Мбайт флеш-памяти, частота ЦПУ 80МГц, встроенный WiFi контроллер. Модули поставляются как готовые устройства с AT-интерфейсом и с возможностью программирования через Arduino IDE, используя для этого официальный SDK.
В статье разбирается подключение, прошивка, и работа с AT командами ESP8266. Изначально статья была целиком посвящена только ESP8266, но впоследствии я решил добавить главу о перепрошивке модуля с ESP32. AT команды в ESP32 практически все те же, что и в ESP8266, так что, все сказанное относительно работы с AT-командам ESP8266 можно отнести и к ESP32.
Большая часть материала статьи посвящена режиму работы ESP8266, когда он работает в режиме WIFI модема с AT-интерфейсом. Разбираются типовые вопросы: как настроить, что-то скачать, переслать свои данные на сервер, и т.д. Предполагается, что уровень знаний читателя о сетях нулевой. Поэтому я постарался расписать всё максимально доходчиво. Для наглядности, показана работа с программами tcpdump и Wireshark для анализа трафика ESP8266. В качестве вспомогательного оборудования используется WiFi роутер с прошивкой OpenWRT, но вместо него можно использовать любой компьютер с Linux.
Содержание:
Т.к. я счастливый обладатель двух модулей ESP12E и одного NodeMCU v.3 (он тоже на базе ESP12E), то далее речь пойдёт именно о них.
Распиновка модуля ESP12E:
Перед впаиванием модуля в плату я сделал фото обратной стороны модуля, где были нанесены обозначения выводов, после чего фотографию совместил со схемой распиновки: "вид сверху" :
Замечу, что модуль имеет светодиод подключённый к GPIO_2.
Модули ESP12E/ESP12F были спроектированы компанией Ai-Thinker. У них на сайте имеется хороший мануал по модулям их производства: ESP-01/07/12 Series Modules User's Manual. Но фактически, модули могут изготавливаются в Китае кем угодно.
Посмотреть модельный ряд модулей "Ai-Thinker" на базе чипа ESP8266, можно на следующей картинке:
Из всего ряда в ходу сейчас остались: ESP01 который имеет выводы с шагом 2.5 мм, ESP07 который имеет разъём для внешней антенны, и ESP12E/ESP12F. Замечу, что модули ESP01 идут с флешкой на 1 мегабайт, а первые модели шли вообще с 512кБ флеш-памяти.
Распиновка модуля Nodemcu v.3:
Здесь имеется две кнопки: "RESET", и непонятная кнопка "FLASH". Непонятна она потому, что прошивка у NodeMCU происходит в автоматическом режиме, кнопку "FLASH" для этого зажимать не нужно. Также NodeMCU имеет линейный стабилизатор на 3.3 Вольт и USB-UART преобразователь на чипе CP2102. Данную плату можно использовать с беспаячной макеткой, в то время как вариант платы с чипом ch340g туда уже не влазит. Т.е. влазить то он влазит, но при этом закрывает все контактные ячейки.
К недостаткам платы NodeMCU я отнесу то, что она не умеет работать с режимом глубокого сна ESP8266 (deep sleep). После "засыпания" проснуться ESP8266 уже не может, приходится нажимать Reset.
Фирма "Espressif Systems" выпускает свой модуль на базе ESP8266 под обозначением ESP-WROOM-02. В документации во всех примерах используется именно он. Данный модуль имеет сертификат FCC для продажи на территории США:
Заметьте, что на плате имеется знак чувствительности к электростатике. Зимой при сухом воздухе это особенно актуально.
Если плату NodeMCU можно сразу подключать к USB-порту компьютера, то с модулем ESP12 придётся немного повозится.
Нам понадобится USB-UART преобразователь с 3.3 вольтовой логикой, паяльник и несколько проводов. В ESP8266 SDK Getting Started Guide приводится следующая схема подключения:
На фотографии слева видны три провода ведущие к USB-UART преобразователю, "земля" подключена к GPIO_0 и GPIO_15, питание 3.3 Вольт подаётся на EN-пин.
Выглядит это так:
Обратите внимание на жёлтый провод с коннектором. При включении, ESP8266 проверяет состояние GPIO_0. Если он оказывается подключён к "земле", то ESP8266 входит в режим прошивки и какое-то время ждёт, поступление прошивки через UART. Т.о. для прошивки ESP8266 контакт GPIO_0 должен быть подтянут к "земле", для обычной работы он должен быть свободен.
В случае использования модуля ESP12E, подключение будет таким:
Здесь кроме всего прочего, в питанию подтягивается ещё и RESET.
Но всё-таки скрутки проводов - это не дело. Мой взгляд на али привлёк такой адаптер:
Здесь уже есть пара подтягивающих резисторов: GPIO_15 к "земле" и CP_PD/EN к питанию. Отсутствует нижняя группа контактов, но она используется чипом ESP8266 для соединения с флеш-памятью, т.е. для вас она бесполезна. На обратной стороне адаптера имеется опциональная площадка для линейного регулятора на 3.3В в корпусе SOT-89, но вот конденсаторы для него впаивать некуда, так что это площадка бесполезна. В макетку этот адаптер тоже не запихнёшь, габариты не позволят. Но в остальном, на мой взгляд это лучше чем скрутка проводов.
И все-таки я решил делать свою плату. Я уже упоминал, что весной у меня была возможность заказать два комплекта печатных плат в Китае. И если первым комплектом была STM8 Board, то вторым комплектом я заказал платы для ESP8266.
В качестве схемы я выбрал простую схему из статьи "ESP8266 - подключение и обновление прошивки – esp8266":
Я не пытался предварительно собрать её на макетке, чтобы проверить работоспособность, или найти ошибки. Поэтому косяки я отлавливал уже на "железе" ;)
Что же с этой схемой не так? Во-первых, здесь перепутаны контакты GPIO_4 и GPIO_5. К счастью, в моем случае это оказалось не принципиально. Во-вторых, здесь не хватает кнопки на CH_PD/EN. Этот пин отключает питание esp8266. Когда требуется перепрошить ESP12, то приходится выполнять такую последовательность: "Отключите CH_PD от питания, подключите GPIO0 модуля к GND, подключите обратно CH_PD модуля." Мне приходилось просто отключать питание ESP12. Повторять это последовательность по двадцать раз кряду - сильно утомляет. Кнопка с фиксацией на CH_PD/EN и светодиод индикации питания решила бы все проблемы. В принципе, можно использовать USB хаб с кнопками вкл/выкл для питания такой платы. Это удобно. В третьих, здесь не помешали бы подтягивающие резисторы на свободных GPIO. В HiZ состоянии они смогут значительно уменьшить энергопотребление. Если даже они не нужны, то их можно и не впаивать.
К преимуществам данной схемы я могу отнести то, что режим энергосбережения deep sleep здесь работает без каких-либо вопросов. Сам бы я не скоро догадался, что для этого надо ставить резистор на GPIO16.
Вариант платы который у меня получился по этой схеме:
Здесь есть линейный стабилизатор на 3.3 В, кнопка Reset, джампер на GPIO_0, и штыревой разъём для USB-UART преобразователя на чипе FT232RL.
Как я уже сказал, не хватает кнопки питания.
Ещё хотелось бы коснуться темы автозагрузки прошивки в ESP8266, т.е. когда не надо вручную соединять GPIO_0 с землёй для перепрошивки. В статье: "ESP8266 - подключение и обновление прошивки – esp8266" предлагается такая схема с автозагрузкой прошивки:
В руководстве Ai-Thinker я нашёл на мой взгляд более грамотную, схему узла автозагрузки:
В любом случае, для дальнейшей работы вполне сгодится недорогая плата NodeMCU, в которой есть эта самая автозагрузка (правда там не работает ражим энергосбережения "deep sleep").
Для того что бы можно было приступить к изучению AT-команд ESP8266, сначала нужно научиться перепрошивать этот самый ESP8266. Актуальная на настоящий момент версия AT-интерпретатора - 1.7.0, и мне хотелось бы рассказывать о работе именно с этой версией AT-интерпретатора.
Если вы только что приобрели модуль ESP12, то там уже должен быть уже прошит интерпретатор AT-команд, скорее всего какой-нибудь старой версии. В модулях которые я приобрёл, прошивка оказалось годичной давности.
Нам потребуется терминальная программа, и т.к. в дальнейшем все-равно придётся использовать Arduino IDE, то я буду использовать монитор последовательного порта Arduino IDE.
После подключения к ESP12, в мониторе последовательного порта нужно будет выставить окончание строки: "NL & CR" и скорость порта 115200 бод. После нужно подать команду: "AT" и в ответ должно прийти "ОК":
Если отклик "OK" был получен, то ваш модуль ESP12 в порядке и можно начинать работу с ним. В противном случае попробуйте перезагрузить ESP8266 и попробовать снова.
Предположим, что ваш модуль в порядке. Для начала полезно будет взглянуть на загрузочный лог. Для этого смените скорость порта в терминальной программе на 74880 бод и нажмите Reset для перезагрузки ESP8266. В терминале появится такой лог:
ets Jan 8 2013,rst cause:2, boot mode:(3,6) load 0x40100000, len 2408, room 16 tail 8 chksum 0xe5 load 0x3ffe8000, len 776, room 0 tail 8 chksum 0x84 load 0x3ffe8310, len 632, room 0 tail 8 chksum 0xd8 csum 0xd8 2nd boot version : 1.6 SPI Speed : 40MHz SPI Mode : QIO SPI Flash Size & Map: 32Mbit(512KB+512KB) jump to run user1 @ 1000 rf cal sector: 1017 rf[112] : 00 rf[113] : 00 rf[114] : 01 SDK ver: 2.0.0(5a875ba) compiled @ Aug 9 2016 15:12:27 phy ver: 1055, pp ver: 10.2 "�j��
На что нужно смотреть в этом логе?
Версия загрузчика:
2nd boot version : 1.6
Версия загрузчика, версия SDK и версия AT-интерфейса - это разные вещи. За формат загрузочного лога отвечает именно загрузчик. Актуальная на данный момент версия загрузчика - 1.7.
В данном случае загрузчик нам сразу печатает версию SDK:
SDK ver: 2.0.0(5a875ba) compiled @ Aug 9 2016 15:12:27
Имеем SDK двухлетней давности, актуальная версия SDK на настоящий момент - 3.0.0.
SPI Flash Size & Map: 32Mbit(512KB+512KB)
Это формат прошивки: имеется 32-мегабитная флешка, 512кБ отведено под SDK, ещё 512 кБ отведено под пользовательскую прошивку. Заметьте, это не тест. Вместо , 32Mbit может быть запросто и меньший размер при фактически 32Mbit флешке. Это нормально. Идём дальше:
SPI Speed : 40MHz SPI Mode : QIO
Согласно документации на чип winbond 25q32 (Datasheet) может работать на максимальной частоте 100MHz. При этом поддерживаются четыре режима работы: Stndard SPI, Dual SPI, Quad SPI и QPI. Dual SPI эквивалентен скорости работы: частота SPI x 2. Режимы Quad и QPI эквивалентны по скорости работы: частота SPI x 4. "Расплатой" за такие фокусы служит использование дополнительных GPIO для обмена. В вики проекта esptool имеется табличка с режимами работы флеш-памяти ESP8266:
Option Mode Name Pins Used Speed (ESP8266 & ESP32) qio Quad I/O 4 pins used for address & data Fastest qout Quad Output 4 pins used for data Approx 15% slower than qio dio Dual I/O 2 pins used for address & data Approx 45% slower than qio dout Dual Output 2 pins used for data Approx 50% slower than qio
Судя по этой публикации: "Новые ревизии модулей на базе ESP8266 не умеют писать в SPI Flash", сейчас в ESP модулях используется флешка PUYA P25Q80 (Datasheet). С ней могут быть нюансы. Еще одним нюансом является то, что при использовании флешки на 4 мегабайта и больше, следует использовать режим DIO.
В вики сайта esp8266.com имеется карта памяти ESP8266 с определением границ различных регионов, составленная в результате исследования чипа. Я приведу её сокращённую версию взятую из статьи - "Reverse Engineering ESP8266 — часть 1":
Диапазон Описание 0x3FFE8000
—
0x3FFFBFFFоперативная память для пользовательских приложений. При старте модуля может инициализироваться значениями из пользовательской прошивки. 0x3FFFC000
—
0x3FFFFFFFсистемная оперативная память 0x40000000
—
0x4000FFFFсистемный ROM. Отсюда стартует процессор, загружается пользовательская прошивка и здесь находятся основные системные библиотеки. 0x40100000
—
0x4010FFFFоперативная память, содержит пользовательскую прошивку 0x40240000
—
0x40271FFFвторая часть пользовательской прошивки. Здесь находятся код подключенных библиотек и SDK. Подмаплено к flash по адресу 40000h.
В логе печатается результат проверки контрольных сумм регионов: iram1 и dram0. Контрольной суммой является результат последовательно выполнения операции исключающего ИЛИ (XOR).
load 0x40100000, len 2408, room 16 tail 8 chksum 0xe5 load 0x3ffe8000, len 776, room 0 tail 8 chksum 0x84 load 0x3ffe8310, len 632, room 0 tail 8 chksum 0xd8 csum 0xd8
Теперь обратим внимание на эту строку загрузчика:
jump to run user1 @ 1000
Здесь осуществляется переход на пользовательскую программу, в данном случае это AT-интерпретатор.
"�j��
Это выводится слово: "ready".
Сейчас я хочу рассказать об одной проблеме, которая касается только Linux-пользователей. Linux-драйвер USB-UART преобразователя CP2102, который используется в платах NodeMCU не умеет работать на скорости 74880 бод. Проявляется это в такой ошибке:
Я проверял на трёх чипах CP2102, все они выдавали такую ошибку. Это означает, что скорость 74880 бод на них не работает. И например лог загрузки такой платы выглядит так:
Здесь нечитаемыми символами идёт вывод версии SDK. На первый взгляд проблема может показаться несущественной. Но когда вы прошьёте ESP8266 какой-нибудь глючной прошивкой, то ошибки вам будут сыпаться именно на скорости 74880. И вы их прочитать не сможете. Повторю ещё раз, что эта проблема имеется только в Linux-драйвере. В Windows всё работает как часы. Версия моего ядра: 4.4.12, надеюсь в более свежих версиях этот баг уже исправлен. (Примечание из 2023г. На самом деле этот баг никакого отношения в ядру не имеет, это баг терминальной программы. При замене терминальной программы все работает.)
Для прошивки ESP8266 будем использовать флешер - esptool. Это программа с открытым кодом компании "Espressif Systems". Домашняя страница проекта: https://github.com/espressif/esptool. Программа устанавливается следующей командой:
$ pip install esptool
Проверяем:
$ esptool.py -h
usage: esptool [-h] [--chip {auto,esp8266,esp32,esp32s2,esp32s3beta2,esp32s3,esp32c3,esp32c6beta,esp32h2beta1,esp32h2beta2,esp32c2,esp32c6,esp32h2}]
[--port PORT] [--baud BAUD] [--before {default_reset,usb_reset,no_reset,no_reset_no_sync}]
[--after {hard_reset,soft_reset,no_reset,no_reset_stub}] [--no-stub] [--trace] [--override-vddsdio [{1.8V,1.9V,OFF}]]
[--connect-attempts CONNECT_ATTEMPTS]
{load_ram,dump_mem,read_mem,write_mem,write_flash,run,image_info,make_image,elf2image,read_mac,chip_id,flash_id,read_flash_status,write_flash_status,read_flash,verify_flash,erase_flash,erase_region,merge_bin,get_security_info,version}
...
esptool.py v4.6.2 - Espressif chips ROM Bootloader Utility
positional arguments:
{load_ram,dump_mem,read_mem,write_mem,write_flash,run,image_info,make_image,elf2image,read_mac,chip_id,flash_id,read_flash_status,write_flash_status,read_flash,verify_flash,erase_flash,erase_region,merge_bin,get_security_info,version}
Run esptool.py {command} -h for additional help
load_ram Download an image to RAM and execute
dump_mem Dump arbitrary memory to disk
read_mem Read arbitrary memory location
write_mem Read-modify-write to arbitrary memory location
write_flash Write a binary blob to flash
run Run application code in flash
image_info Dump headers from a binary file (bootloader or application)
make_image Create an application image from binary files
elf2image Create an application image from ELF file
read_mac Read MAC address from OTP ROM
chip_id Read Chip ID from OTP ROM
flash_id Read SPI flash manufacturer and device ID
read_flash_status Read SPI flash status register
write_flash_status Write SPI flash status register
read_flash Read SPI flash content
verify_flash Verify a binary blob against flash
erase_flash Perform Chip Erase on SPI flash
erase_region Erase a region of the flash
merge_bin Merge multiple raw binary files into a single file for later flashing
get_security_info Get some security-related data
version Print esptool version
optional arguments:
-h, --help show this help message and exit
--chip {auto,esp8266,esp32,esp32s2,esp32s3beta2,esp32s3,esp32c3,esp32c6beta,esp32h2beta1,esp32h2beta2,esp32c2,esp32c6,esp32h2}, -c {auto,esp8266,esp32,esp32s2,esp32s3beta2,esp32s3,esp32c3,esp32c6beta,esp32h2beta1,esp32h2beta2,esp32c2,esp32c6,esp32h2}
Target chip type
--port PORT, -p PORT Serial port device
--baud BAUD, -b BAUD Serial port baud rate used when flashing/reading
--before {default_reset,usb_reset,no_reset,no_reset_no_sync}
What to do before connecting to the chip
--after {hard_reset,soft_reset,no_reset,no_reset_stub}, -a {hard_reset,soft_reset,no_reset,no_reset_stub}
What to do after esptool.py is finished
--no-stub Disable launching the flasher stub, only talk to ROM bootloader. Some features will not be available.
--trace, -t Enable trace-level output of esptool.py interactions.
--override-vddsdio [{1.8V,1.9V,OFF}]
Override ESP32 VDDSDIO internal voltage regulator (use with care)
--connect-attempts CONNECT_ATTEMPTS
Number of attempts to connect, negative or 0 for infinite. Default: 7.
Подключим ESP8266 к компьютеру и попробуем установить контакт:
$ esptool.py chip_id
esptool.py v4.6.2
Found 2 serial ports
Serial port /dev/ttyUSB0
Connecting....
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting....
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: a0:20:a6:12:5f:05
Uploading stub...
Running stub...
Stub running...
Chip ID: 0x00125f05
Hard resetting via RTS pin...
$ esptool.py flash_id
esptool.py v4.6.2
Found 2 serial ports
Serial port /dev/ttyUSB0
Connecting....
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting....
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: a0:20:a6:12:5f:05
Uploading stub...
Running stub...
Stub running...
Manufacturer: e0
Device: 4016
Detected flash size: 4MB
Hard resetting via RTS pin...
Перед вводом команд нужно выполнить процедуру: "а) отключить питание от ESP8266; б) установить перемычку между GPIO_0 и GND; в) включить питание на ESP8266; г) перед вводом команды нажать Reset, подождать одну секунду, и нажать enter для ввода команды". Такую процедуру следует повторять каждый раз при использовании esptool. Для возвращения в нормальный режим работы следует выполнить обратную последовательность: "а) отключить питание от ESP8266; б) убрать перемычку с пинов GPIO_0 и GND; в) включить питание на ESP8266". Если необходимо выполнить несколько команд, то переключаться каждый раз между нормальным и режимом прошивки не нужно. Переключаетесь в режим прошивки, после чего жмёте reset перед каждой командой. Если у вас плата NodeMCU или любая другая плата с возможностью автоматической прошивки, то ничего этого делать не надо, там всё делается автоматически.
Перед тем, как что либо прошивать, скорее всего вам захочется сохранить имеющуюся прошивку. Делается это следующей командой:
$ esptool.py --port /dev/ttyUSB0 --chip esp8266 read_flash 0x00000 0x400000 ./esp8266_firmware.bin
Здесь первое число 0х00000 - это начальный адрес для считывания, второе число 0х400000 - это размер прошивки т.е. 4 мегабайта.
После ввода команды запустится процесс считывания прошивки который займёт примерно минут шесть:
esptool.py v4.6.2 Serial port /dev/ttyUSB0 Connecting.... Chip is ESP8266EX Features: WiFi Crystal is 26MHz MAC: a0:20:a6:12:5f:05 Uploading stub... Running stub... Stub running... 4194304 (100 %) 4194304 (100 %) Read 4194304 bytes at 0x00000000 in 383.1 seconds (87.6 kbit/s)... Hard resetting via RTS pin... .
Теперь мы можем уже что-нибудь прошить. Поначалу, прошивки которые лежат на сайте "Espressif Systems" у меня сыпали логами с ошибками (с последней прошивкой, которая была выложена на сайте Espressif в августе 2018 года (SDK 3.0.0) в самом деле имеются сложности, но об этом позже (сейчас нет никаках проблем, чтобы поставить прошивку на SDK 3.0, но вот прошивка ESP8266-IDF у меня на ESP12E не встала. прим. 2023г)), собирать прошивку самому у меня не было желания, поэтому самым простым способом оказалось взять прошивку на сайте ElectroDragon: "ESP8266 AT-Command firmware - ElectroDragon". Там имеется хорошая вики с инструкций по прошивке.
На сайте ElectroDragon: "ESP8266 AT-Command firmware - ElectroDragon" имеется две прошивки, первая подчёркнута красным, вторая обведена синим:
Примечание из 2023 года: В настоящее время данные прошивки выложены на портале Github.com на аккаунте "Egragon", и доступны по адресу https://github.com/Edragon/esp_firmware/tree/master/Firmware/AT-other/AI-THINKER/At_firmware_bin1.54
Самый простой способ прошивки - это прошивка одним файлом, как прошиваются микроконтроллеры. С ESP8266 тоже можно так работать. Скачаем и распакуем второй файл, который подчёркнут красным (альтернативная ссылка). Там будут два файла: AiThinker_ESP8266_DIO_32M_32M_20160615_V1.5.4.bin, AiThinker_ESP8266_DIO_8M_8M_20160615_V1.5.4.bin и Readme следующего содержания:
****************************************************************** AiThinker_ESP8266_DIO_8M_8M_20160615_V1.5.4.bin MD5: 8E9E9252317A9BCA67673C17B9E3E075 FirmWare Infomation: SPI MODE: DIO Flash Size: 8Mbit File Size: 8Mbit SPI SPEED: 40MHz SDK Version: V1.5.4 Release Date: 2016.6.15 ****************************************************************** AiThinker_ESP8266_DIO_32M_32M_20160615_V1.5.4.bin MD5: B561B49242DC88EA5CBFCAB0CF287BF5 FirmWare Infomation: SPI MODE: DIO Flash Size: 32Mbit File Size: 32Mbit SPI SPEED: 40MHz SDK Version: V1.5.4 Release Date: 2016.6.15 ****************************************************************** How to download: 1. Please select the firmware in ESP_DOWNLOAD_TOOL_V2.4; 2. The address should write 0x00000; 3. If you don't know how to config your download panel, please checked the "DoNotChgBin". That will be download the bin as default setting. More infomation please visit http://www.ai-thinker.com/ If you have any question, please send your mail to support@aithinker.com
Файлы AiThinker_ESP8266_DIO_32M_32M_20160615_V1.5.4.bin, AiThinker_ESP8266_DIO_8M_8M_20160615_V1.5.4.bin это прошивки для плат с флешками на 8Mbit и 32Mbit. В разделе "FirmWare Infomation" указаны режимы флеш-памяти для прошивки. Т.к. на ESP12 установлена флешка на 32Mbit, то нам для прошивки понадобится файл: "AiThinker_ESP8266_DIO_32M_32M_20160615_V1.5.4.bin".
Проверяем контрольную сумму:
$ md5sum AiThinker_ESP8266_DIO_32M_32M_20160615_V1.5.4.bin
b561b49242dc88ea5cbfcab0cf287bf5 AiThinker_ESP8266_DIO_32M_32M_20160615_V1.5.4.bin
Ок. Контрольная сумма совпадает. Тогда прошиваем следующей командой:
$ esptool.py --port /dev/ttyUSB0 --chip esp8266 --baud 115200 write_flash -fm dio -ff 40m -fs 4MB-c1 0x00000 ./AiThinker_ESP8266_DIO_32M_32M_20160615_V1.5.4.bin
Здесь опции: "-fm dio -ff 40m -fs 4MB-c1" задают режим работы флеш-памяти (честно говоря, опции для своего модуля подбирал методом перебора. Примечание 2023г.), которые были указаны в "FirmWare Infomation". Число 0х00000 - это адрес с которого начинается запись. После ввода команды запустится счётчик с процентами выполнения. Процесс прошивки занял около минуты (В 2018 году это занимало минут шесть. Примечание 2023г):
esptool.py v4.6.2 Serial port /dev/ttyUSB0 Connecting.... Chip is ESP8266EX Features: WiFi Crystal is 26MHz MAC: a0:20:a6:12:5f:05 Uploading stub... Running stub... Stub running... Configuring flash size... Flash will be erased from 0x00000000 to 0x003fffff... Flash params set to 0x0260 Compressed 4194304 bytes to 314646... Wrote 4194304 bytes (314646 compressed) at 0x00000000 in 43.4 seconds (effective 773.2 kbit/s)... Hash of data verified. Leaving... Hard resetting via RTS pin...
После завершения прошивки открываем терминал и вводим тестовую команду "AT", если в ответ пришло "OK", значит все в порядке, у нас все получилось.
Далее нам понадобится справочник по AT командам. Они варьируются в зависимости от версии SDK, но мы пока будем использовать только самые базовые. Справочник нужно будет скачать с сайта Espressif по ссылке "ESP8266 AT Instruction Set":
Команды АТ-интерфейса можно сравнить с переменными, функциями или может быть с функторами в обычной программе. Соответственно, у этих функций/команд можно запросить текущие параметры (Query Command), тогда после имени команды используется знак вопроса. Можно назначить свои параметры (Set Command), когда после имени команды используется символ "=". Можно запустить команду на выполнение (Execute Command). Также имеется тест команды (Test Command") когда проверяется, поддерживается ли данная команда данным АТ-интерпретатором. Для теста используется комбинация символов: "=?". Не все команды поддерживают все четыре типа обращения к ним, поэтому некоторые из них выглядят как операторы, другие как переменные, третьи как функторы.
Первым делом нам понадобится информация о версиях имеющегося на борту ПО. Она извлекается с помощью команды: AT+GMR
AT+GMR — Вывод информации о версиях ПО
Execute Command: AT+GMR Отклик: <AT version info>
<SDK version info>
<compile time>
OKПараметры: • <AT version info>: версия AT-интерпретатора.
• <SDK version info>: версия SDK.
• <compile time>: дата компиляции BIN-файла.
Выполняем:
AT+GMR AT version:1.1.0.0(May 11 2016 18:09:56) SDK version:1.5.4(baaeaebb) Ai-Thinker Technology Co. Ltd. Jun 13 2016 11:29:20 OK
На сайте ElectroDragon: "ESP8266 AT-Command firmware - ElectroDragon" прошивки время от времени обновляются, вот отчёт о версиях ПО прошивки которую я брал там летом:
AT+GMR AT version:0.40.0.0(Aug 8 2015 14:45:58) SDK version:1.3.0 Ai-Thinker Technology Co.,Ltd. Build:1.3.0.2 Sep 11 2015 11:48:04 OK
Вот ещё отчёт прошивки которая была зашита к купленных мною модулях:
AT+GMR AT version:1.3.0.0(Jul 14 2016 18:54:01) SDK version:2.0.0(5a875ba) Farylink Technology Co., Ltd. v1.0.0.2 May 11 2017 22:23:58 OK
Я думаю, что если бы это были оригинальные модули Ai-Thinker, то здесь бы не стояло упоминание какой-то непонятной фирмы: "Farylink Technology Co., Ltd."
Теперь для обновления прошивки из "облака" нам понадобиться подключиться к интернет. Для этого нам понадобится следующие команды:
AT+CWMODE_CUR — Установка текущего режима Wi-Fi; Конфигурация НЕ СОХРАНЯЕТСЯ во флеш-памяти
Команды: Test Command:
AT+CWMODE_CUR=?Query Command:
AT+CWMODE_CUR?
Назначение: запрашивает текущий режим работы Wi-Fi ESP8266.Set Command:
AT+CWMODE_CUR=<режим>
Назначение: устанавливает текущий режим работы Wi-Fi ESP8266.Отклик: +CWMODE_CUR:<режим>
OK+CWMODE_CUR:<режим>
OKOK Параметры: <режим>:
‣ 1: Station mode
‣ 2: SoftAP mode
‣ 3: SoftAP+Station modeЗамечания: Конфигурация НЕ СОХРАНЯЕТСЯ во флеш-памяти Примеры: AT+CWMODE_CUR=3
AT+CWMODE_DEF — Установка режима Wi-Fi по умолчанию; Конфигурация сохраняется во флеш-памяти
Команды: Test Command:
AT+CWMODE_DEF=?Query Command:
AT+CWMODE_DEF?
Назначение: запрашивает текущий режим работы Wi-Fi ESP8266.Set Command:
AT+CWMODE_DEF=<режим>
Назначение: устанавливает режим работы Wi-Fi по умолчанию.Отклик: +CWMODE_DEF:<режим>
OK+CWMODE_DEF:<режим>
OKOK Параметры: <режим>:
‣ 1: Station mode
‣ 2: SoftAP mode
‣ 3: SoftAP+Station modeЗамечания: Изменённое значение будет сохранено в области параметров Примеры: AT+CWMODE_DEF=3
Устанавливаем режим клиента (Station):
AT+CWMODE_CUR=1
OK
Поверяем:
AT+CWMODE_CUR?
+CWMODE_CUR:1
OK
Смотрим какой режим работы Wifi установлен по умолчанию:
AT+CWMODE_DEF?
+CWMODE_DEF:2
OK
Теперь нам нужно найти точку доступа. Делается это с помощью команды AT+CWLAP:
AT+CWLAP - вывод списка точек доступа WiFi
Команды: Set Command:
AT+CWLAP[=<ssid>,<mac>,<channel>,<scan_type>, <scan_time_min>,<scan_time_max>]
Действие: выполняет поиск точки
доступа с определённым SSID
и/или MAC-адресом, на определённом канале.Execute Command:
AT+CWLAP
Действие: выводит список всех доступных точек доступа WiFi.Отклик: +CWLAP:<ecn>,<ssid>,<rssi>,<mac>,<channel>,
<freq offset>,<freq cali>,
<pairwise_cipher>,<group_cipher>,<bgn>,<wps>
OK+CWLAP:<ecn>,<ssid>,<rssi>,<mac>,<channel>,
<freq offset>,<freq cali>,
<pairwise_cipher>,<group_cipher>,<bgn>,<wps>
OKПараметры:
- [<scan_type>]: не обязательный параметр ‣ 0: активное сканирование ‣ 1: пассивное сканирование
- [<scan_time_min>] : не обязательный параметр, задаётся в мс, диапазон: [0,1500] ‣ При активном сканировании, <scan_time_min> задаёт минимальное время сканирования каждого канала, по умолчанию равно 0 ‣ При пассивном сканировании, значение параметра <scan_time_min> не имеет значения и оно может быть пропущено.
- [<scan_time_max>] : не обязательный параметр, задаётся в мс, диапазон: [0,1500] ‣ При активном сканировании, <scan_time_max> задаёт максимальное время сканирования для каждого канала; если значение сброшено в ноль, то будет использоваться значение по умолчанию 120 мс. ‣ При пассивном сканировании, <scan_time_max> задаёт время сканирования каждого канала, по умолчанию используется значение в 360 мс
- <ecn>: метод шифрования: ‣ 0: OPEN ‣ 1: WEP ‣ 2: WPA_PSK ‣ 3: WPA2_PSK ‣ 4: WPA_WPA2_PSK ‣ 5: WPA2_Enterprise (AT can NOT connect to WPA2_Enterprise AP for now.)
- <ssid>: строковый параметр, задаёт SSID точки доступа.
- <rssi>: уровень сигнала.
- <mac>: строковый параметр, задаёт MAC адрес точки доступа.
- <channel>: номер канала.
- <freq offset>: frequency offset of AP; unit: KHz. The value of ppm is <freq offset>/2.4.
- <freq calibration>: calibration for frequency offset.
- <pairwise_cipher>: ‣ 0:CIPHER_NONE ‣ 1:CIPHER_WEP40 ‣ 2:CIPHER_WEP104 ‣ 3:CIPHER_TKIP ‣ 4:CIPHER_CCMP ‣ 5:CIPHER_TKIP_CCMP ‣ 6:CIPHER_UNKNOWN
- <group_cipher>:задаёт тип шифра, значения такие же как и для <pairwise_cipher>
- <bgn>: ‣ bit0 управляет 802.11b режимом; bit1 управляет 802.11g режимом; bit2 управляет 802.11n режимом; ‣ Если значение bit установлено в 1, то соответствующий 802.11 режим будет включён; Если бит будет сброшен в ноль, соответствующий 802.11 режим будет отключён.
- <wps>:0 - WPS будет отключено; 1 - WPS будет включено.
Примеры: поиск определённой точки доступа: AT+CWLAP="Wi-Fi","ca:d7:19:d8:a6:44",6
или поиск точки доступа по SSID:
AT+CWLAP="Wi-Fi"
или включение режима пассивного сканирования:
AT+CWLAP=,,,1,,
Сканируем воздух:
AT+CWLAP +CWLAP:(4,"ROSTELECOM_F0DB",-89,"2c:e4:12:3d:f0:dc",1,-24,0) +CWLAP:(4,"TP-LINK_A469B8",-92,"b0:48:7a:a4:69:b8",1,11,0) +CWLAP:(4,"WiFi-DOM.ru-5723",-89,"cc:7b:36:b3:1f:79",1,-9,0) +CWLAP:(4,"Russkikh",-93,"f0:b4:29:d6:8d:f2",1,-4,0) +CWLAP:(4,"WiFi-DOM.ru-1784",-84,"ac:64:62:83:19:08",2,13,0) +CWLAP:(3,"Keenetic-7788",-91,"04:bf:6d:97:08:e4",4,21,0) +CWLAP:(3,"servant",-75,"14:cc:20:33:44:4e",6,11,0) +CWLAP:(4,"WiFi-DOM.ru-5838",-92,"d4:76:ea:20:02:38",6,-19,0) +CWLAP:(4,"ASUS",-90,"00:1a:2b:3c:ff:02",7,6,0) +CWLAP:(4,"elektrik018",-87,"f0:7d:68:95:b8:e2",9,-7,0) +CWLAP:(4,"DOM.RU",-89,"c0:4a:00:4d:3f:7c",10,20,0) +CWLAP:(3,"NETGEAR_146",-76,"c4:3d:c7:8f:44:74",11,-2,0) +CWLAP:(3,"Alien",-22,"00:90:4c:c1:00:00",11,10,0) +CWLAP:(4,"WiFi-DOM.ru-1587",-85,"a0:ec:81:23:5a:b1",11,1,0) +CWLAP:(4,"Brute",-59,"40:f2:01:c1:25:2b",11,10,0) +CWLAP:(4,"WiFi-DOM.ru-8332",-79,"20:89:87:94:d6:ed",11,-12,0) +CWLAP:(3,"MTSRouter-9B1812",-90,"1c:5f:2b:9b:18:12",13,6,0) OK
AT+CWJAP_CUR - подключение к точке доступа, конфигурация НЕ сохраняется во флеш-памяти
Команды: Query Command:
AT+CWJAP_CUR?
Действие: печатает точку доступа к которой в данный момент подключён ESP8266.Set Command:
AT+CWJAP_CUR=<ssid>,<pwd>,[<bssid>][,<pci_en>]
Действие: подключается к указанной точке доступа.Отклик: +CWJAP_CUR:<ssid>,<bssid>,<channel>,<rssi>
OKOK
или
+CWJAP_CUR:<error code>
FAILПараметры: <ssid>: строковый параметр показывающий SSID целевой точки доступа.
- <ssid>: SSID целевой точки доступа.
- <pwd>: пароль, максимум 64 символа ASCII.
- [<bssid>]: опциональный параметр к качестве которого используется MAC-адрес целевой точки доступа. Используется когда несколько точек доступа имеют одинаковый SSID.
- [<pci_en>]: опциональный параметр который отключает подключение по WEP и к открытым точкам доступа. Может использоваться для PCI аутентификация.
- <error code>: (for reference only)
‣ 1: истечение таймаута.
‣ 2: неверный пароль.
‣ 3: не получается найти точку доступа.
‣ 4: ошибка соединения.
Эта команда требует чтобы ESP8266 находился в режиме клиента (Station). Эскейп-последовательности используются, когда SSID или пароль содержат в себе специальные символы, такие как: , или ” или \.Замечания: Изменения конфигурации НЕ сохраняются во флеш-памяти. Примеры: AT+CWJAP_CUR="abc","0123456789"
К примеру, для подключения к точке доступа: "ab\,c" с паролем: "0123456789"\", следует выполнить следующую команду:
AT+CWJAP_CUR="ab\\\,c","0123456789\"\\"
Если несколько точект доступа имеют одинаковый SSID: "abc", то подключиться можно через BSSID:
AT+CWJAP_CUR="abc","0123456789","ca:d7:19:d8:a6:44"
AT+CWJAP_DEF - подключение к точке доступа, конфигурация сохраняется во флеш-памяти
Команды: Query Command:
AT+CWJAP_DEF?
Действие: печатает точку доступа к которой в данный момент подключён ESP8266.Set Command:
AT+CWJAP_DEF=<ssid>,<pwd>,[<bssid>][,<pci_en>]
Действие: подключается к указанной точке доступа.Отклик: +CWJAP_DEF:<ssid>,<bssid>,<channel>,<rssi>
OKOK
или
+CWJAP_DEF:<error code>
FAILПараметры: <ssid>: строковый параметр показывающий SSID целевой точки доступа.
- <ssid>: SSID целевой точки доступа.
- <pwd>: пароль, максимум 64 символа ASCII.
- [<bssid>]: опциональный параметр к качестве которого используется MAC-адрес целевой точки доступа. Используется когда несколько точек доступа имеют одинаковый SSID.
- [<pci_en>]: опциональный параметр который отключает подключение по WEP и к открытым точкам доступа. Может использоваться для PCI аутентификация.
- <error code>: (for reference only)
‣ 1: истечение таймаута.
‣ 2: неверный пароль.
‣ 3: не получается найти точку доступа.
‣ 4: ошибка соединения.
Эта команда требует чтобы ESP8266 находился в режиме клиента (Station). Эскейп-последовательности используются, когда SSID или пароль содержат в себе специальные символы, такие как: , или ” или \.Замечания: Изменения конфигурации сохранются во флеш-памяти. Примеры: AT+CWJAP_DEF="abc","0123456789"
К примеру, для подключения к точке доступа: "ab\,c" с паролем: "0123456789"\", следует выполнить следующую команду:
AT+CWJAP_DEF="ab\\\,c","0123456789\"\\"
Если несколько точек доступа имеют одинаковый SSID: "abc", то подключиться можно через BSSID:
AT+CWJAP_DEF="abc","0123456789","ca:d7:19:d8:a6:44"
Подключаемся к точке доступа:
AT+CWJAP_CUR="Alien","password"
WIFI CONNECTED
WIFI GOT IP
OK
Далее смотрим IP адрес который получил ESP8266:
AT+CIFSR - показать локальный IP адрес
Execute Command: AT+CIFSR Отклик: +CIFSR:APIP,<SoftAP IP address>
+CIFSR:APMAC,<SoftAP MAC address>
+CIFSR:STAIP,<Station IP address>
+CIFSR:STAMAC,<Station MAC address>
OKПараметры: <IP address>:
IP адрес ESP8266 в режиме SoftAP;
IP адрес ESP8266 в режиме клиента (Station)
<MAC address>:
MAC адрес ESP8266 в режиме SoftAP;
MAC адрес ESP8266 в режиме клиента (Station).Замечания: Station IP можно получить только когда ESP8266 находится в режиме клиента и при этом подключён к точке доступа
AT+CIFSR
+CIFSR:STAIP,"192.168.1.125"
+CIFSR:STAMAC,"60:01:94:41:28:0f"
OK
Пробуем достучаться до интернета :
AT+PING - посылка Ping пакета
Set Command: AT+PING=<IP>
Действие: посылка ping пакета.Отклик: +<time>
OK
или
+timeout
ERRORПараметры:
- <IP>: IP хоста или имя домена
- <time>: время отклика на ping
Примеры: AT+PING="192.168.1.1"
AT+PING="www.baidu.com"
AT+PING="ya.ru"
+32
OK
Обновление прошивки из "облака" осуществляется с помощью команды CIUPDATE:
AT+CIUPDATE — Обновление прошивки через Wi-Fi
Execute Command: AT+CIUPDATE
Действие: обновление ПООтклик: +CIPUPDATE:<n>
OKПараметры отклика:
- <n>: ‣ 1: поиск сервера. ‣ 2: подключение к серверу. ‣ 3: запрос версии ПО. ‣ 4: запуск обновления.
Замечания:
- Скорость обновления зависит от скорости интернет-соединения.
- ERROR будет возвращён, если обновление прервётся из-за неудовлетворительного интернет-соединения. Подождите некоторое время, прежде чем повторять попытку.
Замечания:
- При использовании Espressif’s AT BIN (/ESP8266_NONOS_SDK/bin/at), команда AT+CIUPDATE загрузит новый AT BIN из облака Espressif.
- Если используется скомпилированная самостоятельно прошивка AT BIN, то самостоятельно нужно скомпилировать и обновление для AT+CIUPDATE. Espressif предоставляет в SDK пример локального обновления в (/ESP8266_NONOS_SDK/example/at).
- После обновления рекомендуется выполнить AT+RESTORE для восстановления установок по умолчанию.
Обновляем:
AT+CIUPDATE +CIPUPDATE:1 +CIPUPDATE:2 +CIPUPDATE:3 +CIPUPDATE:4 OK
Обновление занимает где-то одну минуту (Примечание из 2023г. В настоящее время обновление не работает. Процесс доходит только до "CIPUPDATE:1", после чего пишет "ERROR"). После обновления выполняем сброс настроек:
AT+RESTORE — Сброс к заводским настройкам
Execute Command: AT+RESTORE Отклик: OK Параметры: Выполнение этой команды сбросит все настройки сохранённые на флешке, что вернёт прошивку к заводским настройкам. После выполнения команды чип будет перезагружен.
В случае, если использовались команды с суффиксом CUR, то для сброса будет достаточно обычного Reset:
AT+RST — Перезагрузка модуля
Execute Command: AT+RST Отклик: OK Параметры: отсутствуют
Выполняем сброс:
Обратите внимание, что вектор старта программы изменился с 0х01000 на 0х81000. Если теперь перешить загрузчик который вернёт вектор старта на 0х01000, то будет запускаться старая прошивка. Т.е. она никуда не делась.
Проверяем версии ПО:
AT+GMR AT version:1.2.0.0(Jul 1 2016 20:04:45) SDK version:1.5.4.1(39cb9a32) Ai-Thinker Technology Co. Ltd. v1.5.4.1-a Nov 30 2017 15:54:51 OK
Обновился AT-интерпретатор с версии "AT version:1.1.0.0(May 11 2016 18:09:56)" до "AT version:1.2.0.0(Jul 1 2016 20:04:45)". Негусто.
На самом деле ESP8266 почти никогда не прошивается одним файлом. Во-первых это долго, во-вторых неудобно. ESP8266 прошивается по регионам. Загрузчик в один регион, SDK в другой, AT-bin в третий. Это быстрее и удобнее, хотя поначалу может сбить с толку. Исключением является создание и восстановление backup прошивки.
Скачаем теперь с сайта "ESP8266 AT-Command firmware - ElectroDragon" (прим 2023г. в настоящее время на сайте Electrotragon нет нужных прошивок, вторая альтернативная ссылка https://github.com/sokil/esp8266/blob/master/AT_V1.1_on_ESP8266_NONOS_SDK_V1.5.4.zip контрольная сумма MD5: "c98ac23570189c31ba81a44adcf69650") прошивку обведённую синим (альтернативная ссылка):После распаковки архива у нас будет следующая структура файлов и каталогов:
$ tree . . └── AT_bin ├── 1024+1024 │ ├── user1.2048.new.5.bin │ └── user2.2048.new.5.bin ├── 512+512 │ ├── user1.1024.new.2.bin │ └── user2.1024.new.2.bin ├── README.md ├── blank.bin ├── boot_v1.5.bin ├── esp_init_data_default.bin └── noboot ├── eagle.flash.bin └── eagle.irom0text.bin 4 directories, 11 files
Подозреваю, что предполётный инструктаж будет находится в файле README.md:
# BOOT MODE ## download ### Flash size 8Mbit: 512KB+512KB boot_v1.2+.bin 0x00000 user1.1024.new.2.bin 0x01000 esp_init_data_default.bin 0xfc000 (optional) blank.bin 0x7e000 & 0xfe000 ### Flash size 16Mbit: 512KB+512KB boot_v1.2+.bin 0x00000 user1.1024.new.2.bin 0x01000 esp_init_data_default.bin 0x1fc000 (optional) blank.bin 0x7e000 & 0x1fe000 ### Flash size 16Mbit-C1: 1024KB+1024KB boot_v1.2+.bin 0x00000 user1.2048.new.5.bin 0x01000 esp_init_data_default.bin 0x1fc000 (optional) blank.bin 0xfe000 & 0x1fe000 ### Flash size 32Mbit: 512KB+512KB boot_v1.2+.bin 0x00000 user1.1024.new.2.bin 0x01000 esp_init_data_default.bin 0x3fc000 (optional) blank.bin 0x7e000 & 0x3fe000 ### Flash size 32Mbit-C1: 1024KB+1024KB boot_v1.2+.bin 0x00000 user1.2048.new.5.bin 0x01000 esp_init_data_default.bin 0x3fc000 (optional) blank.bin 0xfe000 & 0x3fe000 # NON-BOOT MODE ## download eagle.flash.bin 0x00000 eagle.irom0text.bin 0x10000 blank.bin Flash size 8Mbit: 0x7e000 & 0xfe000 Flash size 16Mbit: 0x7e000 & 0x1fe000 Flash size 16Mbit-C1: 0xfe000 & 0x1fe000 Flash size 32Mbit: 0x7e000 & 0x3fe000 Flash size 32Mbit-C1: 0xfe000 & 0x3fe000 esp_init_data_default.bin (optional) Flash size 8Mbit: 0xfc000 Flash size 16Mbit: 0x1fc000 Flash size 16Mbit-C1: 0x1fc000 Flash size 32Mbit: 0x3fc000 Flash size 32Mbit-C1: 0x3fc000 ## compile modify eagle.app.v6.ld, as irom0_0_seg : org = 0x40210000, len = 0x6C000 > NOTICE: UPDATE is not supported in non-boot mode; 4Mbit Flash is not supported in non-boot mode; # Update steps 1.Make sure TE(terminal equipment) is in sta or sta+ap mode AT+CWMODE=3 OK 2.Make sure TE got ip address AT+CWJAP="ssid","12345678" OK AT+CIFSR 192.168.1.134 3.Let's update AT+CIUPDATE +CIPUPDATE:1 found server +CIPUPDATE:2 connect server +CIPUPDATE:3 got edition +CIPUPDATE:4 start start OK > NOTICE: If there are mistakes in the updating, then break update and print ERROR.
Т.к. у нас флешка на 32Mbit, нас будет интересовать фрагмент выделенный красным.
Очищаем флешку:
$ esptool.py -p /dev/ttyUSB0 --chip esp8266 erase_flash
esptool.py v4.6.2
Serial port /dev/ttyUSB0
Connecting....
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: a0:20:a6:12:5f:05
Uploading stub...
Running stub...
Stub running...
Erasing flash (this may take a while)...
Chip erase completed successfully in 11.6s
Hard resetting via RTS pin...
После чего, руководствуясь адресами в выделенном красным фрагменте, составляем следующую команду:
$ esptool.py -p /dev/ttyUSB0 --chip esp8266 write_flash -fm dio -ff 40m -fs 4MB-c1 0x00000 ./AT_bin/boot_v1.5.bin 0x01000 ./AT_bin/512+512/user1.1024.new.2.bin 0x3fc000 ./AT_bin/esp_init_data_default.bin 0x7e000 ./AT_bin/blank.bin 0x3fe000 ./AT_bin/blank.bin
Прошиваем:
$ esptool.py -p /dev/ttyUSB0 --chip esp8266 write_flash -fm dio -ff 40m -fs 4MB-c1 0x00000 ./AT_bin/boot_v1.5.bin 0x01000 ./AT_bin/512+512/user1.1024.new.2.bin 0x3fc000 ./AT_bin/esp_init_data_default.bin 0x7e000 ./AT_bin/blank.bin 0x3fe000 ./AT_bin/blank.bin
esptool.py v4.6.2
Serial port /dev/ttyUSB0
Connecting....
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: a0:20:a6:12:5f:05
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Flash will be erased from 0x00000000 to 0x00000fff...
Flash will be erased from 0x00001000 to 0x00062fff...
Flash will be erased from 0x003fc000 to 0x003fcfff...
Flash will be erased from 0x0007e000 to 0x0007efff...
Flash will be erased from 0x003fe000 to 0x003fefff...
Flash params set to 0x0260
Compressed 3232 bytes to 2336...
Wrote 3232 bytes (2336 compressed) at 0x00000000 in 0.3 seconds (effective 98.8 kbit/s)...
Hash of data verified.
Compressed 399204 bytes to 286943...
Wrote 399204 bytes (286943 compressed) at 0x00001000 in 25.5 seconds (effective 125.3 kbit/s)...
Hash of data verified.
Compressed 128 bytes to 77...
Wrote 128 bytes (77 compressed) at 0x003fc000 in 0.1 seconds (effective 7.2 kbit/s)...
Hash of data verified.
Compressed 4096 bytes to 26...
Wrote 4096 bytes (26 compressed) at 0x0007e000 in 0.1 seconds (effective 384.1 kbit/s)...
Hash of data verified.
Compressed 4096 bytes to 26...
Wrote 4096 bytes (26 compressed) at 0x003fe000 in 0.2 seconds (effective 217.0 kbit/s)...
Hash of data verified.
Leaving...
Hard resetting via RTS pin...
Проверяем:
AT OK AT+GMR AT version:1.1.0.0(May 11 2016 18:09:56) SDK version:1.5.4(baaeaebb) compile time:May 20 2016 15:06:44 OK
Далее, так же как предыдущем случае обновляем прошивку:
AT+CWMODE_CUR=1 OK AT+CWLAP +CWLAP:(4,"WiFi-DOM.ru-5723",-90,"cc:7b:36:b3:1f:79",1,-9,0) +CWLAP:(3,"DIR-48",-91,"28:10:7b:f2:65:ea",1,13,0) +CWLAP:(4,"WiFi-DOM.ru-1784",-87,"ac:64:62:83:19:08",2,21,0) +CWLAP:(3,"Keenetic-4263",-91,"10:7b:ef:5d:17:64",3,3,0) +CWLAP:(3,"Keenetic-7788",-90,"04:bf:6d:97:08:e4",4,20,0) +CWLAP:(3,"servant",-79,"14:cc:20:33:44:4e",6,11,0) +CWLAP:(4,"Super S",-83,"f8:1a:67:50:32:ee",6,10,0) +CWLAP:(4,"WiFi-DOM.ru-5838",-92,"d4:76:ea:20:02:38",6,-17,0) +CWLAP:(4,"WiFi-DOM.ru-8332",-81,"20:89:87:94:d6:ed",11,-12,0) +CWLAP:(4,"Brute",-67,"40:f2:01:c1:25:2b",11,10,0) +CWLAP:(4,"ROSTELECOM_F0DB",-87,"2c:e4:12:3d:f0:dc",11,-24,0) +CWLAP:(3,"Alien",-33,"00:90:4c:c1:00:00",11,10,0) +CWLAP:(3,"Дмитрий",-87,"d4:6e:0e:64:e5:86",12,3,0) OK AT+CWJAP_CUR="Alien","password" WIFI CONNECTED WIFI GOT IP OK AT+CIFSR +CIFSR:STAIP,"192.168.1.125" +CIFSR:STAMAC,"60:01:94:41:28:0f" OK AT+PING="ya.ru" +34 OK AT+CIUPDATE +CIPUPDATE:1 +CIPUPDATE:2 +CIPUPDATE:3 +CIPUPDATE:4 ERROR AT+PING="ya.ru" +33 OK AT+CIUPDATE +CIPUPDATE:1 +CIPUPDATE:2 +CIPUPDATE:3 +CIPUPDATE:3 +CIPUPDATE:4 OK
Примечание из 2023 года. В данный момент обновление пока еще работает, но прошивка после обновления неработоспособна, модуль уходит в жесткий "bootloop":
но может быть вам повезет больше.
По логу видно что в даннном случае не обошлось без ошибки при обновлении. Процедуру пришлось повторять. И несмотря на то, что я использовал команды с суффиксом CUR, после перезагрузки ESP8266 вновь подключается в точке доступа.
Делаем RESTORE, затем смотрим на версии того что прилетело по воздуху:
AT+GMR AT version:1.6.2.0(Apr 13 2018 11:10:59) SDK version:2.2.1(6ab97e9) compile time:Jun 7 2018 19:34:27 Bin version(Wroom 02):1.6.2 OK
Вот это уже лучше, прошивка этого года. Пробуем дать команду из свежего SDK:
AT+SYSRAM — Проверка оставшейся свободной памяти в ОЗУ
Query Command: AT+SYSRAM? Отклик: +SYSRAM:<remaining RAM size>
OKПараметры отклика: <remaining RAM size>: оставшаяся свободная память в байтах.
Выполняем:
AT+SYSRAM?
+SYSRAM:33432
OK
Имеем свободные 32 кбайта ОЗУ. Это уже что-то.
На самом деле, совсем не обязательно так все усложнять, мне просто хотелось показать процесс обновления прошивки "по воздуху". Прошивки с такой возможностью таки и называются: "over the air" или "OTA".
Для загрузки нужной прошивки мы можем зайти на сайт ESP8266EX Resources | Espressif Systems и скачать прошивку нужной версии. В этом случае ничего обновлять уже не придётся.
Как я уже говорил, с прошивкой AT-интерпретатора последней версии 1.7 имеются проблемы, она не поддерживает флешки 32Mbit (Примечание из 2023г: с прошивкой АТ-интерпретатора версии 1.7.5 сейчас проблем никаких нет, в следующей главе это будет продемонстрировано), но мы можем загрузить прошивку версии 1.6. Это та же версия, что мы получили через обновление, но стартовать она будет с адреса 0x01000, а не 0х81000.
Скачиваем прошивку версии 1.6.2 (альтернативная ссылка):
После распаковки архива видим следующую структуру файлов и каталогов:
$ tree . . ├── at │ ├── 1024+1024 │ │ ├── user1.2048.new.5.bin │ │ └── user2.2048.new.5.bin │ ├── 512+512 │ │ ├── user1.1024.new.2.bin │ │ └── user2.1024.new.2.bin │ └── README.md ├── at_sdio │ ├── 1024+1024 │ │ ├── user1.2048.new.5.bin │ │ └── user2.2048.new.5.bin │ ├── 512+512 │ │ ├── user1.1024.new.2.bin │ │ └── user2.1024.new.2.bin │ └── README.md ├── blank.bin ├── boot_v1.2.bin ├── boot_v1.6.bin ├── boot_v1.7.bin ├── esp_init_data_default_v05.bin └── esp_init_data_default_v08.bin 6 directories, 16 files
В README.md имеются следующие указания для нашей флешки:
### Flash size 32Mbit: 512KB+512KB boot_v1.2+.bin 0x00000 user1.1024.new.2.bin 0x01000 esp_init_data_default.bin 0x3fc000 (optional) blank.bin 0x7e000 & 0x3fe000
В соответствии с этими указаниями, составляем команду для прошивки ESP8266:
$ esptool.py -p /dev/ttyUSB0 --chip esp8266 write_flash -fm dio -ff 40m -fs 4MB-c1 0x00000 ./boot_v1.7.bin 0x01000 ./at/512+512/user1.1024.new.2.bin 0x3fc000 ./esp_init_data_default_v05.bin 0x7e000 ./blank.bin 0x3fe000 ./blank.bin
Прошивка занимает примерно секунд сорок. После перезагрузки сразу будет доступен AT-интерпретатор версии 1.6.2.
Перед прошивкой, нелишним будет очистить флешку модуля командой:
$ esptool.py -p /dev/ttyUSB0 --chip esp8266 erase_flash
Прошивка ESP8266 модуля версией AT-интерпретатора 1.7.х в 2018 году была достаточно проблемной вещью, впоследствии компания Espressif исправила баги и сейчас это не представляет сложности. По этой причине, данную главу пришлось полностью переписать. Для тех, кто хочет посмотреть на старую версию, могут заглянуть в старую версию статьи: перейти по ссылке.
Скачать прошивку AT-интерпретатора ESP8266 версии 1.7.5 можно с сайта компании Espressif (альтернативная ссылка):
После распаковки архива имеем следующую структуру файлов:
bin ├── at │ ├── 1024+1024 │ │ ├── user1.2048.new.5.bin │ │ └── user2.2048.new.5.bin │ ├── 512+512 │ │ ├── user1.1024.new.2.bin │ │ └── user2.1024.new.2.bin │ └── README.md ├── at_sdio │ ├── 1024+1024 │ │ ├── user1.2048.new.5.bin │ │ └── user2.2048.new.5.bin │ └── README.md ├── blank.bin ├── boot_v1.7.bin └── esp_init_data_default_v08.bin
В README.md содержится следующая таблица адресов:
### Flash size 8Mbit: 512KB+512KB boot_v1.2+.bin 0x00000 user1.1024.new.2.bin 0x01000 esp_init_data_default.bin 0xfc000 blank.bin 0x7e000 & 0xfe000 ### Flash size 16Mbit-C1: 1024KB+1024KB boot_v1.2+.bin 0x00000 user1.2048.new.5.bin 0x01000 esp_init_data_default.bin 0x1fc000 blank.bin 0xfe000 & 0x1fe000 # NON-BOOT MODE ## download eagle.flash.bin 0x00000 eagle.irom0text.bin 0x10000 blank.bin Flash size 8Mbit: 0x7e000 & 0xfe000 Flash size 16Mbit: 0x7e000 & 0x1fe000 Flash size 16Mbit-C1: 0xfe000 & 0x1fe000 Flash size 32Mbit: 0x7e000 & 0x3fe000 Flash size 32Mbit-C1: 0xfe000 & 0x3fe000 esp_init_data_default.bin Flash size 8Mbit: 0xfc000 Flash size 16Mbit: 0x1fc000 Flash size 16Mbit-C1: 0x1fc000 Flash size 32Mbit: 0x3fc000 Flash size 32Mbit-C1: 0x3fc000
В документации сказано, что для модулей с флешкой 2МБ и выше, следует использовать адреса от "16Mbit-C1". Т.о. для прошивки сначала протираем флешку:
$ esptool.py -p /dev/ttyUSB0 --chip esp8266 erase_flash
После чего прошиваем:
$ esptool.py -p /dev/ttyUSB0 --chip esp8266 write_flash -fm qio -ff 40m -fs 4MB-c1 0x00000 ./boot_v1.7.bin 0x01000 ./at/1024+1024/user1.2048.new.5.bin 0x1fc000 ./esp_init_data_default_v08.bin 0xfe000 ./blank.bin 0x1fe000 ./blank.bin
esptool.py v4.6.2
Serial port /dev/ttyUSB0
Connecting....
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: a0:20:a6:12:5f:05
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Flash will be erased from 0x00000000 to 0x00000fff...
Flash will be erased from 0x00001000 to 0x00065fff...
Flash will be erased from 0x001fc000 to 0x001fcfff...
Flash will be erased from 0x000fe000 to 0x000fefff...
Flash will be erased from 0x001fe000 to 0x001fefff...
Flash params set to 0x0060
Compressed 4080 bytes to 2936...
Wrote 4080 bytes (2936 compressed) at 0x00000000 in 0.3 seconds (effective 102.9 kbit/s)...
Hash of data verified.
Compressed 413556 bytes to 296987...
Wrote 413556 bytes (296987 compressed) at 0x00001000 in 26.4 seconds (effective 125.5 kbit/s)...
Hash of data verified.
Compressed 128 bytes to 75...
Wrote 128 bytes (75 compressed) at 0x001fc000 in 0.1 seconds (effective 20.0 kbit/s)...
Hash of data verified.
Compressed 4096 bytes to 26...
Wrote 4096 bytes (26 compressed) at 0x000fe000 in 0.1 seconds (effective 583.8 kbit/s)...
Hash of data verified.
Compressed 4096 bytes to 26...
Wrote 4096 bytes (26 compressed) at 0x001fe000 in 0.1 seconds (effective 564.9 kbit/s)...
Hash of data verified.
Leaving...
Hard resetting via RTS pin...
При старте получем такой лог:
ts Jan 8 2013,rst cause:2, boot mode:(3,6) load 0x40100000, len 2592, room 16 tail 0 chksum 0xf3 load 0x3ffe8000, len 764, room 8 tail 4 chksum 0x92 load 0x3ffe82fc, len 676, room 4 tail 0 chksum 0x22 csum 0x22 2nd boot version : 1.7(5d6f877) SPI Speed : 40MHz SPI Mode : QIO SPI Flash Size & Map: 32Mbit(1024KB+1024KB) jump to run user1 @ 1000 correct flash map mismatch map 5,spi_size_map 6 system param partition error system_partition_table_regist fail V2 Mo ,�rf cal sector: 507 freq trace enable 0 rf[112] : 00 rf[113] : 00 rf[114] : 01 SDK ver: 3.0.5(b29dcd3) compiled @ Oct 9 2021 09:52:05 phy ver: 1156_0, pp ver: 10.2
Проверяем работу интерпретатора:
AT OK AT+GMR AT version:1.7.5.0(Oct 9 2021 09:26:04) SDK version:3.0.5(b29dcd3) compile time:Oct 15 2021 18:05:38 Bin version(Wroom 02):1.7.5 OK AT+SYSRAM? +SYSRAM:52040 OK
Вроде все ОК. Пробуем подключиться к сети и обновить прошивку:
Обновление произошло, но поменялась лишь дата компиляции прошивки.
На сайте Espressif можно найти также прошивку "ESP8266 IDF AT Bin", но насколько я понял, она только для фирменных модулей WROOM. На ESP12E ее завести не удалось, сколько бы опций я не перебирал, дальше загрузчика прошивка не стартует.
В последние лет десять проект MicroPython обрел настоящую популярность. Его прошивки ставят на всевозможные платы: ESP8266/ESP32/RP2040/Blackpill и т.д. одним словом на все, что обладает достаточной флеш-памятью. К слову говоря, ESP8266 был один из первых сторонних модулей, получивший официальную поддержку MicroPython. Сейчас MicroPython становится некой альтернативой Arduino (да, я знаю, что MicroPython объявили частью подсистемы Arduino), т.к. язык программирования Python в настоящее время намного популярнее, чем C/C++ используемый в Arduino IDE.
MicroPython ставится на ESP8266 модули с объемом флеш-памяти от одного мегабайта. Для модулей ESP-01 с флешкой на 512 KБайт существует специальные, урезанные сборки MicroPython, которые я рассматривать не буду, из-за отсутствия у меня таковых.
Прошивка MicroPython ставится по первому способу, т.е. одним файлом. Руководство по установке прошивки можно найти на официальном сайте MicroPython: "Getting started with MicroPython on the ESP8266"
Первым делом следует скачать прошивку с официальной страницы MicroPython: "MicroPython - Python for microcontrollers"
Прошивка может быть "релизной(протестированной и стабильной)" или "Nightly build (горячие пирожки)". На настоящее время стабильный релиз имеет версию v1.20.0 от 26 Апреля 2023г. (годовщина аварии на ЧАЭС). Скачать ее можно по следующей ссылке: "https://micropython.org/resources/firmware/ESP8266_GENERIC-20230426-v1.20.0.bin" (альтернативная ссылка)
В инструкциях по прошивке дают следующую команду:
$ esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=detect 0 имя_файла_прошивки.bin
Но сперва нужно очистить флешку:
$ esptool.py -p /dev/ttyUSB0 --chip esp8266 erase_flash
После чего прошиваем:
$ esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=detect 0 ./ESP8266_GENERIC-20230426-v1.20.0.bin
esptool.py v4.6.2
Serial port /dev/ttyUSB0
Connecting....
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting....
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: a0:20:a6:12:5f:05
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
Configuring flash size...
Auto-detected Flash size: 4MB
Flash will be erased from 0x00000000 to 0x0009afff...
Flash params set to 0x0040
Compressed 634016 bytes to 420365...
Wrote 634016 bytes (420365 compressed) at 0x00000000 in 9.6 seconds (effective 530.0 kbit/s)...
Hash of data verified.
Leaving...
Hard resetting via RTS pin...
В терминальной программе после нажатия "RST" на плате ESP8266 можно будет увидеть следующий лог:
В настройках терминальной программы следует выставить скорость 115200 и окончание строки "CR & NL".
Если выставить скорость 74880 и вновь перезагрузить модуль, можно будет увидеть лог загрузчика:
Переключимся вновь на скорость 115200 и введем команду "help()". В ответ получим следующую картинку:
Теперь в REPL-режиме введем две строки:
import esp esp.check_fw()
В результате чего получим:
Если в ответ получаем как на скриншоте "True", то прошивка прошла успешно.
REPL обладает эхо-эффектом, т.е. он пропечатывает команды, которые вы вводите. Если ввести какую-нибудь ерунду, то REPL выдаст ошибку:
>>> ? Traceback (most recent call last): File "", line 1 SyntaxError: invalid syntax >>>
Как и многие, я пользуюсь питоном, как подручным калькулятором. Давайте посмотрим, сможем ли мы так использовать MicroPython:
print (hex(20+70))
Как видите, это работает.
Давайте попробуем сделать что-то более интересное. Помигать светодиодом например. На сайте MicroPython есть примеры работы с GPIO: "Quick reference for the ESP8266 — MicroPython latest documentation: Pins and GPIO"
Вводим две команды:
from machine import Pin p0 = Pin(2, Pin.OUT)
После этого светодиод на модуле ESP12 должен загореться. Выключить его можно будет командой: "p0.on()", снова включить командой: "p0.off()" (нет, я ничего не путаю).
Теперь давайте подключимся к сети. Для этого последовательно вводим команды:
import network wlan = network.WLAN(network.STA_IF) wlan.active(True) wlan.scan()
В ответ должны получить список точек доступа следующего вида:
Для подключения к точке доступа вводим команды:
wlan.isconnected() wlan.connect('Ваша_точка_доступа', 'пароль') wlan.isconnected()
В первом случае "wlan.isconnected()" должна выдать "False", а во втором случае "True":
При вводе команды "wlan.ifconfig()" можно получить параметры соединения:
wlan.ifconfig() ('192.168.1.4', '255.255.255.0', '192.168.1.1', '192.168.1.1') >>>
Таким образом, MicroPython это неплохая, на мой взгляд, альтернатива для AT-интерпретатора, Arduino и даже программированию на SDK, потому-что во всех случаях вы будете опираться на закрытые функции SDK, а их производительность будет одинакова, что в Arduino, что в MicroPython, что еще где. Вопрос лишь в удобстве пользования.
Все наверное слышали по "умные розетки" Sonoff (продаются в магазинах), это пожалуй самый известный коммерческий проект на модулях ESP8266. С помощью данной прошивки вы сможете по телефону включать или выключать свет, или придумать какое-то свое уникальное применение.
Для установки прошивки потребуется лишь браузер и интернет. Т.е. прошивать будем через браузер. Потребуется Chrome или Edge, потому что когда я пытался прошить с Firefox, мне выдало ошибку, что данный браузер не поддерживает технологию "Web-Serial" (дословно: Your browser does not support Web Serial. Open this page in Google Chrome or Microsoft Edge instead, but not on your mobile device).
Для прошивки я использовал плату NodeMCU v3 с модулем ESP12-E, т.к. там работает автоматическая прошивка по USB. При необходимости, прошивку можно будет "скрутить" c помощью esptool и поставить на голый модуль.
Итак подключаем плату к компьютеру и в браузере заходим по адресу "https://tasmota.github.io/install/"
В списке устройств выбираем ESP8266. Для выбора доступны также ESP32, ESP32-S2, ESP32-S3 и ESP32-C3.
После этого щелкаем по кнопке "коннект" и выбираем последовательный порт со своей платой:
Я прошивал из Linux, но почему-то я уверен, что в Windows это будет работать аналогично. Щелкаем по кнопке "Install бла-бла-бла":
Соглашаемся, что перед прошивкой следует очистить флешку устройства:
После очистки еще раз щелкаем по "INSTALL":
После этого наконец-то начинается установка прошивки, и в браузере появляется бегунок с прогресс-баром.
По завершении установки, вам выдадут скучное сообщение:
Если установка прошивки Sonoff пройдет успешно, то у вас появится такая страничка, где нужно будет выбрать свою точку доступа и указать пароль к ней, дабы вы потом могли соединиться с модулем:
В случае успешного соединения модуля с вашей сетью, будет предложено зайти в веб-интерфейс вашей свежеустановленной прошивки Sonoff:
Главный экран веб-интерфейса выглядит как-то так:
Если щелкнуть по меню "Information", то вам распечатают много букв:
Ну и главный экран с конфигурацией модуля, где вы на любой пин можете повесить ту или иную функцию:
В дальнейшем, вы можете управлять устройством через мобильный телефон или планшет из браузера. Допустим, нам хочется помигать светодиодом. На модуле ESP12 имеется светодиод на GPIO2, давайте сделаем из него "умный" светодиод. Для этого заходим в конфигурацию WiFi модуля:
Там выбираем GPIO_2 и назначаем для него нагрузку "LED":
После сохранения настройки нажатием на зеленую кнопку "Save" модуль перезагрузится. После чего можно будет включать или выключать светодиод нажатем на кнопку "Toggle". Надписями "ON"/"OFF" будет отображаться состояние "умного" выключателя.
С таким же успехом можно использовать другие доступные GPIO. О том, как подключить нагрузку на пин микроконтроллера, можно почитать здесь:
Управление мощной нагрузкой переменного токаЕсли у вас нет устройства с OpenWRT на борту, то все описанное ниже можно будет выполнить в виртуальной машине. Для этого достаточно будет скачать образ OpenWRT под архитектуру x86, и пробрость в виртуалку сеть. Примечание 2023г.
У меня имеется точка доступа с установленной OpenWRT. Это позволяет мне полностью контролировать трафик идущий с ESP8266. OpenWRT, кстати, в наши времена можно установить почти на любую "кофеварку". Народ изгаляется и ставит OpenWRT на всякое барахло: Руководство по доведению «до кондиции» клона популярного китайского мини-роутера Hame A15, он же «unbranded A5-V11», я же пользуюсь классикой - DIR-320 rev.A2. DIR-320 имеет репутацию "неубиваемого роутера". Даже после прошивки его в OpenWRT, все-равно можно вызвать родной загрузчик для восстановления прошивки. Это часто выручало меня на первых порах, когда в результате неудачной настройки, до OpenWRT становилось невозможно достучаться из сети.
Установка OpenWRT на роутер позволяет, по сути, превратить его в одноплатный компьютер. У меня установлена версия "Attitude Adjustment 12.09", в качестве корневого раздела используется флешка на 4 GB. Это позволяет устанавливать приложения без оглядки на занимаемое ими пространство, кроме того, на роутере можно размещать простенькие сайты, для которых не планируется высокая загруженность. OpenWRT может работать в паре с ESP8266, беря на работу по парсингу страниц, работу с защищенными соединениями и разграничении подсетей.
Итак, сбрасываем ESP8266 командой: "AT+RESTORE", на OpenWRT запускаем tcpdump командой: "tcpdump -i wlan0 -n", после чего ESP8266 подключаем точке доступа с OpenWRT:
AT+CWMODE_CUR=1 OK AT+CWJAP="Alien","password" WIFI CONNECTED WIFI GOT IP OK
Syslog в OpenWRT выводится по команде: "logread", и в данном случае, при подключении ESP8266 можно будет увидеть следующую картинку:
Nov 10 08:30:20 OpenWrt daemon.info hostapd: wlan0: STA 60:01:94:41:28:0f IEEE 802.11: authenticated Nov 10 08:30:20 OpenWrt daemon.info hostapd: wlan0: STA 60:01:94:41:28:0f IEEE 802.11: associated (aid 1) Nov 10 08:30:20 OpenWrt daemon.info hostapd: wlan0: STA 60:01:94:41:28:0f WPA: pairwise key handshake completed (RSN) Nov 10 08:30:20 OpenWrt daemon.info dnsmasq-dhcp[2108]: DHCPDISCOVER(br-lan) 60:01:94:41:28:0f Nov 10 08:30:20 OpenWrt daemon.info dnsmasq-dhcp[2108]: DHCPOFFER(br-lan) 192.168.1.11 60:01:94:41:28:0f Nov 10 08:30:20 OpenWrt daemon.info dnsmasq-dhcp[2108]: DHCPREQUEST(br-lan) 192.168.1.11 60:01:94:41:28:0f Nov 10 08:30:20 OpenWrt daemon.info dnsmasq-dhcp[2108]: DHCPACK(br-lan) 192.168.1.11 60:01:94:41:28:0f ESP12_A
Здесь, сначала через демон hostapd устанавливается беспроводное соединение. MAC адрес "60:01:94:41:28:0f" в данном случае - это мой ESP8266. После чего, DHCP в соответствии с моей настройкой, выдает клиенту с данным MAC адресом локальный IP "192.168.1.11" и обозначает его хост как "ESP12_A". За этот процесс отвечает следующее правило в /etc/config/dhcp:
config host option name 'ESP12_A' option mac '60:01:94:41:28:0f' option ip '192.168.1.11'
Замечу, что для поддержки WiFi у меня в OpenWRT установлен пакет wpad-mini, который обеспечивает минимальный функционал и не занимает много места.
tcpdump при этом выдаёт нам следующий лог:
08:30:20.171350 60:01:94:41:28:0f > ff:ff:ff:ff:ff:ff Null Unnumbered, xid, Flags [Response], length 6: 01 00 08:30:20.183276 EAPOL key (3) v2, len 95 08:30:20.188693 EAPOL key (3) v1, len 117 08:30:20.194392 EAPOL key (3) v2, len 151 08:30:20.200214 EAPOL key (3) v1, len 95 08:30:20.257746 IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from 60:01:94:41:28:0f, length 308 08:30:20.258239 IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from 60:01:94:41:28:0f, length 308 08:30:20.261535 IP 192.168.1.10.67 > 192.168.1.11.68: BOOTP/DHCP, Reply, length 300 08:30:20.273383 IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from 60:01:94:41:28:0f, length 308 08:30:20.273797 IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from 60:01:94:41:28:0f, length 308 08:30:20.280894 IP 192.168.1.10.67 > 192.168.1.11.68: BOOTP/DHCP, Reply, length 300 08:30:20.286433 ARP, Request who-has 192.168.1.11 tell 0.0.0.0, length 28 08:30:20.286763 ARP, Request who-has 192.168.1.11 tell 0.0.0.0, length 28 08:30:20.473236 ARP, Request who-has 192.168.1.11 tell 0.0.0.0, length 28 08:30:20.473464 ARP, Request who-has 192.168.1.11 tell 0.0.0.0, length 28 08:30:20.973475 ARP, Request who-has 192.168.1.11 tell 192.168.1.11, length 28 08:30:20.973769 ARP, Request who-has 192.168.1.11 tell 192.168.1.11, length 28
Пока клиент не авторизируется, то он может общатся только на протоколе EAPOL, через который в данном случае происходит авторизация. После авторизации идет получение параметров сети через BOOTP-протокол.
С помощью tcpdump можно записать сессию в отдельный файл, что бы потом его можно было внимательно исследовать в программе-анализаторе трафика Wireshark. Выполняем в OpenWRT команду:
# tcpdump -i wlan0 -n -w alien.cap
После завершения сессии, копируем файл alien.cap на локальную машину:
$ scp root@alien:/root/alien.cap ./
Затем открываем файл alien.cap в Wireshark.
Wireshark это ещё один "швейцарский нож" который умеет декодировать множество сетевых протоколов. Для примера, посмотрим на запрос к DHCP и увидим в теле сообщения запрашиваемые параметры:
В ответе DHCP сервера видим какие параметры ему предложили для работы в сети:
Ок, идём дальше. Посмотрим какие DNS использует ESP8266:
AT+CIPDNS_CUR — Задание пользовательских DNS серверов, настройки НЕ сохраняются во флеш-памяти
Команды: Query Command:
AT+CIPDNS_CUR?
Действие: показать текущие DNS сервераSet Command:
AT+CIPDNS_CUR=<enable>[,<DNS server0>,<DNS server1>]
Действие: задать пользовательские DNS сервераОтклик: [+CIPDNS_CUR:<DNS server0>]
[+CIPDNS_CUR:<DNS server1>]
OKOK Параметры:
- <enable>: ‣ 0: отключает заданные пользователем DNS сервера; ‣ 1: включает заданные пользователем DNS сервера.
- <DNS server0>: необязательный параметр, задание первого DNS сервера;
- <DNS server1>: необязательный параметр, задание второго DNS сервера.
Примеры AT+CIPDNS_CUR=1,"208.67.220.220" Замечания:
- При команде: AT+CIPDNS_CUR=0 (отключает заданные пользователем DNS сервера), будет использован DNS сервер по умолчанию: "208.67.222.222". Так же DNS сервер может быть задан роутером при конфигурации через DHCP.
- При команде: AT+CIPDNS_CUR=1 (включает заданные пользователем DNS сервера, но параметр <DNS server> не задан), будет использоваться сервер: "208.67.222.222" как DNS сервер по умолчанию.
AT+CIPDNS_DEF — Задание пользовательских DNS серверов, настройки сохраняются во флеш-памяти
Команды: Query Command:
AT+CIPDNS_DEF?
Действие: показать текущие DNS сервераSet Command:
AT+CIPDNS_DEF=<enable>[,<DNS server0>,<DNS server1>]
Действие: задать пользовательские DNS сервераОтклик: [+CIPDNS_DEF: ]
[+CIPDNS_DEF:<DNS server1>]
OKOK Параметры:
- <enable>: ‣ 0: отключает заданные пользователем DNS сервера; ‣ 1: включает заданные пользователем DNS сервера.
- <DNS server0>: необязательный параметр, задание первого DNS сервера;
- <DNS server1>: необязательный параметр, задание второго DNS сервера.
Примеры AT+CIPDNS_DEF=1,"208.67.220.220" Замечания:
- Конфигурация будет сохранена во флеш-памяти.
- При команде: AT+CIPDNS_CUR=0 (отключает заданные пользователем DNS сервера), будет использован DNS сервер по умолчанию: "208.67.222.222". Так же DNS сервер может быть задан роутером при конфигурации через DHCP.
- При команде: AT+CIPDNS_CUR=1 (включает заданные пользователем DNS сервера, но параметр <DNS server> не задан), будет использоваться сервер: "208.67.222.222" как DNS сервер по умолчанию.
Смотрим какие DNS используются по умолчанию:
AT+CIPDNS_CUR? +CIPDNS_CUR:192.168.1.10 +CIPDNS_CUR:208.67.222.222 OK
Первый сервер - это шлюз, второй - это сервер проекта OpenDNS.
Задаем DNS яндекса:
AT+CIPDNS_CUR=1,"77.88.8.8","77.88.8.1" OK AT+CIPDNS_CUR? +CIPDNS_CUR:77.88.8.8 +CIPDNS_CUR:77.88.8.1 OK
Проверяем:
AT+PING="ya.ru" +35 OK
В tcpdump при этом появляются следующие строки:
07:34:35.982725 IP 192.168.1.11.4096 > 77.88.8.8.53: 43482+ A? ya.ru. (23) 07:34:36.014821 IP 77.88.8.8.53 > 192.168.1.11.4096: 43482 1/0/0 A 87.250.250.242 (39) 07:34:36.018460 IP 192.168.1.11 > 87.250.250.242: ICMP echo request, id 44975, seq 1, length 40 07:34:36.050192 IP 87.250.250.242 > 192.168.1.11: ICMP echo reply, id 44975, seq 1, length 40
Здесь, в первой строке идёт запрос к нашему DNS-серверу, чтобы тот предоставил IP адрес сервера "ya.ru". Во второй строке DNS сервер возвращает IP адрес: "87.250.250.242" . В третей строке идет сам ICMP запрос, а в четвёртой - ответ. Всё работает.
Одним из наиболее очевидным способов применения ESP8266 в электронике, на мой взгляд, является синхронизация RTC по сетевому протоколу NTP. Даже если вы используете RTC повышенной точности, например: DS3231, это не избавляет вас от нудной процедуры подводки часов, которая зачастую упирается в удобство интерфейса. Не во всех устройствах рационально прикручивать кейпад, для коррекции даты и времени.
Для работы с NTP серверами имеются следующие AT-команды:
AT+CIPSNTPCFG — настройка SNTP
Команды: Query Command:
AT+CIPSNTPCFG?Set Command:
AT+CIPSNTPCFG=<enable>[,<timezone>][,<SNTP server0>,<SNTP server1>,<SNTP server2>]Отклик: +CIPSNTPCFG:<enable>,<timezone>,<SNTP server1>[,<SNTP server2>,<SNTP server3>]
OKOK Параметры:
- <enable>: ‣ 0: SNTP отключён; ‣ 1: SNTP включён.
- <timezone>: часовой пояс; допустимые значения: [-11,13]; Если SNTP отключено, то <timezone> не используется
- <SNTP server0>: необязательный параметр, задаёт первый SNTP сервер;
- <SNTP server1>: необязательный параметр, задаёт второй SNTP сервер;
- <SNTP server2>: необязательный параметр, задаёт третий SNTP сервер.
Примеры AT+CIPSNTPCFG=1,8,"cn.ntp.org.cn","ntp.sjtu.edu.cn","us.pool.ntp.org" Замечания: Если параметры <SNTP server> не заданы, то по умолчанию будут использоваться следующие сервера: будут использоваться по: "cn.ntp.org.cn","ntp.sjtu.edu.cn", и "us.pool.ntp.org".
AT+CIPSNTPTIME — получение текущей даты и времени по SNTP
Query Command: AT+CIPSNTPTIME? Отклик: +CIPSNTPTIME:<time>
OKПараметры отклика: <time>: SNTP time
Например:
+CIPSNTPTIME: Thu Aug 04 14:48:05 2016
OKПримеры использования: AT+CWMODE=1 //установить WiFi режим клиента AT+CWJAP="DemoAP","password" //подключиться к роутеру AT+CIPSNTPCFG=1,8 //задать часовой пояс AT+CIPSNTPTIME? //получить текущее время
OpenWRT может выступать в качестве SNTP сервера поэтому я указываю его адрес в качестве сервера, после чего запрашиваю текущее время:
OK AT+CIPSNTPCFG=1,4,"192.168.1.10" OK AT+CIPSNTPTIME? +CIPSNTPTIME:Sun Nov 11 21:59:56 2018 OK
В tcpdump при этом появляются следующие строки:
21:59:09.411350 IP 192.168.1.11.4097 > 192.168.1.10.123: NTPv4, Client, length 48 21:59:09.434194 IP 192.168.1.10.123 > 192.168.1.11.4097: NTPv4, Server, length 48
Здесь первая срока - это запрос к серверу, а вторая - ответ сервера.
Теперь рассмотрим вопрос организации связи ESP8266 с точкой доступа на OpenWRT. Допустим, программа или скрипт на OpenWRT ищет какую-либо информацию в интернет, и через ESP8266 её нужно вывести на дисплей. В составе OpenWRT имеется Web сервер uhttpd на котором крутится веб интерфейс LUCI, его и будем использовать. Север настраивается через конфиг /etc/config/uhttpd. LUCI мы трогать не будем, вместо этого создадим конфиг для нового сайта. Для этого, в конфиг: /etc/config/uhttpd добавим следующий раздел:
config uhttpd 'site' list listen_http '0.0.0.0:8010' list listen_http '[::]:8010' option home '/site' option rfc1918_filter '1' option max_requests '3' option max_connections '25' option cgi_prefix '/cgi-bin' option script_timeout '60' option network_timeout '30' option http_keepalive '20' option tcp_keepalive '1' option ubus_prefix '/ubus
Как не трудно догадаться, директорией для сайта будет папка: "/site", директорией CGI будет папка: "/site/cgi-bin", а рабочим портом: "8010". Структура папки "site" пусть пока будет такой:
$ tree site site ├── cgi-bin ├── index.html └── pub └── weather.txt 2 directories, 2 files
Где index.html - обычная "заглушка":
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> </head> <body style="background-color: white"> <h3>Hello World!</h3> </body> </html>
После редактирования конфига и добавления директории "/site", перезапускаем web-сервер:
# /etc/init.d/uhttpd restart
Проверяем:
# netstat -l
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:8010 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:www 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:domain 0.0.0.0:* LISTEN
tcp 0 0 OpenWrt.lan:ssh 0.0.0.0:* LISTEN
netstat: /proc/net/tcp6: No such file or directory
udp 0 0 0.0.0.0:domain 0.0.0.0:*
udp 0 0 0.0.0.0:bootps 0.0.0.0:*
udp 0 0 0.0.0.0:ntp 0.0.0.0:*
netstat: /proc/net/udp6: No such file or directory
netstat: /proc/net/raw6: No such file or directory
Active UNIX domain sockets (only servers)
Proto RefCnt Flags Type State I-Node Path
unix 2 [ ACC ] STREAM LISTENING 650 /var/run/ubus.sock
Видим, что открыт наш порт 8010. Теперь с локальной машины пробуем с помощью curl подать на Web-сервер GET-запрос:
$ curl alien:8010
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<body style="background-color: white">
<h3>Hello World!</h3>
</body>
</html>
В ответ мы получили свою html страницу, и значит, здесь все ОК. Ради любопытства посмотрим, что нам скажет nmap:
$ nmap -sV alien
Starting Nmap 7.12 ( https://nmap.org ) at 2018-11-12 13:10 +04
Nmap scan report for alien (192.168.1.10)
Host is up (0.00067s latency).
Not shown: 996 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh Dropbear sshd 2011.54 (protocol 2.0)
53/tcp open domain dnsmasq 2.62
80/tcp open http LuCI Lua http config
8010/tcp open http BusyBox http 1.19.4
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 46.36 seconds
Здесь на 80-м порту висит LUCI, а на 8010 наш сайт. Теперь можно подключиться к нему через ESP8266. Но для этого нам нужно будет ознакомится с набором AT-команд для установления TCP/UDP соединения.
Прежде всего хочу коснуться терминологии. В ESP8266 имеется два режима TCP/UDP соединения: обычный нормальный режим, и режим "UART-Wi-Fi passthrough", который также называется прозрачным (transparent mode). Режим "UART-Wi-Fi passthrough" это мостовое соединение вида: "UART over WIFI", этакий UART по воздуху. Фактически это выглядит как чат на две персоны. Включается он командой: "AT+CIPMODE=1", а выключается последовательностью: "+++". Сейчас мы режима "UART-Wi-Fi passthrough" касаться не будем, но он часто упоминается в описании команд, поэтому я предварительно решил рассказать о нем.
AT+CIPMUX — включение или отключение режима нескольких подключений
Команды: Query Command:
AT+CIPMUX?Set Command:
AT+CIPMUX=<mode>
Действие: установить тип соединенияОтклик: +CIPMUX:<mode>
OKOK Параметры: <mode>:
‣ 0: режим одиночного подключения
‣ 1: режим нескольких подключенийЗамечения:
- По умолчанию используется режим одиночного соединения
- Режим нескольких подключений может быть включен только тогда, когда отключен прозрачный режим (AT+CIPMODE=0).
- Этот режим может быть изменен только после отключения отключения всех активных соединений.
- Если включен TCP сервер, то его следует отключить (AT+CIPSERVER=0) перед тем, как устанавливать режим одиночного соединения.
Пример: AT+CIPMUX=1
AT+CIPMODE — установить режим соединения
Команды: Query Command:
AT+CIPMODE?
Действие: возвращает текущий режим соединения.Set Command:
AT+CIPMODE=<mode>
Действие: устанавливает режим соединения.Отклик: +CIPMODE:<mode>
OKOK Параметры: <mode>:
‣ 0: нормальный режим соединения.
‣ 1: UART-Wi-Fi passthrough mode (прозрачный режим соединения), может быть установлен при использовании режима одиночного соединения или в UDP режиме, когда удалённые IP-адрес и порт не могут быть изменены.Замечения:
- Конфигурация не сохраняется во флеш-памяти.
- Если в при режиме "UART-Wi-Fi passthrough" рвётся связь, то ESP8266 пытается восстановить ее переподключением, до тех пор пока, не получит символы +++ которые означают завершение режима "UART-Wi-Fi passthrough" и возврат к нормальному режиму. При дисконнекте в нормальном режиме, ESP8266 не будет пытаться переподключиться заново.
Пример: AT+CIPMODE=1
AT+CIPSTART — установка TCP соединения, UDP передачи или SSL соединения
Установка TCP соединения
Set Command: Одиночное соединение (когда +CIPMUX=0):
AT+CIPSTART=<type>,<remote IP>,<remote port>[,<TCP keep alive>]Множественное соединение: (когда +CIPMUX=1):
AT+CIPSTART=<link ID>,<type>,<remote IP>,<remote port>[,<TCP keep alive>]Отклик: OK
или
ERROR
Если соединение уже было установлено, то вернет: ALREADY CONNECTEDПараметры:
- <link ID>: ID соединения: от 0 до 4. Применимо только для множественного режима соединения.
- <type>: строковый параметр указывающий тип соединения: "TCP", "UDP" или "SSL".
- <remote IP>: строковый параметр содержащий удалённый IP адрес.
- <remote port>: удаленный порт.
- [<TCP keep alive>]: определение времени удержания TCP соединения: "keep-alive"; по умолчанию выключено.
‣ 0: отключение TCP keep-alive.
‣ 1 ~7200: определение интервала в секундах.Примеры: AT+CIPSTART="TCP","iot.espressif.cn",8000
AT+CIPSTART="TCP","192.168.101.110",1000
Для большей информации смотрите документ: ESP8266 AT Command ExamplesУстановка UDP соединения
Set Command: Одиночное соединение (когда +CIPMUX=0):
AT+CIPSTART=<type>,<remote IP>,<remote port>[,(<UDP local port>),(<UDP mode>)]Множественное соединение: (когда +CIPMUX=1):
AT+CIPSTART=<link ID>,<type>,<remote IP>,<remote port>[,(<UDP local port>),(<UDP mode>)]Отклик: OK
или
ERROR
Если соединение уже было установлено, то вернет: ALREADY CONNECTEDПараметры:
- <link ID>: ID соединения: от 0 до 4. Применимо только для множественного режима соединения.
- <type>: строковый параметр указывающий тип соединения: "TCP", "UDP" или "SSL".
- <remote IP>: строковый параметр содержащий удалённый IP адрес.
- <remote port>: удаленный порт.
- [<UDP local port>]: необязательный параметр, указывает UDP порт ESP8266.
- [<UDP mode>]: необязательный параметр, для прозрачной UDP передачи должен быть сброшен в ноль. ‣ 0: целевой объект UDP передачи не может быть изменен; это значение используется по умолчанию. ‣ 1: целевой объект UDP передачи может быть изменен один раз. ‣ 2: целевой объект UDP передачи возможно менять.
Замечание: <UDP local port> должен быть задан перед <UDP mode>.Примеры: AT+CIPSTART="UDP","192.168.101.110",1000,1002,2
Для большей информации смотрите документ: ESP8266 AT Command ExamplesУстановка SSL соединения
Set Command: AT+CIPSTART=[<link ID>,]<type>,<remote IP>,<remote port>[,<TCP keep alive>] Отклик: OK
или
ERROR
Если соединение уже было установлено, то вернет: ALREADY CONNECTEDПараметры:
- <link ID>: ID соединения: от 0 до 4. Применимо только для множественного режима соединения.
- <type>: строковый параметр указывающий тип соединения: "TCP", "UDP" или "SSL".
- <remote IP>: строковый параметр содержащий удалённый IP адрес.
- <remote port>: удаленный порт.
- [<TCP keep alive>]: определение времени удержания TCP соединения: "keep-alive"; по умолчанию выключено.
‣ 0: отключение TCP keep-alive.
‣ 1 ~7200: определение интервала в секундах.Замечания:
- ESP8266 может устанавливать только одно SSL соединение.
- SSL не поддерживает режим прозрачного соединения (UART-Wi-Fi passthrough mode).
- SSL соединению необходим большой объем памяти, иначе это может привести к перезагрузке ESP8266. Память для SSL соединения можно выделить командой AT+CIPSSLSIZE=<size>, где size - размер буфера.
Примеры: AT+CIPSTART="SSL","iot.espressif.cn",8443
AT+CIPSEND — отправка данных
Команды: Set Command:
- Одиночное соединение: (при +CIPMUX=0)
AT+CIPSEND=<length>- Множественные соединения:(при +CIPMUX=1)
AT+CIPSEND=<link ID>,<length>- При UDP сессии может быть указан удаленный IP-адрес и порт:
AT+CIPSEND=[<link ID>,]<length> [,<remote IP>,<remote port>]
Действие: задание длины данных в нормальном режиме передачи (не "UART-WIFI passthrough mode").Execute Command: AT+CIPSEND
Действие: объявлет начало передачи данных в прозрачном режиме.Отклик: Отправка данных определенной длины. Возвращает значок > после передачи "Set Command". Значок означает, что можно начать передавать данные. Когда длина данных достигнет размера заданного в параметре <length>, данные начнут передаваться. Если соединение не удастся установить или оно будет прервано, то будет возвращенно:
ERROR
Если данные были переданны успешно, то будет возвращенно:
SEND OK
Если же это не удалось, то вернется:
SEND FAILВозвращает значок ">" после подачи команды. После этого, ESP8266 удерживает соединение посылая пакеты с интервалом 20 мс и максимальной длиной пакета 2048 байт. Когда будет получен пакет содержащий три последовательных символа плюс: "+++", то соединение разрывается и ESP8266 возвращается в обычный командный режим.
Команда может использоваться только в прозрачном режиме которе требует одиночного режима соединения(+CIPMUX=0)
Для UDP режима, значение <UDP mode> должно быть установлено в нуль, прежде чем подавать команду AT+CIPSTART.Параметры:
- <link ID>: ID соединения: от 0 до 4. Применимо для множественного режима соединения.
- <length>: длина данных, максимальное значение: 2048 байта.
- [<remote IP>]: удаленный IP адрес, может быть установлен для UDP сессии.
- [<remote port>]: удаленный порт, может быть установлен для UDP сессии.
Примеры: Для большей информации смотрите документ ESP8266 AT Command Examples.
AT+CIPCLOSE — Закрытие TCP/UDP/SSL соединения
Команды: Set Command (используется только при множественном соединении):
AT+CIPCLOSE=<link ID>
Действие: закрывает TCP/UDP соединение.(Про закрытие SSL соединения в оригинале ничего не сказано. Прим переводчика.)Execute Command (используется только при множественном соединении):
AT+CIPCLOSEОтклик: OK Параметры: <link ID>: где ID это номер закрываемого соединения (от 1 до 4). Когда ID равен 5, то это означает, что нужно закрыть все соединения. В режиме сервера, ID=5 не имеет какого-либо эффекта.
AT+CWQAP — отключение от точки доступа
Execute Command: AT+CWQAP Отклик: OK Параметры: отсутствуют.
Итак, попробуем получить html страницу которую мы разместили на веб-сервере OpenWRT.
Подключаемся к точке доступа:
AT+CWMODE_CUR=1 OK AT+CWJAP="Alien","password" WIFI CONNECTED WIFI GOT IP OK
Устанавливаем TCP-соединение:
AT+CIPSTART="TCP","192.168.1.10",8010 CONNECT OK
Отправляем http запрос из 18 байт, где текст запроса составляет 14 байт, плюс четыре байта отводится на комбинацию завершения: "\r\n\r\n"
AT+CIPSEND=18 OK >
После того, как появится символ ">", нужно будет ввести команду:
GET / HTTP/1.0
После ввода команды нужно еще раз ввести пустой Enter. Если всё было сделано правильно, то вернется наша html страница:
> Recv 18 bytes SEND OK +IPD,17:HTTP/1.0 200 OK +IPD,450:Connection: close ETag: "6004-111-5be409c1" Last-Modified: Thu, 08 Nov 2018 10:02:41 GMT Date: Thu, 15 Nov 2018 20:00:08 GMT Content-Type: text/html Content-Length: 273 <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> </head> <body style="background-color: white"> <h3>Hello World!</h3> </body> </html> CLOSED
Если посмотреть запись TCP-сессии в wireshark, то можно увидеть наш GET-запрос:
И 200-й ответ сервера с содержанием html-страницы:
Теперь подумаем, для чего нужна html страница? HTML страницы открывают в браузерах которые переобразуют их в форматированный текст. В ESP8266 нет ресурсов чтобы парсить интернет. Зато эти ресурсы есть в OpenWRT.
Погодные метеостанции различных типов - это одно из популярных направлений в любительской разработке. Но стоит ли изобретать велосипед? В сети существуют сайты которые публикуют погодные характеристики в режиме реального времени. Нужно только скачать страницу, отпарсить её и передать на ESP8266. Ну вот, например: получение температуры для Самары:
$ elinks --dump http://realmeteo.ru/samara/1/current|sed -n "13p" |awk '{print $1}'
-9DEGC
Остается написать задание для cron, что бы он периодически запускал эту команду, еще добавить дату и время для справки, и получим погодный логер из старого роутера. Остается передать лог на ESP8266 чтобы он выводил этот лог на дисплей, т.е. получаем этакий Hi-Tech градусник. У кого обычный градусник летом постоянно нагревается солнцем, те оценят.
Файл с логом погоды разместим в директории сайта: "/site/pub/waether.txt". Чтобы нам получить этот файл от веб-сервера, в GET-запросе нужно будет указать имя файла, который нам нужно получить:
GET /pub/weather.txt HTTP/1.0
В результате получаем наш файл:
AT+CIPSTART="TCP","192.168.1.10",8010 CONNECT OK AT+CIPSEND=33 OK > Recv 33 bytes SEND OK +IPD,17:HTTP/1.0 200 OK +IPD,1460:Connection: close ETag: "6006-545-5bede30f" Last-Modified: Thu, 15 Nov 2018 21:20:15 GMT Date: Thu, 15 Nov 2018 21:41:04 GMT Content-Type: text/plain Content-Length: 1349 [11-15-18 00:00:11] -5.8DEGC [11-15-18 00:30:11] -5.9DEGC [11-15-18 01:30:12] -6.4DEGC [11-15-18 02:00:12] -6.4DEGC [11-15-18 02:30:12] -6.6DEGC [11-15-18 03:00:11] -6.6DEGC [11-15-18 03:30:11] -6.8DEGC [11-15-18 04:00:11] -7.1DEGC [11-15-18 04:30:11] -7.2DEGC [11-15-18 05:00:11] -7.4DEGC [11-15-18 05:30:11] -7.6DEGC [11-15-18 06:00:12] -8.1DEGC [11-15-18 06:30:12] -8.1DEGC [11-15-18 07:00:12] -9DEGC [11-15-18 07:30:12] -9DEGC [11-15-18 08:00:12] -9DEGC [11-15-18 08:30:11] -9DEGC [11-15-18 09:00:11] -9DEGC [11-15-18 09:30:11] -7.9DEGC [11-15-18 10:00:11] -7.9DEGC [11-15-18 10:30:11] -6.7DEGC [11-15-18 11:00:11] -6.1DEGC [11-15-18 11:30:11] -5.4DEGC [11-15-18 12:00:11] -5.2DEGC [11-15-18 12:30:11] -5.2DEGC [11-15-18 13:00:11] -4.3DEGC [11-15-18 13:30:11] -4.2DEGC [11-15-18 14:00:11] -3.8DEGC [11-15-18 14:30:11] -3.4DEGC [11-15-18 15:00:11] -3.4DEGC [11-15-18 15:30:11] -3DEGC [11-15-18 16:00:11] -3DEGC [11-15-18 16:30:11] -2.8DEGC [11-15-18 17:00:11] -2.8DEGC [11-15-18 17:30:11] -2.7DEGC [11-15-18 18:00:11] -2.7DEGC [11-15-18 18:30:11] -2.6DEGC [11-15-18 19:00:11] -2.4DEGC [11-15-18 19:30:11] -2.4DEGC [11-15-18 20:00:12] -2.4DEGC [11-15-18 20:30:12] -2.7DEGC [11-15-18 21:00:12] -2.7DEGC [11-15-18 21:30:12] -2.7DEGC [11-15-18 22:00:12] -2.7DEGC [11-15-18 22:30:11] +IPD,68: -2.7DEGC [11-15-18 23:00:11] -2.7DEGC [11-15-18 23:30:11] -2.5DEGC CLOSED
Раньше, чтобы управлять роутером на OpenWRT, нужно было либо припаивать к нему "гребёнку" на UART интерфейс и тянуть провода к микроконтроллеру, посредством которого передавались бы ваши команды. Либо прикручивать к микроконтроллеру какой либо Ethernet чип и передавать команды через сеть Ethernet, что опять же подразумевает провода. С помощью ESP8266 вы сможете вычеркнуть из этого уравнения провода.
Т.к. сервер uhttpd поддерживает CGI интерфейс, мы можем связать наш ESP8266 с OpenWRT посредством этого интерфейса, который и заменит нам пресловутые провода. Скрипты cgi могут писаться на каких угодно языках, для примера я возьму самый очевидный вариант - язык shell скриптов. Я буду краток, но если вас заинтересует тема написания cgi скриптов на языке shell скриптов, то советую почитать книгу Дэвида Тейнсли: "Linux и UNIX: программирование в shell. Руководство разработчика", глава 29 "Сценарии cgi".
Для проверки работоспособности GCI интерфейса проведем небольшой тест. Для этого в каталоге "/site/cgi-bin/" создадим файл esp8266.cgi следующего содержания:
#!/bin/sh echo -en "Status: 200 OK\r\n" echo -en "Content-type: text/html\r\n\r\n" echo "<h1>test</h1>"
Установим на файл права:
# chmod 755 /site/cgi-bin/esp8266.cgi
Проверяем тут же в OpenWRT:
# curl localhost:8010/cgi-bin/esp8266.cgi
<h1>test</h1>
Работает. Теперь, допустим нам нужно получить текущую температуру. Приведем скрипт esp8266.cgi к такому виду:
#!/bin/sh echo -en "Status: 200 OK\r\n" echo -en "Content-type: text/html\r\n\r\n" echo "<h1>ESP8266 Weather</h1>" temp=$(elinks --dump http://realmeteo.ru/samara/1/current|sed -n "13p" |awk '{print $1}'|sed "s/DEGC//") echo "<p>" echo -n "current temp= " echo -n "$temp" echo "°" echo "</p>"
Проверяем из ESP8266:
Здесь после "AT+CIPSEND=37" нужно будет ввести: "GET /cgi-bin/esp8266.cgi HTTP/1.1", после чего два раза ввести Enter. Как можно видеть по вставкам вида: "+IDC:num", ответ от сервера приходит в формате Chunked transfer encoding, когда данные бьются на фрагменты.
Теперь нам нужно рассмотреть, как можно отправить данные с микроконтроллера, посредством ESP8266, на OpenWRT. В HTTP протоколе имеются два основных способа передачи данных от клиента серверу: а) через GET запрос; б) через POST запрос.
Первый способ несколько попроще, там данные передаются через строку адреса. Отсюда и главное ограничение такого способа: длина передаваемых данные не должна превышать максимальную длину URL. Кроме того, такие данные видны пользователю в строке веб-браузера, что тоже не всегда желательно. Но для того, чтобы передать несколько цифр полученных микроконтроллером от датчиков, GET запрос подходит как нельзя лучше.
GET запрос формируется добавлением к URL знака вопроса, после которого перечисляются данные и их значения:
?var1=value1&var2=value2&var3=value3
Данные разделяются символом амперсанда, пробелы и прочие непечатные символы передаются в шестнадцатеричном виде: %xy. Shell - скрипт получает данные от сервера через CGI интерфейс в виде встроенных переменных.
Приведем содержимое скрипта esp8266.cgi к следующему виду:
#!/bin/sh echo -en "Status: 200 OK\r\n" echo -en "Content-type: text/html\r\n\r\n" echo "<h1>ESP8266 - GET Request Example</h1>" echo "<p>" echo -n "Request method= " echo "$REQUEST_METHOD" echo "<br>" echo -n "Data: " echo "$QUERY_STRING" echo "</p>"
Проверяем:
# curl "localhost:8010/cgi-bin/esp8266.cgi?var1=value1&var2=value2&var3=value3"
<h1>ESP8266 - GET Request Example</h1>
<p>
Request method= GET
<br>
Data: var1=value1&var2=value2&var3=value3
</p>
Как видно, данные были успешно приняты, нам осталось лишь распарсить переменную QUERY_STRING. У меня это получилось так:
#!/bin/sh echo -en "Status: 200 OK\r\n" echo -en "Content-type: text/html\r\n\r\n" echo "<h1>ESP8266 - GET Request Example</h1>" echo "<p>" echo -n "Request method= " echo "$REQUEST_METHOD" echo "<br>" echo -n "Data: " echo "$QUERY_STRING" echo "</p>" line=$(echo "$QUERY_STRING"|sed "s/&/ /g") for loop in $line do name=$(echo $loop|awk -F = '{print $1}') type=$(echo $loop|awk -F = '{print $2}') var=$(printf "${name}=${type}") eval $(printf $var) done [ -z $var1 ] && exit || echo $var1 [ -z $var2 ] && exit || echo $var2 [ -z $var3 ] && exit || echo $var3 let "var1 += 10" echo $var1
Алгоритм был подсмотрен в книге Дэвида Тейнсли, но я его несколько упростил предположив, что значения переменных не будут содержать пробелы и непечатные символы, которые кодируются шестнадцатеричными числами. После парсинга выводятся значения полученных переменных. Предпологается, что переменная var1 является числом, и с ней производится арифметическая операция. Проверяем:
# curl "localhost:8010/cgi-bin/esp8266.cgi?var1=12&var2=bar&var3=foo"
<h1>ESP8266 - GET Request Example</h1>
<p>
Request method= GET
<br>
Data: var1=12&var2=bar&var3=foo
</p>
12
bar
foo
22
Отправка данных через POST запрос несколько сложнее. У этого метода имеется заголовок, в котором следует указывать формат и длинну данных.
Для обработки POST запросов создадим скрипт: "/site/cgi-bin/post.cgi" следующего содержания:
#!/bin/sh if [ "$REQUEST_METHOD" = "POST" ]; then QUERY_STRING=$(cat -) fi echo -en "Status: 200 OK\r\n" echo -en "Content-type: text/html\r\n\r\n" echo "<h1>ESP8266 - POST Request Example</h1>" echo "<p>" echo -n "Request method= " echo "$REQUEST_METHOD" echo "<br>" echo -n "Data: " echo "$QUERY_STRING" echo "</p>" line=$(echo "$QUERY_STRING"|sed "s/&/ /g") for loop in $line do name=$(echo $loop|awk -F = '{print $1}') type=$(echo $loop|awk -F = '{print $2}') var=$(printf "${name}=${type}") eval $(printf $var) done [ -z $var1 ] && exit || echo $var1 [ -z $var2 ] && exit || echo $var2 [ -z $var3 ] && exit || echo $var3 let "var1 += 10" echo $var1
Установим на него права:
# chmod 755 /site/cgi-bin/post.cgi
Проверяем командой:
$ curl -d "var1=12&var2=bar&var3=foo" -X POST "192.168.1.10:8010/cgi-bin/post.cgi"
Или:
$ curl -d "var1=12&var2=bar&var3=foo" -H "Content-Type: application/x-www-form-urlencoded" -X POST "192.168.1.10:8010/cgi-bin/post.cgi"
Где "192.168.1.10" - это адрес роутера c OpenWRT.
В Wireshark можно посмотреть формат запроса:
Как можно видеть, заголовок запроса состоит из следующих строк:
POST /cgi-bin/post.cgi HTTP/1.1 Host: 192.168.1.10:8010 User-Agent: curl/7.59.0 Accept: */* Content-Type: application/x-www-form-urlencoded Content-Length: 25
После заголовка следует ДВА enter'а, т.е. последовательность: "\r\n\r\n". После этого идут данные.
Полностью вводить вручную весь заголовок может быть утомительно, на скриншоте приведён лог сессии, где используется только первая строка заголовка:
Теперь подробнее, пошаговая инструкция.
Устанавливаем TCP-соединение:
AT+CIPSTART="TCP","192.168.1.10",8010 CONNECT OK
Отправляем http запрос из 60 байт, где заголовок будет состоять из 31 байта, 4 байта будет занимать последовательность окончания заголовка: "\r\n\r\n", на остальные 25 байт приходятся сами данные.
AT+CIPSEND=60 OK
После того, как появится символ ">", нужно будет ввести запрос:
POST /cgi-bin/post.cgi HTTP/1.1
После ввода запроса нужно еще раз ввести пустой Enter. После этого, вводим наши данные:
var1=12&var2=bar&var3=foo
После ввода Enter, должен прийти ответ от сервера. На скриншоте показан наш POST запрос в программе Wireshark:
В ESP8266 имеется режим "UART-WiFi passthrough" который в документации также называется прозрачным режимом (transparent). Этот режим можно назвать "UART через WIFI", т.к. он позволяет установить непрерывное соединение по TCP или UDP протоколу. Режим включается командой AT+CIPMODE=1, а выход из этого режима происходит посылкой последовательности трех плюсов подряд: "+++". Примеры с использованием данного режима приведены в следующем руководстве: ESP8266 AT Command Examples
Какие у этого может быть практическое применение? Думаю все знают о такой полезной утилите как nc или netcat, с помощью которой можно устраивать простенькие чаты. Одними чатами ее полезность не ограничена, мы можем также управлять компьютером c linux или Windows с её по помощью через ESP8266. Давайте посмотрим как это делается на примере OpenWRT.
Открываем backdoor на OpenWRT с помощью команды:
# nc -l -p 12345 -e /bin/ash
Запускаем ESP8266 и подключаемся к точке доступа:
AT+CWMODE_CUR=1 OK AT+CWJAP="Alien","password" WIFI CONNECTED WIFI GOT IP OK
Устанавливаем TCP-соединение:
AT+CIPSTART="TCP","192.168.1.10",12345 CONNECT OK
Где 192.168.1.10 - адрес роутера с OpenWRT, на котором мы открыли порт. Далее даём команды:
AT+CIPMODE=1
и:
AT+CIPSEND
После этого появится значок ">". После этого, в терминале, знак окончания строки нужно будет сменить с "NL & CR" на "NL", и можно начинать вводить команды:
Для окончания сеанса, следует в терминале сменить знак окончания строки на: "нет окончания строки". После этого ввести три знака плюс. Затем знак окончания строки сменить на: "NL & CR".
Далее, для разрыва соединения вводится команды:
AT+CIPMODE=0
и:
AT+CIPCLOSE
Думаю, что стоит упомянуть, что: а) использовать такой способ следует только в защищённом участке интрасети, б) не следует предоставлять привилегированный доступ к . При необходимости следует использовать sudo.
Плата "NodeMCU ESP32S" несколько более громоздкая нежели "NodeMCU V3":
Она шире, чем ESP8266 NodeMCU, и при установке в беспаячную макетку, свободным остается только один ряд. Т.е. пины на другой стороне становятся недоступными.
Существенным отличием от NodeMCU v3 является то, что для работы с AT-интерпретатором, от вас потребуется дополнительный USB-UART преобразователь. ESP32 имеет два интерфейса UART. Один используется для отладки, другой для работы с AT-интерпретатором. Микро-USB порт который имеется на плате используется для отладки и прошивки.
В настройках терминальной программы нужно будет выставить режим 115200 бод, и признак окончания строки: "NL & CR", т.е. все так же как и при работе с ESP8266. При подключении только что купленного модуля, у меня через отладочный порт пошел такой лог:
ets Jun 8 2016 00:22:57 rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) configsip: 0, SPIWP:0x00 clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO, clock div:2 load:0x3fff0008,len:8 load:0x3fff0010,len:3480 load:0x40078000,len:7804 ho 0 tail 12 room 4 load:0x40080000,len:252 entry 0x40080034 ^[[0;32mI (46) boot: ESP-IDF v2.0-3-gbef9896 2nd stage bootloader^[[0m ^[[0;32mI (46) boot: compile time 05:59:45^[[0m ^[[0;32mI (46) boot: Enabling RNG early entropy source...^[[0m ^[[0;32mI (65) boot: SPI Speed : 40MHz^[[0m ^[[0;32mI (78) boot: SPI Mode : DIO^[[0m ^[[0;32mI (90) boot: SPI Flash Size : 4MB^[[0m ^[[0;32mI (102) boot: Partition Table:^[[0m ^[[0;32mI (114) boot: ## Label Usage Type ST Offset Length^[[0m ^[[0;32mI (136) boot: 0 phy_init RF data 01 01 0000f000 00001000^[[0m ^[[0;32mI (160) boot: 1 otadata OTA data 01 00 00010000 00002000^[[0m ^[[0;32mI (183) boot: 2 nvs WiFi data 01 02 00012000 0000e000^[[0m ^[[0;32mI (206) boot: 3 at_customize unknown 40 00 00020000 000e0000^[[0m ^[[0;32mI (229) boot: 4 ota_0 OTA app 00 10 00100000 00180000^[[0m ^[[0;32mI (253) boot: 5 ota_1 OTA app 00 11 00280000 00180000^[[0m ^[[0;32mI (276) boot: End of partition table^[[0m ^[[0;32mI (289) boot: Disabling RNG early entropy source...^[[0m ^[[0;32mI (306) boot: Loading app partition at offset 00100000^[[0m ^[[0;32mI (1482) boot: segment 0: paddr=0x00100018 vaddr=0x00000000 size=0x0ffe8 ( 65512) ^[[0m ^[[0;32mI (1482) boot: segment 1: paddr=0x00110008 vaddr=0x3f400010 size=0x1c5f0 (116208) map^[[0m ^[[0;32mI (1499) boot: segment 2: paddr=0x0012c600 vaddr=0x3ffb0000 size=0x0215c ( 8540) load^[[0m ^[[0;32mI (1529) boot: segment 3: paddr=0x0012e764 vaddr=0x40080000 size=0x00400 ( 1024) load^[[0m ^[[0;32mI (1552) boot: segment 4: paddr=0x0012eb6c vaddr=0x40080400 size=0x1b028 (110632) load^[[0m ^[[0;32mI (1631) boot: segment 5: paddr=0x00149b9c vaddr=0x400c0000 size=0x00034 ( 52) load^[[0m ^[[0;32mI (1632) boot: segment 6: paddr=0x00149bd8 vaddr=0x00000000 size=0x06430 ( 25648) ^[[0m ^[[0;32mI (1648) boot: segment 7: paddr=0x00150010 vaddr=0x400d0018 size=0x7a56c (501100) map^[[0m ^[[0;32mI (1676) heap_alloc_caps: Initializing. RAM available for dynamic allocation:^[[0m ^[[0;32mI (1698) heap_alloc_caps: At 3FFBA6B8 len 00025948 (150 KiB): DRAM^[[0m ^[[0;32mI (1719) heap_alloc_caps: At 3FFE8000 len 00018000 (96 KiB): D/IRAM^[[0m ^[[0;32mI (1741) heap_alloc_caps: At 4009B428 len 00004BD8 (18 KiB): IRAM^[[0m ^[[0;32mI (1762) cpu_start: Pro cpu up.^[[0m ^[[0;32mI (1773) cpu_start: Single core mode^[[0m ^[[0;32mI (1786) cpu_start: Pro cpu start user code^[[0m ^[[0;32mI (1847) cpu_start: Starting scheduler on PRO CPU.^[[0m ^[[0;32mI (2016) uart: queue free spaces: 10^[[0m Bin version:0.10.0^M I (2017) wifi: wifi firmware version: c604573 I (2017) wifi: config NVS flash: enabled I (2018) wifi: config nano formating: disabled I (2027) wifi: Init dynamic tx buffer num: 32 I (2027) wifi: wifi driver task: 3ffc4eac, prio:23, stack:3584 I (2032) wifi: Init static rx buffer num: 10 I (2036) wifi: Init dynamic rx buffer num: 0 I (2040) wifi: Init rx ampdu len mblock:7 I (2044) wifi: Init lldesc rx ampdu entry mblock:4 I (2049) wifi: wifi power manager task: 0x3ffca254 prio: 21 stack: 2560 I (2055) wifi: wifi timer task: 3ffcb2d4, prio:22, stack:3584 ^[[0;31mE (2060) phy_init: PHY data partition validated^[[0m ^[[0;32mI (2080) phy: phy_version: 329, Feb 22 2017, 15:58:07, 0, 0^[[0m I (2081) wifi: mode : softAP (80:7d:3a:cb:66:b9) I (2084) wifi: mode : sta (80:7d:3a:cb:66:b8) + softAP (80:7d:3a:cb:66:b9) I (2087) wifi: mode : softAP (80:7d:3a:cb:66:b9)^M
Из любопытного. Последовательности: [[0;32mI и [[0m означают цветовую разметку вывода в Linux. Это означает, что мы можем подключиться к порту программной screen:
$ screen /dev/ttyUSB0 115200,cs8
Выглядит это так:
Из полезного, тут можно узнать версию AT-интерпретатора:
Bin version:0.10.0
Т.к. это ужас какая древняя версия, аж прошлого 2017-го года, скорее всего вам захочется ее обновить. Для этого нам снова придется обратится к программе esptool.py
Для начала проверим связь:
$ esptool.py --port /dev/ttyUSB0 --chip esp32 flash_id
esptool.py v4.6.2
Serial port /dev/ttyUSB0
Connecting....
Chip is ESP32-D0WDQ6 (revision v1.0)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
WARNING: Detected crystal freq 41.01MHz is quite different to normalized freq 40MHz. Unsupported crystal in use?
Crystal is 40MHz
MAC: 80:7d:3a:cb:66:b8
Uploading stub...
Running stub...
Stub running...
Manufacturer: c8
Device: 4016
Detected flash size: 4MB
Hard resetting via RTS pin...
$ esptool.py --port /dev/ttyUSB0 --chip esp32 chip_id esptool.py v4.6.2 Serial port /dev/ttyUSB0 Connecting...... Chip is ESP32-D0WDQ6 (revision v1.0) Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None Crystal is 40MHz MAC: 80:7d:3a:cb:66:b8 Uploading stub... Running stub... Stub running... Warning: ESP32 has no Chip ID. Reading MAC instead. MAC: 80:7d:3a:cb:66:b8 Hard resetting via RTS pin...
В википедии есть табличка с вариантами чипа ESP32, где можно будет найти свой:
Затем, вам возможно захочется сохранить существующую прошивку:
$ esptool.py --chip esp32 --port /dev/ttyUSB0 read_flash 0x00000 0x400000 ./esp32_firmware2.bin
esptool.py v4.6.2
Serial port /dev/ttyUSB0
Connecting.....
Chip is ESP32-D0WDQ6 (revision v1.0)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: 80:7d:3a:cb:66:b8
Uploading stub...
Running stub...
Stub running...
4194304 (100 %)
4194304 (100 %)
Read 4194304 bytes at 0x00000000 in 381.6 seconds (87.9 kbit/s)...
Hard resetting via RTS pin...
Актуальную версию прошивки AT-интерпретатора можно скачать с официального сайта: ESP32 Released Firmwares.
После распаковки архива, видим следующую структуру каталогов:
$ tree . . ├── at_customize.bin ├── bootloader │ └── bootloader.bin ├── customized_partitions │ ├── mfg_nvs.bin │ └── mfg_nvs.csv ├── download.config ├── esp-at.bin ├── esp-at.elf ├── esp-at.map ├── factory │ └── factory_WROOM-32.bin ├── flasher_args.json ├── ota_data_initial.bin ├── partition_table │ └── partition-table.bin ├── phy_multiple_init_data.bin └── sdkconfig
Здесь нас будет интересовать содержимое файла "download.config", к котором хранится опции прошивки для esptool.py:
--flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 bootloader/bootloader.bin 0x100000 esp-at.bin 0x8000 partition_table/partition-table.bin 0x10000 ota_data_initial.bin 0xf000 phy_multiple_init_data.bin 0x20000 at_customize.bin 0x21000 customized_partitions/mfg_nvs.bin
Для начала протираем флешку:
$ esptool.py -p /dev/ttyUSB0 --chip esp32 erase_flash
esptool.py v4.6.2
Serial port /dev/ttyUSB0
Connecting....
Chip is ESP32-D0WDQ6 (revision v1.0)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: 80:7d:3a:cb:66:b8
Uploading stub...
Running stub...
Stub running...
Erasing flash (this may take a while)...
Chip erase completed successfully in 5.0s
Hard resetting via RTS pin...
Затем заливаем прошивку:
$ esptool.py --chip esp32 --port /dev/ttyUSB0 write_flash $(cat download.config)
Процесс прошивки:
esptool.py v4.6.2 Serial port /dev/ttyUSB0 Connecting.... Chip is ESP32-D0WDQ6 (revision v1.0) Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None Crystal is 40MHz MAC: 80:7d:3a:cb:66:b8 Uploading stub... Running stub... Stub running... Configuring flash size... Flash will be erased from 0x00001000 to 0x00007fff... Flash will be erased from 0x00100000 to 0x00260fff... Flash will be erased from 0x00008000 to 0x00008fff... Flash will be erased from 0x00010000 to 0x00011fff... Flash will be erased from 0x0000f000 to 0x0000ffff... Flash will be erased from 0x00020000 to 0x00020fff... Flash will be erased from 0x00021000 to 0x0003cfff... Compressed 25456 bytes to 16057... Wrote 25456 bytes (16057 compressed) at 0x00001000 in 1.6 seconds (effective 123.8 kbit/s)... Hash of data verified. Compressed 1443168 bytes to 967763... Wrote 1443168 bytes (967763 compressed) at 0x00100000 in 85.6 seconds (effective 134.8 kbit/s)... Hash of data verified. Compressed 3072 bytes to 129... Wrote 3072 bytes (129 compressed) at 0x00008000 in 0.0 seconds (effective 584.9 kbit/s)... Hash of data verified. Compressed 8192 bytes to 31... Wrote 8192 bytes (31 compressed) at 0x00010000 in 0.1 seconds (effective 1075.2 kbit/s)... Hash of data verified. Compressed 1072 bytes to 153... Wrote 1072 bytes (153 compressed) at 0x0000f000 in 0.0 seconds (effective 209.1 kbit/s)... Hash of data verified. Compressed 3072 bytes to 92... Wrote 3072 bytes (92 compressed) at 0x00020000 in 0.0 seconds (effective 646.7 kbit/s)... Hash of data verified. Compressed 114688 bytes to 12973... Wrote 114688 bytes (12973 compressed) at 0x00021000 in 1.9 seconds (effective 478.1 kbit/s)... Hash of data verified. Leaving... Hard resetting via RTS pin...
После перезагрузки ESP32, в терминальной программе должен появиться такой лог:
Если после перепрошивки отладочный лог платы в порядке, то теперь для работы с AT-командами нужно будет подключить USB-UART адаптер с 3.3 вольтовой логикой на второй UART порт ESP32. Подключение USB-UART адаптера и ESP32: GND<-->GND(адаптера), RX2<-->TX(адаптера), TX2<-->RX(адаптера).
Выглядит этот "колхоз" примерно так:
При подключении терминальной программой запрашиваем версию прошивки:
AT+GMR AT version:3.2.0.0(s-ec2dec2 - ESP32 - Jul 28 2023 07:05:28) SDK version:v5.0.2-376-g24b9d38a24-dirty compile time(6118fc22):Jul 28 2023 09:47:28 Bin version:v3.2.0.0(WROOM-32)
Работа с AT интерпретатором ESP32 по сути не отличается от ESP8266:
Как можно видеть, в настоящее время избавились от суффиксов "DEF" и "CUR" в командах.
Руководство по командам AT-интерпретатора можно найти на официальном сайте:
https://docs.espressif.com/projects/esp-at/en/latest/esp32/AT_Command_Set/index.html
При работе с MicroPython, существенным плюсом является то, ему не требуется дополнительный UART-преобразователь. Т.е. вы подключаете плату ESP32 к компьютеру, и работаете, т.е. все так же как и на ESP8266.
Скачать прошивку MicroPython для ESP32 можно с официального сайта https://micropython.org/download/ESP32_GENERIC/
Там же есть инструкция по прошивке:
После прошивки, запускаем терминальную программу на скорости обмена 115200 и последовательность окончания строки "CR & NL"
Перезагружаем чип щелчком по кнопке "EN". В терминале должно появиться следующее:
ets Jun 8 2016 00:22:57 rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) configsip: 0, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO, clock div:2 load:0x3fff0030,len:4656 load:0x40078000,len:13284 ho 0 tail 12 room 4 load:0x40080400,len:3712 entry 0x4008064c MicroPython v1.20.0 on 2023-04-26; ESP32 module with ESP32 Type "help()" for more information. >>>
Вводим "help()" и в ответ должно появиться следующее:
help() Welcome to MicroPython on the ESP32! For generic online docs please visit http://docs.micropython.org/ For access to the hardware use the 'machine' module: import machine pin12 = machine.Pin(12, machine.Pin.OUT) pin12.value(1) pin13 = machine.Pin(13, machine.Pin.IN, machine.Pin.PULL_UP) print(pin13.value()) i2c = machine.I2C(scl=machine.Pin(21), sda=machine.Pin(22)) i2c.scan() i2c.writeto(addr, b'1234') i2c.readfrom(addr, 4) Basic WiFi configuration: import network sta_if = network.WLAN(network.STA_IF); sta_if.active(True) sta_if.scan() # Scan for available access points sta_if.connect("", " ") # Connect to an AP sta_if.isconnected() # Check for successful connection Control commands: CTRL-A -- on a blank line, enter raw REPL mode CTRL-B -- on a blank line, enter normal REPL mode CTRL-C -- interrupt a running program CTRL-D -- on a blank line, do a soft reset of the board CTRL-E -- on a blank line, enter paste mode For further help on a specific object, type help(obj) For a list of available modules, type help('modules') >>>
Вводим команды:
import machine machine.freq()
в ответ у меня выдало:
160000000
Пишем "machine.freq(240000000)" и в следующий раз при запросе "machine.freq()" должно выдать уже цифру "240000000"
Можно попытаться считать показания температурного датчика:
>>> import esp32 >>> esp32.raw_temperature() 113 >>> print ((113-32)*5/9) 45.0 >>>
Температура выдается в фаренгейтах, для ее преобразования в цельсии используется формула. Сорок пять градусов это многовато, но данном случае это температура чипа, а не окружающей среды. Хотя, когда я прикоснулся к крышке модуля, она была холодной.
Подключение к сети производится также как в случае ESP8266:
import network wlan = network.WLAN(network.STA_IF) wlan.active(True) wlan.scan()
Подключение:
wlan.isconnected() wlan.connect('Ваша_точка_доступа', 'пароль') wlan.isconnected()
Проверяем:
>>> wlan.ifconfig() ('192.168.1.14', '255.255.255.0', '192.168.1.1', '192.168.1.1')
Связь есть. В принципе, на этом этапе можно уже запускать VSCode или VSCodium и начинать писать код на MicroPython.
Буквально пару слов о прошивке модуля ESP32 в "Tasmota Sonoff". Она производится также как и для ESP8266, там только пришлось зажимать кнопку "boot" перед "INSTALL". Главный экран выглядит так:
Но то, что я хотел бы там найти - управление через Bluetooth я там не нашел:
При работе с MicroPython, существенным плюсом является то, ему не требуется дополнительный UART-преобразователь. Т.е. вы подключаете плату ESP32 к компьютеру, и работаете, т.е. все так же как и на ESP8266.
Скачать прошивку MicroPython для ESP32 можно с официального сайта https://micropython.org/download/ESP32_GENERIC/
Там же есть инструкция по прошивке:
После прошивки, запускаем терминальную программу на скорости обмена 115200 и последовательность окончания строки "CR & NL"
Перезагружаем чип щелчком по кнопке "EN". В терминале должно появиться следующее:
ets Jun 8 2016 00:22:57 rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) configsip: 0, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO, clock div:2 load:0x3fff0030,len:4656 load:0x40078000,len:13284 ho 0 tail 12 room 4 load:0x40080400,len:3712 entry 0x4008064c MicroPython v1.20.0 on 2023-04-26; ESP32 module with ESP32 Type "help()" for more information. >>>
Вводим "help()" и в ответ должно появиться следующее:
help() Welcome to MicroPython on the ESP32! For generic online docs please visit http://docs.micropython.org/ For access to the hardware use the 'machine' module: import machine pin12 = machine.Pin(12, machine.Pin.OUT) pin12.value(1) pin13 = machine.Pin(13, machine.Pin.IN, machine.Pin.PULL_UP) print(pin13.value()) i2c = machine.I2C(scl=machine.Pin(21), sda=machine.Pin(22)) i2c.scan() i2c.writeto(addr, b'1234') i2c.readfrom(addr, 4) Basic WiFi configuration: import network sta_if = network.WLAN(network.STA_IF); sta_if.active(True) sta_if.scan() # Scan for available access points sta_if.connect("", " ") # Connect to an AP sta_if.isconnected() # Check for successful connection Control commands: CTRL-A -- on a blank line, enter raw REPL mode CTRL-B -- on a blank line, enter normal REPL mode CTRL-C -- interrupt a running program CTRL-D -- on a blank line, do a soft reset of the board CTRL-E -- on a blank line, enter paste mode For further help on a specific object, type help(obj) For a list of available modules, type help('modules') >>>
Вводим команды:
import machine machine.freq()
в ответ у меня выдало:
160000000
Пишем "machine.freq(240000000)" и в следующий раз при запросе "machine.freq()" должно выдать уже цифру "240000000"
Можно попытаться считать показания температурного датчика:
>>> import esp32 >>> esp32.raw_temperature() 113 >>> print ((113-32)*5/9) 45.0 >>>
Температура выдается в фаренгейтах, для ее преобразования в цельсии используется формула. Сорок пять градусов это многовато, но данном случае это температура чипа, а не окружающей среды. Хотя, когда я прикоснулся к крышке модуля, она была холодной.
Подключение к сети производится также как в случае ESP8266:
import network wlan = network.WLAN(network.STA_IF) wlan.active(True) wlan.scan()
Подключение:
wlan.isconnected() wlan.connect('Ваша_точка_доступа', 'пароль') wlan.isconnected()
Проверяем:
>>> wlan.ifconfig() ('192.168.1.14', '255.255.255.0', '192.168.1.1', '192.168.1.1')
Связь есть. В принципе, на этом этапе можно уже запускать VSCode или VSCodium и начинать писать код на MicroPython.
Буквально пару слов о прошивке модуля ESP32 в "Tasmota Sonoff". Она производится также как и для ESP8266, там только пришлось зажимать кнопку "boot" перед "INSTALL". Главный экран выглядит так:
Но то, что я хотел бы там найти - управление через Bluetooth я там не нашел:
Настройку VSCode для работы с микропитоном я уже описывал в статье про BlackPill: "Использование редакторов VS Code и Atom в качестве IDE для MicroPython". Но работа с микропитоном в ESP8266/ESP32 имеет принципиальное отличие от работы с платами STM32/RP2040.
Микропитон включает в себя файловую систему куда можно сохранять свой проект. Если вы имеете дело с платой STM32, то при подключении по USB у вас появлется два устройства: последовательный порт и небольшая флешка. Однако ESP8266/ESP32 не имеют USB интерфейса, и при подключении по USB вы имеете лишь последовательный порт. Тем не менее, ESP8266/ESP32 имеют флеш-память на несколько мегабайт. И файловая система микропитона, куда вы можете сохранять свой проект там тоже есть. Как с ней работать? Давайте разбираться.
Здесь можно ознакомится с кратким справочником по использованию микропиона на ESP8266:
"Quick reference for the ESP8266"
Функции для работы с файловой системой микропитона находятся в модуле "UOS":
uos – basic “operating system” services.
Открываем терминал и выводим список доступных модулей:
>>> help('modules')
__main__ lwip uasyncio/lock upysh
_boot math uasyncio/stream urandom
_onewire micropython ubinascii ure
_uasyncio mip/__init__ ucollections urequests
_webrepl neopixel ucryptolib urllib/urequest
apa102 network uctypes uselect
btree ntptime uerrno usocket
builtins onewire uhashlib ussl
dht port_diag uheapq ustruct
ds18x20 ssd1306 uio usys
esp uarray ujson utime
flashbdev uasyncio/__init__ umachine uwebsocket
framebuf uasyncio/core umqtt/robust uzlib
gc uasyncio/event umqtt/simple webrepl
inisetup uasyncio/funcs uos webrepl_setup
Plus any modules on the filesystem
>>>
Это те модули, которые "хардкорно" были собраны вместе с прошивкой. Выводим справку по модулю UOS:
>>> help(uos)
object <module 'uos'> is of type module
__name__ -- uos
uname -- <function>
urandom -- <function>
chdir -- <function>
getcwd -- <function>
listdir -- <function>
mkdir -- <function>
remove -- <function>
rename -- <function>
rmdir -- <function>
stat -- <function>
statvfs -- <function>
unlink -- <function>
dupterm -- <function>
dupterm_notify -- <function>
ilistdir -- <function>
mount -- <function>
umount -- <function>
VfsFat -- <class 'VfsFat'>
VfsLfs2 -- <class 'VfsLfs2'>
>>>
загружаем модуль:
>>> import uos
Печатаем список файлов флешки:
>>> uos.listdir('/')
['boot.py']
Очевидно, что это файл который прошит здесь по умолчанию. Можем прочитать его с помощью следующих команд:
file = open("boot.py","r") file.read() file.close()
В результате получим следующий лог:
В данном случае файл прочитался одной строкой. Можно причитать его построчно, если вместо функции read() использовать readline(). Но тогда "readline()" придется вводить столько раз, сколько строк в файле:
Когда readline() возвращает символ кавычек, это означает, что файл закончился. Собирая воедино, получаем следующее содержание загрузочного скрипта "boot.py":
# This file is executed on every boot (including wake-boot from deepsleep) #import esp #esp.osdebug(None) import uos, machine #uos.dupterm(None, 1) # disable REPL on UART(0) import gc #import webrepl #webrepl.start() gc.collect()
Т.е. у нас дефолом загружаются модули "uos","machine" и "gc", после чего командой gc.collect() запускается сборщик мусора (Модуль gc - control the garbage collector).
Можно удалить этот файл, и после следующей перезагрузки его уже не будет. Перезагрузка ESP8266 осуществляется по команде:
machine.reset()
Мы можем посмотреть размер свободного пространства на флешке, если последовательно введем следующие команды:
import uos fs_stat = uos.statvfs('/') fs_size = fs_stat[0] * fs_stat[2] fs_free = fs_stat[0] * fs_stat[3] print("File System Size {:,} - Free Space {:,}".format(fs_size, fs_free))
В моем случае получилось 3МБ свободно:
File System Size 3,125,248 - Free Space 3,117,056
Полный размер флешки можно узнать с помощью команд:
import esp esp.flash_size()
Получается как-то так:
import esp >>> esp.flash_size() 4194304
Аналогичным образом можно создавать файлы и каталоги, удалять их, переименовывать, можно даже отформатировать флешку. Но гораздо удобнее это будет делать из кодового редактора.
Хочу оговориться, что я не пытаюсь продвигать какой либо кодовый редактор, или расширение. Показываю только то, что у меня работает. Далее речь пойдет о работе со связкой "VSCode+Pymakr", но насколько я понял, "Pymakr" довольно проблемное решение и будет работать далеко не у всех. Если вам не удастся подружиться pymakr, то попробуйте обратить внимание на Arduino IDE 2.x, там поддержка микропитона официально заявлена.
Допустим мы установили расширение "pymakr":
Актуальная версия расширения 2.22.5 лично у меня отказалась работать. Хорошую инструкцую по работе с "pymakr" версии 2.х можно прочитать здесь: Program ESP32 with MicroPython Using VS Code and PyMakr. В моем случае, расширение не видело подключенное устройство. Решением для меня стал откат на версию 1.1.18
Если расширение устанавливается в первый раз, то вам сразу откроется файл с настройками " ~/.config/Code/User/pymakr.json". В противном случае его можно открыть через меню "All Commands -> Global Settings"
Главная сложность здесь в добавлении "Manufacturer" вашего USB-UART преобразователя. Для CP2102 он прописан:
А вот для другой моей платы на СH341 "Manufacturer" не был прописан, и как ее подружить с pymakr я не придумал.
В целом, настройки должны выгядеть как-то так:
Если ваша плата ESP8266 на UART-USB преобразователе CP2102, то в список мануфактур должен быть прописан производитель "Silicon Labs". После сохранения настроек создаем новый проект, открываем терминал, подключаемся к ESP8266, вводим тестовое "Неllo":
Теперь можно начать программировать на микропитоне!
Лично мне первым делом захотелось запустить какой-нибудь тест производительности (бенчмарк). Я нашел следующий проект: "https://github.com/shaoziyang/micropython_benchmarks/tree/master/1.9.4-479", где имеется любопытная табличка выполнения теста на различных платформах:
Добавляем новый файл в проект, копируем в него текст программы, после чего жмем на кнопку "Upload" на нижней панели. После загрузки файла ESP8266 перезагрузится. После этого следует запустить программу нажав кнопку "Run" на нижней панели. Выполнение теста займет некоторое время, в итоге у меня получился такой результат:
В принципе цифры совпадают с табличными значениями. Мне стало любопытно, какие результаты покажет тест на обычном компьютере. Я собрал микропитон из исходников для Linux, немного модифицировал программу, т.к. модуля "machine" в Linux-версии микропитона не было. С помощью модуля "machine" бенчмарк печатает частоту процессора, и я посчитал, что эти данные не столь важны. Процессор компьютера на котором я выполнял тест - далеко не первой свежести, это AMD FX-6300. В процессе выполнения теста я посмотрел загрузку процессора, и как я и ожидал, микропитон работал только на одном ядре. Т.о. я получил следующий результат:
Получилось, что тест на одном ядре процессора выполнялся примерно в сто раз быстрее чем на ESP8266. Если верить приведенной выше таблице, то неплохие результаты показали H743 и K210, они всего лишь в десять раз медленнее, т.е. их производительность где-то на уровне Pentium-3.
Теперь давайте попробуем сделать что-то более полезное. Микропитон в процессе загрузки выполняет последовательно файлы, если они есть: "boot.py" и "main.ру" , а после их выполнения запускает интерпретатор REPL. Если в любой из этих файлов вы поместите бесконечный цикл, то доступ к REPL вы потеряете.
Давайте составим "boot.py" где будет устанавливаться соединение с точкой доступа:
import network from time import sleep import esp esp.osdebug(None) import gc gc.collect() wlan = network.WLAN(network.STA_IF) wlan.active(True) while wlan.active() == False: print("waiting...\n") sleep (0.5) if wlan.isconnected() == False: wlan.connect('ваша_точка_доступа', 'пароль') while wlan.isconnected() == False: print("connection...\n") sleep(0.5) print('Connection successful') print(wlan.ifconfig())
Результат выполнения:
Как можно видеть, процесс установки соединения не быстрый.
Теперь, когда у нас есть соединение, давайте напишем веб-сервер и с его помощью будем мигать светодиодом. На python с использованием модуля "socket" это делается парой строк кода.
Мне не очень хочется вдаваться здесь в тонкости создания веб-приложений на питоне, поэтому я взял готовый пример и немого адаптировал его под NodeMCU v3. Тем кому интересны подробности, почитайте оригинальную статью:
"ESP32/ESP8266 MicroPython Web Server – Control Outputs".
Итак, создаем файл "main.py" следующего содержания:
# https://randomnerdtutorials.com/esp32-esp8266-micropython-web-server/ import gc from machine import Pin try: import usocket as socket except: import socket gc.collect() led = Pin(2, Pin.OUT) led.value(1) # off led def web_page(): if led.value() == 0: gpio_state="ON" else: gpio_state="OFF" html = """<html><head> <title>ESP Web Server</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" href="data:,"> <style>html{font-family: Helvetica; display:inline-block; margin: 0px auto; text-align: center;} h1{color: #0F3376; padding: 2vh;}p{font-size: 1.5rem;}.button{display: inline-block; background-color: #e7bd3b; border: none; border-radius: 4px; color: white; padding: 16px 40px; text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;} .button2{background-color: #4286f4;}</style></head><body> <h1>ESP Web Server</h1> <p>GPIO state: <strong>""" + gpio_state + """</strong></p><p><a href="/?led=on"><button class="button">ON</button></a></p> <p><a href="/?led=off"><button class="button button2">OFF</button></a></p></body></html>""" return html s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('', 80)) s.listen(5) while True: conn, addr = s.accept() print('Got a connection from %s' % str(addr)) request = conn.recv(1024) request = str(request) print('Content = %s' % request) led_on = request.find('/?led=on') led_off = request.find('/?led=off') if led_on == 6: print('LED ON') led.value(0) if led_off == 6: print('LED OFF') led.value(1) response = web_page() conn.send('HTTP/1.1 200 OK\n') conn.send('Content-Type: text/html\n') conn.send('Connection: close\n\n') conn.sendall(response) conn.close()
Загружаем файл на ESP8266 и если после перезагрузки ESP8266 установилось соединение и не высыпались ошибки, то проверяем наш сервер утилитой curl. Мы должны получить такой ответ:
При этом в терминале ESP8266 должен появиться такой лог:
Если все в порядке, на ESP8266 можно зайти с телефона или планшета, где у нас появится возможность управлять состояним светодиода на GPIO2:
Скачать исходники проекта можно по следующей ссылке скачать
На этом пока всё. За бортом осталась работа с mDSN (мультикаст) и ESP-NOW, но я подозреваю, что для этого потребуется отдельная статья.