ESP8266:Прошивки/Arduino/Архив/Справочник по Arduino-аддону для ESP8266

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску

Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.



Это старая версия статьи, она больше не будет обновляться.

Справочник по Arduino-аддону для ESP8266[1]

Цифровые контакты ввода/вывода

Благодаря аддону номера контактов ESP8266 полностью соответствуют номерам контактов Arduino. В результате функции pinMode(), digitalRead() и digitalWrite() работают как обычно. К примеру, чтобы прочитать данные с контакта GPIO2, нужно будет просто вызвать функцию digitalRead(2).

Цифровые контакты с 0 по 15 могут быть выставлены в режим INPUT, OUTPUT или INPUT_PULLUP. Контакт 16 может быть выставлен в режим INPUT, OUTPUT или INPUT_PULLDOWN_16. После запуска ESP8266 все контакты по умолчанию выставлены в режим INPUT.

Контакты могут служить и для других функций – например, для передачи данных по последовательному порту или по интерфейсам I2C и SPI. Эти функции, как правило, активируются при помощи соответствующих библиотек. К примеру, на картинке ниже показана распиновка популярного модуля ESP-12.

Контакты с 6 по 11 используются для подключения к flash-памяти чипа. Поэтому, если использовать их в качестве контактов ввода/вывода, ваша программа, скорее всего, крашнется.

Впрочем, на некоторых платах и модулях (например, на ESP-12ED и NodeMCU 1.0) контакты 9 и 11 можно использовать в качестве контактов ввода/вывода, но только в том случае, если flash-память чипа работает в режиме DIO (вместо QIO, который используется по умолчанию).

Кроме того, аддон поддерживает прерывания, которыми можно пользоваться при помощи функций attachInterrupt() и detachInterrupt(). Прерывания можно использовать на всех GPIO-контактах, за исключением GPIO16. Аддон поддерживает стандартные типы прерываний Arduino: CHANGE, RISING и FALLING.

Ввод аналоговых данных

У чипа ESP8266 есть один доступный АЦП-канал (контакт ADC). Его можно использовать либо для считывания внешнего напряжения, идущего на контакт ADC, либо для считывания напряжения самого модуля (VCC).

Чтобы прочесть внешнее напряжение, используйте функцию analogRead(A0). Диапазон входного напряжения – от 0 до 1 вольта.

Чтобы прочесть VCC-напряжение, контакт ADC должен остаться неподключенным. Также в код нужно будет добавить вот такую строчку:

ADC_MODE(ADC_VCC);

Эта строчка должна быть расположена вне функций. К примеру, сразу после блока с директивами #include.

Вывод аналоговых данных

При помощи функции analogWrite(pin, value) можно использовать ШИМ на заданном контакте. ШИМ можно использовать на контактах с 0 по 16, и нужный контакт указывается у функции analogWrite() в аргументе pin. Значение в аргументе value может варьироваться от «0» до PWMRANGE, которое по умолчанию составляет «1023». Диапазон ШИМ можно поменять при помощи функции analogWriteRange(new_range).

По умолчанию частота ШИМ составляет 1 КГц. Чтобы поменять частоту, воспользуйтесь функцией analogWriteFreq(new_frequency).

Синхронизация и задержки

Функции millis() и micros() возвращают количество миллисекунд и микросекунд, прошедших с последнего сброса.

Функция delay(ms) ставит скетч на паузу на указанное количество миллисекунд, позволяя выполнить задачи, связанные с WiFi и TCP/IP. Функция delayMicroseconds(us) ставит скетч на паузу на указанное количество микросекунд.

Помните, что при подключенном WiFi чипу нужно обработать очень много кода, находящегося за пределами самого скетча. Библиотеки для WiFi и TCP/IP получают возможность обработать незавершенные события при каждом прохождении блока loop() или при вызове функции delay(). Если в вашем скетче есть какой-нибудь слишком длинный цикл (т.е. занимающий более 50 мс), лучше добавить в него функцию delay() – чтобы работа WiFi-стека была более стабильной.

Есть также функция yield(), которая эквивалента delay(0). Учтите, впрочем, что функция delayMicroseconds() не переключает чип на выполнение другой задачи, поэтому использовать ее для задержек длиной более 20 мс не рекомендуется.

Объекты Serial и Serial1

Объект Serial работает примерно так же, как и на обычной Arduino. Помимо буфера FIFO (по 128 байт для RX и TX) порт HardwareSerial имеет дополнительные буферы TX и RX, и объем каждого составляет 256 байт. Обе линии (и для передачи, и для приема данных) управляются при помощи прерываний. Функции чтения и записи блокируют выполнение скетча только в том случае, если буферы/FIFO полны или пусты.

