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

Особенности работы WiFi


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

  • Автоматически в конце каждой итерации loop()
  • Внутри любого delay()
  • Внутри функции yield()

Если у вас есть участки программы, которые долго выполняются, то нужно разместить вызовы yield() до и после тяжёлых блоков кода. Также в чужих скетчах можно встретить delay(0), по сути это и есть yield().

По тем же причинам не рекомендуется использовать задержку delayMicroseconds() более чем на 20’000 мкс.

Отличия от AVR Arduino

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 байта.
  • Тип double имеет полную двойную точность – 8 байт. В AVR это 4 байта.
  • Указатель занимает 4 байта, так как область памяти тут 32-битная. В AVR – 2 байта.

Функция analogRead()


ESP8266 имеет крайне убогий одноканальный АЦП.

  • Сам АЦП в esp8266 может измерять напряжение в диапазоне 0.. 1.0V. На платах (NodeMCU, Wemos Mini) стоит делитель напряжения, который расширяет диапазон до более удобных 3.3V.
  • Частый вызов 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 бит).
  • Частота ШИМ по умолчанию 1 кГц.
    • Частоту можно настроить в analogWriteFreq(100.. 40000 Гц).
  • ШИМ реализован программно, поэтому на повышенной частоте и разрядности будет тормозить выполнение программы!

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


  • Настраиваются точно так же, через attachInterrupt().
  • Работают на всех пинах, кроме GPIO16.
  • Функция-обработчик должна быть объявлена с атрибутом IRAM_ATTR:
    void setup() {
      attachInterrupt(1, myIsr, RISING);
    }
    
    IRAM_ATTR void myIsr() {
    }

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

    void ICACHE_RAM_ATTR myIsr() {
    }
    
    void setup() {
      attachInterrupt(1, myIsr, RISING);
    }
  • В обработчике нельзя использовать динамическое выделение и перераспределение памяти (new, malloc, realloc), соответственно менять String-строки тоже нельзя.
  • В прерывании нельзя использовать задержки.

Функция yield()


В реализации esp8266 функция yield() выполняет другую задачу и использовать её как на AVR не получится. Скажем спасибо индусам за совместимость

EEPROM


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

  • Перед началом работы нужно вызвать EEPROM.begin(4.. 4096) с указанием размера области памяти в байтах.
  • Для применения изменений в памяти нужно вызвать EEPROM.commit().

В остальном работа с библиотекой EEPROM.h ничем не отличается.

Serial (UART)


  • В отличие от реализации для AVR, можно изменить размер буфера на приём: Serial.setRxBufferSize(размер) в байтах. Вызывать перед Serial.begin(), по умолчанию 256 байт.
  • Можно настроить работу только на приём или только на отправку для освобождения пина: Serial.begin(скорость, SERIAL_8N1, режим), где режим:
    • 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, настроив его только на отправку.

Полезные страницы


  • Набор GyverKIT – большой стартовый набор Arduino моей разработки, продаётся в России
  • Каталог ссылок на дешёвые Ардуины, датчики, модули и прочие железки с AliExpress у проверенных продавцов
  • Подборка библиотек для Arduino, самых интересных и полезных, официальных и не очень
  • Полная документация по языку Ардуино, все встроенные функции и макросы, все доступные типы данных
  • Сборник полезных алгоритмов для написания скетчей: структура кода, таймеры, фильтры, парсинг данных
  • Видео уроки по программированию Arduino с канала “Заметки Ардуинщика” – одни из самых подробных в рунете
  • Поддержать автора за работу над уроками
  • Обратная связь – сообщить об ошибке в уроке или предложить дополнение по тексту (alex@alexgyver.ru)
5/5 - (35 голосов)
Вперёд Digispark. Начало работы, особенности
Подписаться
Уведомить о
guest
19 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии