View Categories

ESP8266

ESP8266 - китайский микроконтроллер с большим объемом памяти и WiFi связью на борту (SoM на картинке справа). Популярные платы на его основе: Wemos D1 mini (слева), NodeMCU (по центру).

Wemos mini #

Плата Wemos D1 mini является лучшим вариантом для знакомства с МК ESP8266 - недорогая, компактная и удобная в работе на макетке. Существует несколько вариантов исполнения и их версий, в принципе они все хорошие и рекомендуются к покупке:

Информация #

Документация:

Купить Wemos mini:

Wemos mini идёт в нашем наборе GyverKIT в версиях GyverKIT PRO и GyverKIT IOT

Характеристики #

Характеристика Значение
Микроконтроллер Espressif ESP8266
Логический уровень 3.3V
Напряжение питания 2.2.. 3.6V
Через стабилизатор (Wemos) 4.5.. 5.5V
Через стабилизатор (NodeMCU) 5.. 15V
Макс. ток с пина 12 mA
Ток потребления 300 mA при запуске и передаче данных, 35 mA во время работы, 80 mA в режиме точки доступа
Режимы энергосбережения Modem sleep (15 mA), Light sleep (0.4 mA), Deep sleep (15 uA)
Частота тактирования 80/160 MHz
Flash 1.. 16 MB внешняя
RAM 82 kB (доступно около 52 kB)
EEPROM Эмуляция из Flash
GPIO 14 (доступно 11)
ADC 10 bit 1 канал
ШИМ пины 10
Аппаратные интерфейсы 1x SPI, 1x I2S, 1.5x UART, WiFi

Аппаратного I2C нет, есть встроенный программный

Распиновка #

Особенности пинов #

У esp8266 много системных пинов, с которыми нужно быть очень внимательным:

  • К нескольким пинам подключена внешняя Flash память, в общем случае их использовать нельзя (если очень нужно - ищите информацию). На плате NodeMCU визуально гораздо больше пинов, чем на Wemos Mini, но по факту "безопасных" для использования пинов там ровно столько же. У Wemos эти пины не выведены на плату
  • Светодиод LED_BUILTIN находится на пине GPIO2 и его поведение инвертировано: при подаче LOW он включается и наоборот
  • На GPIO16 нельзя подключать прерывания attachInterrupt() и включать ШИМ сигнал analogWrite()
  • GPIO0 управляет режимом запуска МК (старт или режим прошивки)
  • При старте контроллера почти все пины делают скачок до высокого уровня, подробнее - в этой статье. Единственными "спокойными" пинами являются D1 (GPIO5) и D2 (GPIO4). Если контроллер управляет напрямую какими-то железками (реле, транзистор, или является "кнопкой" для другого устройства), то лучше использовать именно эти пины! На этих же пинах сидит I2C, но шину можно переназначить на любые другие пины
  • С оставшимися пинами тоже не всё гладко: некоторые из них требуют наличия определенного логического уровня на момент включения МК (подача питания, перезагрузка). Если к этим пинам подключить что-то, дающее противоположный сигнал - esp не запустится. На распиновке у таких пинов указан и зачёркнут сигнал, который нельзя подавать при запуске
Пин Нельзя
D8 (GPIO15) HIGH
D4 (GPIO2) LOW
TX (GPIO1) LOW

К этим пинам можно подключать внешние железки, но с пониманием того, какой сигнал они дадут на пин. Например, можно подключить энкодер, он прижмёт системный пин к GND и esp не запустится

Нумерация пинов #

У самого чипа esp8266 все выводы пронумерованы цифрами. На распиновке они подписаны как GPIOn, где n - номер GPIO. На плате (NodeMCU, Wemos Mini) пины подписаны как Dn и эти номера не совпадают с номерами GPIO! При работе например с Wemos можно использовать как нумерацию выводов GPIO - digitalWrite(5, LOW), так и D-нумерацию пинов на плате - digitalWrite(D1, LOW), если выбрана плата Wemos. Новички очень часто в этом путаются, будьте внимательны. Также GPIO1 и GPIO3 подписаны на плате как TX и RX, по этим названиям к ним тоже можно обращаться - digitalWrite(TX, LOW).

Аналоговый пин один, к нему можно обращаться как analogRead(0).

Особенности #

WiFi #

WiFi реализован синхронно, его обработчик должен постоянно вызываться во время работы программы не реже, чем каждые 20 мс (если WiFi используется в программе). Обработка WiFi происходит в следующих местах:

  • После выхода из loop()
  • Внутри delay()
  • Внутри yield()

Поэтому:

  • Нужно вызывать delay(0)/yield() до и после тяжёлых блоков кода и/или внутри них
  • Нужно обязательно вызывать delay(0)/yield() в глухих циклах ожидания
  • Не рекомендуется использовать задержку delayMicroseconds() более чем на 20 000 мкс
while (some_condition) {
    // ...
    delay(0);
}
yield();
тяжёлая_функция();
yield();

Если этого не делать - МК перезагрузится с ошибкой WDT reset

Деление на 0 #

В отличие от AVR, деление на 0 приводит к критической ошибке и перезагрузке микроконтроллера. Стараемся этого избегать.

min() и max() #

В ядре esp8266 функции min() и max() реализованы как функции, а не как макросы, поэтому должны использоваться с данными одного типа. Использование переменных разного типа приведёт к ошибке компиляции:

unsigned long v;
v = max(v, 123);    // ошибка
v = max(v, 123ul);  // ОК

map() #

В функции map(val, min, max, to_min, to_max) нет защиты от деления на 0, поэтому если min равен max - микроконтроллер зависнет и перезагрузится. Если min и max задаются какими-то внешними условиями - проверяйте их равенство вручную и исключайте вызов map() с такими аргументами.

Типы данных #

  • int - 32 битный
  • double - 64 битный
  • Указатель - 32 битный

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
  • ШИМ реализован программно, поэтому на повышенной частоте и разрядности будет тормозить выполнение программы
  • Частота по умолчанию 1 кГц
    • Частоту можно настроить в analogWriteFreq(100.. 40000 Гц)
  • Разрядность по умолчанию 8 бит (0.. 255) на версиях ядра 3.x. На ранних версиях - 10 бит (0.. 1023)
    • Разрядность можно настроить в analogWriteResolution(4...16 бит)

Аппаратные прерывания #

  • Работают на всех пинах, кроме GPIO16
  • В обработчике нельзя использовать динамическое выделение и перераспределение памяти (new, malloc, realloc), соответственно менять String-строки тоже нельзя
  • В прерывании нельзя использовать задержки
  • Функция-обработчик должна быть объявлена с атрибутом IRAM_ATTR:
IRAM_ATTR void myIsr() {}

void setup() {
    attachInterrupt(1, myIsr, RISING);
}

Либо с ICACHE_RAM_ATTR (на старых версиях ядра):

void ICACHE_RAM_ATTR myIsr() {}

void setup() {
    attachInterrupt(1, myIsr, RISING);
}

EEPROM #

EEPROM в esp8266 является эмуляцией из Flash памяти, поэтому мы можем выбрать нужный размер:

  • Перед началом работы нужно вызвать EEPROM.begin(4.. 4096) с указанием размера области памяти в байтах
  • Для применения изменений в памяти нужно вызвать EEPROM.commit()
  • В некоторых версиях SDK отсутствует EEPROM.update() и EEPROM.length()
  • У Flash памяти небольшой ресурс - всего около 10'000 перезаписей. У фирменной памяти Winbond (можно найти на некоторых моделях ESP-12 и прочих) - около 50'000 перезаписей

Важно: EEPROM реализован следующим образом: после запуска EEPROM.begin(4.. 4096) содержимое EEPROM указанного размера дублируется в оперативной памяти. После любого изменения и вызова EEPROM.commit() стирается весь блок Flash памяти (4 кБ) и записывается заново. Таким образом ресурс "EEPROM" памяти у ESP вырабатывается довольно быстро и весь сразу, а не по ячейкам.

Вместо EEPROM используйте библиотеку FileData для удобного хранения любых данных в файловой системе

Serial (UART) #

  • В отличие от реализации для AVR, можно изменить размер буфера на приём: Serial.setRxBufferSize(размер) в байтах. Вызывать перед Serial.begin(), по умолчанию 256 байт
  • Можно настроить работу только на приём или только на отправку для освобождения пина: Serial.begin(скорость, SERIAL_8N1, mode), где mode:
    • SERIAL_TX_ONLY - только отправка
    • SERIAL_RX_ONLY - только приём
    • SERIAL_FULL - приём и отправка (по умолчанию)
  • Можно перенести Serial на другие пины при помощи Serial.swap(), вызывать после Serial.begin(). Пины переместятся на GPIO15/D8 (TX) и GPIO13/D7 (RX). Если вызвать ещё раз - переместятся обратно на GPIO1 (TX) и GPIO3 (RX) и так по кругу
  • У esp8266 есть второй аппаратный UART, но его приёмная нога (RX) занята одним из пинов для работы с памятью и не выведена на плате Wemos Mini. Нога TX находится на GPIO2/D4, то есть можно работать только на отправку, но на практике и это может пригодиться. В программе просто работаем с объектом Serial1, настроив его только на отправку

При перезагрузке ESP8266 отправляет в UART информацию о перезапуске на скорости 74880, что при другой скорости монитора выглядит как набор битых символов

Начало работы #

  • Ссылка для менеджера плат: https://arduino.esp8266.com/stable/package_esp8266com_index.json
  • Для платы Wemos mini выбираем LOLIN(WEMOS) D1 R2 & mini
  • Для работы с любой платой (даже самодельной) можно выбрать Generic esp8266, будет доступен полный набор настроек

Параметры #

  • 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)
  • Flash mode: режим загрузки во Flash память
    • DOUT: медленный, но совместим со всеми модификациями esp8266
    • QIO: более быстрый, но будет работать не на всех чипах
  • Erase Flash: режим очистки памяти
    • Only Sketch: стереть только программу
    • Sketch + WiFi Settings: стереть программу и настройки WiFi (логин-пароль последнего подключения и т.д.)
    • All Flash Contents: полностью очистить память

platformio.ini #

[env:d1_mini]
platform = espressif8266
board = d1_mini
framework = arduino
monitor_speed = 115200
upload_speed = 921600
monitor_filters = esp8266_exception_decoder, default
build_type = debug
board_build.filesystem = littlefs
lib_deps =
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
Прокрутить вверх