Объект Serial использует интерфейс UART0, работающий на контактах GPIO1 (TX) и GPIO3 (RX). Впрочем, воспользовавшись функцией Serial.begin(), а затем Serial.swap(), эту коммуникацию можно перенаправить на контакты GPIO15 (TX) и GPIO13 (RX). Если вызвать Serial.swap() еще раз, интерфейс UART0 снова передвинется на контакты GPIO1 (TX) и GPIO3 (RX).

Объект Serial1 использует интерфейс UART1, и его TX-контакт – это GPIO2. Интерфейс UART1 нельзя использовать для приема данных, поскольку его RX-контакт используется, как правило, для подключения к flash-памяти чипа. Объект Serial1 используется при помощи функции Serial1.begin(baudrate), где аргумент baudrate – это скорость передачи данных.

Если просто вызвать функцию Serial.begin(), то по умолчанию вывод отладочных данных, генерируемых WiFi-библиотеками, будет отключен. Чтобы включить его, вызовите функцию Serial.setDebugOutput(true). Чтобы перенаправить вывод отладочных данных на Serial1, вызовите Serial1.setDebugOutput(true).

Кроме того, чтобы активировать вывод данных от функции printf(), нужно будет вызвать функцию Serial.setDebugOutput(true).

Оба объекта (Serial и Serial1) поддерживают контакты для передачи данных 5, 6, 7 и 8, типы паритетных битов «odd» (или просто «O»; т.е. «нечетный»), «even» (или просто «E»; т.е. «четный») и «none» (или просто «N»; контроль четности не осуществляется), а также один или два стоп-бита. Чтобы задать нужный режим, можно вызвать, к примеру, функцию Serial.begin(baudrate, SERIAL_8N1), Serial.begin(baudrate, SERIAL_6E2) и пр. Аргумент baudrate здесь – это скорость передачи данных.

Память PROGMEM

Память PROGMEM в аддоне ESP8266 работает примерно так же, как и на обычной Arduino. То есть, это память только для чтения, куда мы помещаем данные (в том числе строковые) только для чтения, тем самым освобождая кучу свободного места для своего скетча. Но есть и неприятный момент – ESP8266 не позволяет объединять текстовые строки, и это значит, что даже одинаковые текстовые строки, используемые внутри F("") и/или PSTR(""), будут занимать в памяти отдельное место. Поэтому возней с повторяющимися строками придется заниматься самостоятельно.

В этом случае может помочь вспомогательный макрос FPSTR(), который упрощает передачу PROGMEM-строк типа const в функции, использующие тип данных __FlashStringHelper.

Вот так выглядит код с необъединенными строками:

String response1;
response1 += F("http:");
...
String response2;
response2 += F("http:");
А вот так, если воспользоваться макросом FPSTR():
const char HTTP[] PROGMEM = "http:";
...
{
    String response1;
    response1 += FPSTR(HTTP);
    ...
    String response2;
    response2 += FPSTR(HTTP);
}

Файловая система

Хотя файловая система, как и программа, тоже хранится в flash-памяти чипа, запись нового скетча не модифицирует содержимое файловой системы. Благодаря этому файловую систему можно использовать для хранения данных скетча, конфигурационных файлов или контента для веб-сервера.

График ниже демонстрирует разбивку flash-памяти, используемую в IDE Arduino:

|--------------|-------|---------------|--|--|--|--|--|
^              ^       ^               ^     ^
Скетч  OTA-апдейт   Файл. система   EEPROM   Конфиг для WiFi (SDK)

Размер файловой системы зависит от размера flash-памяти чипа. В зависимости от платы, которую использует IDE Arduino, эти размеры будут следующими:

Плата Размер flash-памяти чипа(в байтах) Размер файловой системы (в байтах)
Generic Module 512 Кб 64 Кб
Generic Module 1 Мб 64 Кб, 128 Кб, 256 Кб, 512 Кб
Generic Module 2 Мб 1 Мб
Generic Module 4 Мб 3 Мб
Adafruit HUZZAH 4 Мб 3 Мб
NodeMCU 0.9 4 Мб 3 Мб
NodeMCU 1.0 4 Мб 3 Мб
Olimex MOD-WIFI-ESP8266(-DEV) 2 Мб 1 Мб
SparkFun Thing 512 Кб 64 Кб
SweetPea ESP-210 4 Мб 3 Мб

