- ESP8266. Начало работы, особенности
- Купить на Aliexpress
- Уроки по работе с esp8266
- Характеристики
- Начало работы
- Настройки платы
- Нумерация пинов
- Особенности пинов
- Особенности работы WiFi
- Отличия от AVR Arduino
- Деление на 0
- min() и max()
- map()
- Типы данных
- Функция analogRead()
- Функция analogWrite()
- Аппаратные прерывания
- Функция yield()
- EEPROM
- Serial (UART)
- Полезные страницы
ESP8266. Начало работы, особенности
В этом уроке поговорим о микроконтроллере ESP8266 и платах на его основе. Как с ними работать и чем они отличаются от Arduino на базе МК AVR. ESP8266 – китайский микроконтроллер за 2 доллара с большим объемом памяти и WiFi связью на борту. Официальная документация:
Купить на Aliexpress
Дёшево купить Wemos Mini можно тут: ссылка, ссылка, ссылка. Рекомендуется брать версию как слева на картинке выше, на базе полного чипа ESP-12.
Уроки по работе с esp8266
Конкретные уроки по работе с платой и WiFi библиотеками публикуются на сайте набора GyverKIT, так как уроки на этом сайте являются общими по программированию Arduino, без углубления в сторонние библиотеки.
Характеристики
- Напряжение питания: 3.3V (2.5-3.6V)
- Ток потребления: 300 мА при запуске и передаче данных, 35 мА во время работы, 80 мА в режиме точки доступа
- Максимальный ток пина – 12 мА.
- Flash память (память программы): 1 МБ
- Flash память (файловое хранилище): 1-16 МБ в зависимости от модификации
- EEPROM память: до 4 кБ
- SRAM память: 82 кБ
- Частота ядра: 80/160 МГц
- GPIO: 11 пинов
- ШИМ: 10 пинов
- Прерывания: 10 пинов
- АЦП: 1 пин
- I2C: 1 штука (программный, пины можно назначить любые)
- I2S: 1 штука
- SPI: 1 штука
- UART: 1.5 штуки
- WiFi связь
Начало работы
Для работы с платами на основе esp8266 нужно установить ядро и драйвер.
- Идём в Файл/Настройки/Дополнительные ссылки для менеджера плат. Вставляем ссылку https://arduino.esp8266.com/stable/package_esp8266com_index.json.
- Инструменты/Плата/Менеджер плат…, ищем в поиске esp8266 и устанавливаем. В списке плат появится семейство плат на базе esp8266.
- На большинстве плат стоит USB конвертер CH340, как на всех китайских Ардуинах. Если вы ещё не устанавливали драйвер – читать здесь.
Настройки платы
Для работы с любой платой (даже самодельной) можно выбрать пункт Generic esp8266, будет доступен полный набор настроек. Для работы с Wemos Mini выбираем LOLIN Wemos D1 R2 mini. Настроек станет меньше, а к пинам платы можно будет обращаться в программе по их подписям на плате (Dn). Основные настройки:
- Upload speed: скорость загрузки прошивки. Можно смело поднимать до 921600.
- CPU Frequency: частота тактирования процессора. Для большинства задач хватит стандартных 80 МГц. На 160 МГц будет работать шустрее, но могут быть сбои.
- Flash Size: распределение памяти, настройка имеет вид xMB (FS:xMB OTA:~xKB). Размер памяти под программу не меняется – это всегда 1 МБ.
- Первое число: полный объём микросхемы памяти (в основном 4MB, на Wemos и NodeMCU стоят такие).
- Второе число: объём под файловое хранилище.
- Третье число: объём под OTA (обновление по воздуху) – всегда меньше 1 МБ.
- Что выбрать? У Wemos самый ходовой – первый вариант: 4MB (FS:2MB OTA:~1019KB).
- DOUT: медленный, но совместим со всеми модификациями esp8266.
- QIO: более быстрый, но будет работать не на всех чипах.
- Only Sketch: стереть только программу.
- Sketch + WiFi Settings: стереть программу и настройки WiFi (логин-пароль последнего подключения и т.д.).
- All Flash Contents: полностью очистить память.
Нумерация пинов
У самого чипа esp8266 все выводы пронумерованы цифрами. На распиновке они подписаны как GPIOn, где n – номер. На плате (NodeMCU, Wemos Mini) пины подписаны как Dn и эти номера не совпадают с номерами GPIO! При работе например с Wemos можно использовать как нумерацию выводов GPIO ( digitalWrite(5, LOW) ), так и D-нумерацию пинов на плате ( digitalWrite(D1, LOW) ) – если выбрана плата Wemos. Новички очень часто в этом путаются, будьте внимательны. Также GPIO1 и GPIO3 подписаны на плате как TX и RX, по этим названиям к ним тоже можно обращаться ( digitalWrite(TX, LOW) ).
Особенности пинов
У esp8266 много системных пинов, с которыми нужно быть очень внимательным.
- К целому ряду пинов подключена внешняя Flash память, в общем случае их использовать нельзя (если очень нужно – ищите информацию). На плате NodeMCU визуально гораздо больше пинов, чем на Wemos Mini, но по факту “безопасных” для использования пинов там ровно столько же.
- С оставшимися пинами тоже не всё гладко: некоторые из них требуют наличия определенного логического уровня на момент включения микроконтроллера (подача питания, перезагрузка). Если к этим пинам подключить что-то, дающее противоположный сигнал – esp не запустится. Вот распиновка с нужным уровнем сигнала при запуске:
- На плате (NodeMCU, Wemos и других) эти пины уже подтянуты резисторами к нужному напряжению, поэтому нужно несколько раз подумать, что вы к ним подключаете и как оно повлияет на напряжение на пине. Например, можно подключить энкодер, он прижмёт системный пин к GND и esp не запустится.
- На GPIO16/D0 нельзя подключать прерывания ( attachInterrupt() ) и включать ШИМ сигнал ( analogWrite() ).
- Максимальный ток с GPIO – 12 мА.
- Светодиод LED_BUILTIN находится на пине GPIO2 и его поведение инвертировано: при подаче LOW он включается и наоборот.
- При старте контроллера почти все пины делают скачок до высокого уровня, подробнее – в этой статье. Единственными “спокойными” пинами являются D1 (GPIO5) и D2 (GPIO4). Если контроллер управляет напрямую какими-то железками (реле, транзистор, или является “кнопкой” для другого устройства), то лучше использовать именно эти пины!
- На этих же пинах сидит I2C, но шину можно переназначить на любые другие пины через Wire.begin(sda, scl) .
Особенности работы WiFi
WiFi реализован синхронно, его обработчик должен постоянно вызываться во время работы программы не реже, чем каждые 20 мс (если WiFi используется в программе). Обработка WiFi происходит в следующих местах:
- Автоматически в конце каждой итерации loop()
- Внутри любого delay()
- Внутри функции yield()
Если у вас есть участки программы, которые долго выполняются, то нужно разместить вызовы yield() до и после тяжёлых блоков кода. Также в чужих скетчах можно встретить delay(0) , по сути это и есть yield() .
По тем же причинам не рекомендуется использовать задержку delayMicroseconds() более чем на 20’000 мкс.
Отличия от AVR Arduino
Деление на 0
В отличие от AVR, деление на 0 приводит к критической ошибке и перезагрузке микроконтроллера. Стараемся этого избегать.
min() и max()
В ядре esp8266 функции min() и max() реализованы как функции, а не как макросы, поэтому должны использоваться с данными одного типа. Использование переменных разного типа приведёт к ошибке компиляции.
map()
В функции map(val, min, max, to min, to max) нет защиты от деления на 0, поэтому если min равен max – микроконтроллер зависнет и перезагрузится. Если min и max задаются какими-то внешними условиями – проверяйте их равенство вручную и исключайте вызов map() с такими аргументами.
Типы данных
- Тип int является синонимом long ( int32_t ) и занимает 4 байта. В AVR int это int16_t , то есть 2 байта.
- Тип char является синонимом byte – принимает значения 0.. 255 в отличие от -128.. 127 в AVR.
- Тип double имеет полную двойную точность – 8 байт. В AVR это 4 байта.
- Указатель занимает 4 байта, так как область памяти тут 32-битная. В AVR – 2 байта.
Функция analogRead()
ESP8266 имеет крайне убогий одноканальный АЦП.
- Сам АЦП в esp8266 может измерять напряжение в диапазоне 0.. 1.0V. На платах (NodeMCU, Wemos Mini) стоит делитель напряжения, который расширяет диапазон до более удобных 3.3V.
- Разрешение – 10 бит, т. е. значения 0.. 1023 как на Arduino
- Частый вызов analogRead() замедляет работу WiFi. При вызовах чаще нескольких миллисекунд WiFi полностью перестаёт работать.
- Результат analogRead() имеет кеширование до 5 мс, то есть полученные данные могут запаздывать на это время.
- АЦП может использоваться для измерения напряжения питания МК: для этого нужно вызвать ADC_MODE(ADC_VCC); до void setup() , а само напряжение питания можно получить из ESP.getVcc() .
Функция analogWrite()
- Работает на всех пинах, кроме GPIO16.
- Разрядность ШИМ по умолчанию 8 бит (0.. 255) на версиях ядра 3.x. На ранних версиях – 10 бит (0.. 1023). Скажем спасибо индусам за совместимость.
- Разрядность можно настроить в analogWriteResolution(4. 16 бит) .
- Частоту можно настроить в analogWriteFreq(100.. 40000 Гц) .
Аппаратные прерывания
- Настраиваются точно так же, через attachInterrupt() .
- Работают на всех пинах, кроме GPIO16.
- Функция-обработчик должна быть объявлена с атрибутом IRAM_ATTR :
void setup() < attachInterrupt(1, myIsr, RISING); >IRAM_ATTR void myIsr()
void ICACHE_RAM_ATTR myIsr() < >void setup()Функция yield()
В реализации esp8266 функция yield() выполняет другую задачу и использовать её как на AVR не получится. Скажем спасибо индусам за совместимость
EEPROM
EEPROM в esp8266 является эмуляцией из Flash памяти, поэтому мы можем выбрать нужный размер.
- Перед началом работы нужно вызвать EEPROM.begin(4.. 4096) с указанием размера области памяти в байтах.
- Для применения изменений в памяти нужно вызвать EEPROM.commit() .
- В некоторых версиях SDK отсутствует EEPROM.update() и EEPROM.length() .
- У Flash памяти небольшой ресурс – всего около 10’000 перезаписей. У фирменной памяти Winbond (можно найти на некоторых моделях ESP-12 и прочих) – около 50’000 перезаписей.
В остальном работа с библиотекой EEPROM.h ничем не отличается.
Важно: EEPROM реализован следующим образом: после запуска EEPROM.begin(4.. 4096) содержимое EEPROM указанного размера дублируется в оперативной памяти. После любого изменения и вызова EEPROM.commit() стирается весь блок Flash памяти (4 кБ) и записывается заново. Таким образом ресурс “EEPROM” памяти у ESP вырабатывается довольно быстро и весь сразу, а не по ячейкам.
Serial (UART)
- В отличие от реализации для AVR, можно изменить размер буфера на приём: Serial.setRxBufferSize(размер) в байтах. Вызывать перед Serial.begin() , по умолчанию 256 байт.
- Можно настроить работу только на приём или только на отправку для освобождения пина: Serial.begin(скорость, SERIAL_8N1, режим) , где режим:
- SERIAL_TX_ONLY – только отправка
- SERIAL_RX_ONLY – только приём
- SERIAL_FULL – приём и отправка (по умолчанию)
Полезные страницы
- Набор GyverKIT – большой стартовый набор Arduino моей разработки, продаётся в России
- Каталог ссылок на дешёвые Ардуины, датчики, модули и прочие железки с AliExpress у проверенных продавцов
- Подборка библиотек для Arduino, самых интересных и полезных, официальных и не очень
- Полная документация по языку Ардуино, все встроенные функции и макросы, все доступные типы данных
- Сборник полезных алгоритмов для написания скетчей: структура кода, таймеры, фильтры, парсинг данных
- Видео уроки по программированию Arduino с канала “Заметки Ардуинщика” – одни из самых подробных в рунете
- Поддержать автора за работу над уроками
- Обратная связь – сообщить об ошибке в уроке или предложить дополнение по тексту ([email protected])