ESP8266:Прошивки/Arduino/Справочник по функциям аддона ESP8266 для IDE Arduino

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

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


Черновик


Справочник по функциям аддона ESP8266 для IDE Arduino[1]

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

Аддон ESP8266 для IDE Arduino напрямую привязывает номера контактов Arduino к номерам GPIO-контактов ESP8266. В результате функции pinMode(), digitalRead() и digitalWrite() работают как обычно. То есть, чтобы прочесть данные с контакта GPIO2, используйте функцию digitalRead(2).

Контакты с 0 по 15 можно перевести в режимы INPUT, OUTPUT и INPUT_PULLUP. Контакт 16 можно перевести в режимы INPUT, OUTPUT и INPUT_PULLDOWN16. При запуске платы контакты настроены на режим INPUT.

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

Функции контактов ESP-12

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

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

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

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

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

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

Чтобы прочесть VCC-напряжение, используйте функцию ESP.getVcc(). При этом контакт ADC должен быть ни к чему не подключен. Кроме того, в скетч нужно добавить вот такую строчку:

ADC_MODE(ADC_VCC);

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

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

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

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

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

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

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

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

Последовательная коммуникация

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

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

Объект Serial1 использует шину UART1, TX-контактом которой является GPIO2. Шину UART1 нельзя использовать для приема данных, потому что ее контакт RX обычно занимается коммуникацией с flash-памятью.

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

Если Serial1 не используется, а Serial не переназначен на другие контакты, контакт TX шины UART0 можно переназначить на контакт GPIO2. Для этого вызовите функцию Serial.begin(), а затем Serial.set_tx(2). Или можно сделать это напрямую – при помощи функции Serial.begin(baud, config, mode, 2).

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

Функция Serial.setDebugOutput(true) также нужна, чтобы включить вывод данных от функции printf().

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

Кроме того, для обоих объектов доступна новая функция, позволяющая узнать скорость передачи данных (бодрейт). Выглядит она так – Serial.baudRate() или Serial1.baudRate(). Для хранения возвращаемого значения воспользуйтесь типом данных int. К примеру...

// задаем скорость передачи данных на 57600 бод:
Serial.begin(57600);

// извлекаем данные о текущей скорости:
int br = Serial.baudRate();

// печатаем "Serial is 57600 bps", то есть
// «скорость передачи данных на Serial – 57600 бит/с»:
Serial.printf("Serial is %d bps", br);

Я также сделал запрос на включение этой функции в библиотеку EspSoftwareSerial (это версия SoftwareSerial для ESP8266).

Обратите внимание, что эта функция совместима только с платами на базе ESP8266, но не с платами Arduino.

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);
}

См.также

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