Примечание: Чтобы использовать в скетче функции файловой системы, в него сначала нужно вписать следующее:

#include "FS.h"

Объект файловой системы (SPIFFS)

Функция SPIFFS.begin()

Устанавливает файловую систему SPIFFS. Ее нужно вызывать самой первой, т.е. до вызова всех остальных функций файловой системы. Если установка файловой системы прошла успешно, эта функция вернет значение true, а если нет – false.

Функция SPIFFS.open(path, mode)

Открывает указанный файл. Аргумент path – это полный путь, который начинается со слэша и выглядит примерно так: «/dir/filename.txt». Аргумент mode – это режим доступа к файловой системе. Здесь могут быть значения r, w, a, r+, w+ и a+. Это те же самые режимы, которые используются в функции fopen() языка C. Эта функция возвращает объект File.

Чтобы проверить, успешно ли был открыт файл, воспользуйтесь оператором if():

File f = SPIFFS.open("/f.txt", "w");
if (!f) {
    Serial.println("file open failed");
               //  "Открыть файл не удалось"
}

Функция SPIFFS.openDir(path)

Открывает директорию, находящуюся по указанному маршруту. Аргумент path – полный путь к директории. Возвращает объект Dir. Чтобы проверить, успешно ли была открыта директория, воспользуйтесь оператором if(), как в случае с функцией выше.

Функция SPIFFS.remove()

Удаляет файл, находящийся по указанному маршруту. Аргумент path – полный путь к файлу. Если файл был успешно удален, возвращает true.

Функция SPIFFS.rename()

Переименовывает файл с pathFrom в pathTo. Пути должны быть полными. Если файл был переименован успешно, возвращает true.

Объект директории (Dir)

Цель объекта Dir – перебор файлов, находящихся внутри директории. Этот объект используются с тремя функциями – next(), fileName() и openFile(). Фрагмент ниже демонстрирует, как правильно использовать все эти функции:

Dir dir = SPIFFS.openDir("/data");
while (dir.next()) {
    Serial.print(dir.fileName());
    File f = dir.openFile("r");
    Serial.println(f.size());
}

Функция dir.next() возвращает true, если в директории есть какие-то файлы. Ее нужно вызывать самой первой – до вызова функций fileName() и openFile().

Вместе с функцией openFile() используется аргумент mode, который выполняет ту же задачу, что и аргумент mode в функции SPIFFS.open().

Объект файла (File)

Функции SPIFFS() и dir.openFile() возвращают объект File. Этот объект поддерживает все функции класса Stream, включая readBytes(), findUntil(), parseInt(), println() и т.д. Но у объекта File есть и собственные функции.

Функция file.seek(offset, mode)

Работает аналогично функции fseek() языка C, т.е. ставит курсор в нужное место файла. Аргумент offset – это смещающее значение, а с помощью аргумента mode задается то, каким образом выполняется смещение:

  • Если в mode указано SeekSet, то смещение выполняется от начала файла
  • Если в mode указано SeekCur, то смещение выполняется от текущей позиции курсора
  • Если в mode указано SeekEnd, то смещение выполняется от конца файла.

Если позиция курсора была установлена успешно, возвращает true.

Функция file.position()

Возвращает текущую позицию внутри файла (в байтах).

Функция file.size()

Возвращает размер файла (в байтах).

Функция String name = file.name();

Возвращает название файла в виде const char*. Конвертирует в String для дальнейшего хранения.

Функция file.close()

Закрывает файл. После вызова этой функции с объектом File не должно выполняться никаких действий.

Библиотеки

WiFi (библиотека «ESP8266WiFi»)

Очень похожа на стандартную библиотеку WiFi для Arduino, но есть и отличия:

  • Функция WiFi.mode(m). В качестве аргумента можно выставить WIFI_AP, WIFI_STA, WIFI_AP_STA или WIFI_OFF
  • Чтобы создать открытую сеть, воспользуйтесь функцией WiFi.softAP(ssid)
  • Чтобы создать сеть с шифрованием WPA2-PSK, воспользуйтесь функцией WiFi.softAP(ssid, password). Пароль должен быть не менее 8 символов
  • Чтобы узнать MAC-адрес в стационарном режиме – WiFi.macAddress(mac), в режиме точки доступа – WiFi.softAPmacAddress(mac)
  • Чтобы узнать IP-адрес в стационарном режиме – WiFi.localIP(), в режиме точки доступа – WiFi.softAPIP()
  • Чтобы напечатать отладочную информацию, воспользуйтесь функцией WiFi.printDiag(Serial)
  • Класс WiFiUDP поддерживает отправку и получение многоадресных пакетов на интерфейс STA. При отправке многоадресного пакета замените udp.beginPacket(addr, port) на udp.beginPacketMulticast(addr, port, WiFi.localIP()). При прослушивании многоадресных пакетов замените udp.begin(port) на udp.beginMulticast(WiFi.localIP(), multicast_ip_addr, port). При помощи функции udp.destinationIP() можно узнать, был ли полученный пакет отправлен на несколько адресов или только на один.

Классы WiFiServer, WiFiClient и WiFiUDP работают примерно также, как и в библиотеке WiFi. В комплекте с библиотекой идет четыре скетча-примера. Более подробно о функциях можно почитать тут.

Библиотека Ticker

Эта библиотека предназначена для повторяющегося (на основе заданного интервала) вызова функций. В комплекте с библиотекой идут два скетча-примера.

В данный момент не рекомендуется использовать функции обратного вызова, имеющиеся в библиотеке Ticker, для выполнения блокирующих IO-команд (для работы с сетью, последовательной коммуникацией, файлами). Вместо этого поставьте флаг внутри функции обратного вызова Ticker, а затем проверяйте этот флаг внутри блока loop().

EEPROM

Класс EEPROM из аддона для ESP8266 немного отличается от стандартного класса EEPROM. Перед тем, как приступить к записи или считыванию данных, нужно вызвать функцию EEPROM.begin(size). Аргумент size – это количество байтов, которое вы хотите использовать (может быть в диапазоне от «4» до «4096»).

Функция EEPROM.write() не выполняет немедленную запись данных на flash-память, поэтому вместо нее лучше использовать EEPROM.commit(). Функция EEPROM.end() делает то же самое, что и EEPROM.commit(), но также удаляет из оперативной памяти данные, записанные на EEPROM.

Память EEPROM использует один сектор flash-памяти, расположенный по адресу 0x7b000.

В комплекте с библиотекой идут три скетча-примера.

Шина I2C (библиотека Wire)

В настоящий момент библиотека Wire поддерживает режим ведущего устройства с частотой до 450 КГц (примерно). Перед использованием I2C нужно задать контакты для линий SDA и SCL, и это делается при помощи функции Wire.begin(int sda, int scl). Таким образом, если вы работаете с модулем ESP-01, эта функция будет выглядеть Wire.begin(0, 2), а в других случаях для этих линий по умолчанию используются контакты 4 (SDA) и 5 (SCL).

Шина SPI

Библиотека SPI поддерживает почти все операции библиотеки SPI для IDE Arduino, включая настройку фазы тактового сигнала (CPHA). Настройка полярности тактового сигнала (CPOL) пока не поддерживается (не работают режимы SPI_MODE2 и SPI_MODE3).

Специальные функции для чипа ESP

Вы также можете использовать объект ESP, через который можно выполнять задачи, связанные с глубоким сном и сторожевым таймером. Они доступны только в альфа-версии.

  • Функция ESP.deepSleep(microseconds, mode)
    • Переключает чип в режим глубокого сна. Для аргумента mode допустимы значения WAKE_RF_DEFAULT, WAKE_RFCAL, WAKE_NO_RFCAL и WAKE_RF_DISABLED. Контакт GPIO16 должен быть привязан к RST – чтобы вывести чип из режима глубокого сна.
  • Функция ESP.restart()
    • Перезапускает процессор.
  • Функция ESP.getFreeHeap()
    • Возвращает размер свободной памяти.
  • Функция ESP.getChipId()
    • Возвращает ID чипа ESP8266 в виде целого 32-битного значения.

Кроме того, некоторые функции объекта ESP можно использовать для получения информации о flash-памяти чипа:

  • Функция ESP.getFlashChipId()
    • Возвращает ID flash-памяти чипа в виде целочисленного 32-битного значения.
  • Функция ESP.getFlashChipSize()
    • Возвращает размер flash-памяти чипа (в байтах), каким его видит SDK (может быть меньше настоящего размера).
  • Функция ESP.getFlashChipSpeed(void)
    • Возвращает частоту flash-памяти чипа (в Гц).
  • Функция ESP.getCycleCount()
    • Возвращает количество командных циклов процессора с момента запуска. Возвращаемое значение – беззнаковое 32-битное число. Эта функция полезна для точной синхронизации очень коротких действий вроде тех, что происходят при использовании техники «bit-banging».
  • Функция getVcc()
    • Может быть использована для измерения питающего напряжения. Для использования этой функции необходимо, чтобы чип ESP при запуске нужным образом настроил АЦП. Для этого в верхнюю часть скетча нужно добавить следующую строчку:
ADC_MODE(ADC_VCC);

При использовании этого режима контакт TOUT должен быть неподключенным.

Учтите, что по умолчанию АЦП настроен на считывание с контакта TOUT при помощи функции analogRead(A0), а функция ESP.getVCC() недоступна.

Библиотека OneWire

Мы адаптировали под ESP8266 библиотеку, которая описана здесь, добавив в OneWire.h данные о регистрах памяти. Обратите внимание, что если в папке библиотек IDE Arduino уже есть библиотека OneWire, то IDE Arduino будет использовать именно ее, а не ту, что идет в комплекте с аддоном для ESP8266.

Библиотека ESP8266mDNS (для запросов mDNS и DNS-SD)

Позволяет скетчу отвечать на многоадресные DNS-запросы с доменных имен вроде «foo.local», а также на запросы DNS-SD (от «service discovery», т.е. «обнаружение сервисов»). Более подробно смотрите в скетче-примере, который идет в комплекте с библиотекой.

Библиотека ESP8266SSDP (для запросов SSDP)

SSDP – это еще один протокол для обнаружения сервисов, который поддерживает Windows безо всяких дополнительных настроек. Более подробно смотрите в скетче-примере, который идет в комплекте с библиотекой.

Библиотека DNSServer (DNS-сервер)

Позволяет создать простой DNS-сервер, который можно использовать и в стационарном режиме, и в режиме точки доступа. В данный момент DNS-сервер поддерживает только один домен. Для всех прочих доменов ответом будет NXDOMAIN (от «non-existent domain», что значит «несуществующий домен») или какой-то другой ответ, который пользователь задал сам. С помощью библиотеки клиенты могут открыть веб-сервер, работающий на ESP8266, при помощи доменного имени, а не IP-адреса. Более подробно смотрите в скетче-примере, который идет в комплекте с библиотекой.

Библиотека Servo

Эта библиотека служит для работы с радиоуправляемыми сервоприводами. Она поддерживает до 24 сервоприводов на любом доступном выходном контакте. По умолчанию первые 12 сервоприводов будут использовать Timer0, и с другими задачами это никак конфликтовать не будет (по крайней мере, сейчас). Сервоприводы, идущие после 12-го, будут использовать Timer1, что может вступить в конфликт с другими задачами, которые тоже используют Timer1. Хотя существуют радиоуправляемые сервоприводы, которым будет достаточно 3,3 вольт, идущих от контакта ESP8266, большинству все же понадобится дополнительный источник питания, который будет удовлетворять их техническим требованиям.

Другие библиотеки (не идущие в комплекте с IDE Arduino)

Библиотеки, которые не используют низкоуровневый доступ к регистрам AVR, должны работать c ESP8266 очень хорошо. Вот несколько библиотек, уже доказавших стабильную работу:

  • arduinoWebSockets – сервер и клиент WebSocket, совместимые с ESP8266 (RFC6455)
  • aREST – библиотека для использования REST API на ESP8266 и Arduino
  • Blynk – простой IoT-фреймворк для мейкеров (подробнее смотрите на Kickstarter-странице)
  • DallasTemperature – библиотека для температурных датчиков DS18B20, MAX31820 и т.д.
  • DHT-sensor-library – библиотека Arduino для датчиков температуры/влажности DHT11/DHT22. Сразу загружайте последнюю версию (v1.1.1), и никаких настроек делать будет не нужно. В старых версиях объект DHT инициализируется следующим образом: DHT dht(DHTPIN, DHTTYPE, 15)
  • NeoPixel – библиотека от Adafruit, теперь с поддержкой ESP8266 (используйте версию 1.0.2 или выше из менеджера библиотек Arduino)
  • NeoPixelBus – библиотека Arduino NeoPixel, совместимая с ESP8266. Чтобы использовать цветовую модель HSL, используйте ветку «NeoPixelAnimator» для ESP8266.
  • PubSubClient – библиотека для протокола MQTT (от пользователя @Imroy)
  • RTC – библиотека Arduino для часов реального времени DS1307 и DS3231, совместимая с ESP8266
  • Souliss – фреймворк для использования технологий «умного дома» на Arduino, Android и openHAB
  • ST7735 – библиотека ST7735 от Adafruit, модифицированная для совместимости с ESP8266. В скетчах-примерах вписаны номера контактов для AVR, поэтому не забудьте поменять их на контакты для ESP8266.

См.также

Внешние ссылки