ESP8266:Модули/Платой ESP8266 Thing

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

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



Руководство по работе с прототипной платой ESP8266 Thing[1]

За последнее время ESP8266 стал самой настоящей звездой проектов, связанных с WiFi и интернетом вещей. Это очень недорогой WiFi-модуль, который (нужно лишь немного повозиться) можно программировать, как и любой другой микроконтроллер. Однако ESP8266 поставляется, как правило, в маленьком, модульном виде, а также с неудобной распиновкой и ограниченным количеством GPIO-контактов, поэтому его бывает сложно использовать для разработки проектов.

Оригинальный WiFi-модуль ESP8266; удобно подключать поверх Arduino, не очень удобно использовать в других проектах

Поэтому компания SparkFun разработала прототипную плату Thing, у которой выведены все доступные контакты чипа ESP8266, а также имеются USB-коннектор, разъем для питания от литий-полимерной батареи и прочие компоненты, упрощающие разработку проектов. Как пишут разработчики, название «Thing» (т.е. «вещь») не случайно, т.к. эта плата предназначена в первую очередь для проектов в сфере интернета вещей (англ. «internet of things»).

Необходимые компоненты

Для этого руководства понадобятся следующие инструменты и материалы:

  • Плата SparkFun ESP8266 Thing
  • Два гребешка с 10 контактами (с одной стороны – длинные штырьковые контакты, с другой – контакты-отверстия)
  • USB-кабель SparkFun Cerebrus
  • Конвертерная 3,3-вольтовая плата SparkFun FTDI
  • Литий-ионная батарея на 850 мА

Описание

Плата SparkFun ESP8266 Thing устроена относительно просто. Контакты чипа ESP8266 выведены на два параллельных ряда, расположенных по бокам платы. Эти ряды совместимы с контактами стандартной макетной платы.

Коннекторы для USB и литий-полимерной батареи находятся в верхней части Thing и служат для питания платы. Этими коннекторами можно управлять при помощи переключателя ONN/OFF, находящегося в правом верхнем углу платы. Светодиоды расположены чуть ниже коннекторов и служат индикаторами питания, зарядки и статуса Thing.

Вот небольшая схема, демонстрирующая главные элементы SparkFun ESP8266 Thing:

Распиновка

IO-контакты ESP8266 Thing можно разбить на три секции.

Контакты для последовательной коммуникации

Этот 6-контактный участок будет главным связующим звеном между Thing и компьютером. Эти контакты соответствуют контактам широко распространенного «гребешка FTDI». Другими словами, их можно подключить к 3-вольтовой плате FTDI или 3,3-вольтовому кабелю FTDI, чтобы с их помощью программировать и настраивать Thing.

Описание этих контактов смотрите в таблице ниже. Если контакт напрямую привязан к GPIO-контакту ESP8266, это будет указано во втором столбце.

Название контакта GPIO-контакт ESP8266 Примечания
DTR Выполняет автоматический сброс и переводит ESP8266 в режим загрузчика. Через конденсатор подключен к RESET, а также к буферу 0-ого GPIO-контакта ESP8266.
TXO 7 Контакт для вывода данных шины UART1 на ESP8266
RXI 8 Контакт для ввода данных шины UART1 на ESP8266
3V3 По умолчанию этот контакт не обеспечивает ESP8266 питанием напрямую (это можно изменить при помощи перемычки на задней стороне платы)
NC Ни к чему не подключен
GND Заземление (0 вольт)

Контакты для интерфейса I2C

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

Название контакта GPIO-контакт ESP8266 Примечания
GND Заземление (0 вольт)
3V3 3,3 вольта
SDA 2 Может использоваться либо как 2-ой GPIO-контакт ESP8266, либо как контакт для передачи данных шины I2C (SDA).
SCL 14 Может использовать либо как 14-ый GPIO-контакт ESP8266, либо как контакт для тактового сигнала шины I2C (SCL). Также используется для тактового сигнала шины SPI (SCLK).

Распиновка этих контактов соответствует распиновке большинства плат SparkFun, использующих шину I2C, так что вы можете смело подключать их поверх Thing.

Если вашему проекту понадобятся дополнительные GPIO-контакты, то контакты SDA и SCL можно использовать в качестве 2-ого и 14-ого GPIO-контактов. Контакт SCL также служит для передачи тактового сигнала (SCLK) шины SPI у ESP8266.

GPIO-контакты

Оставшиеся GPIO-контакты, а также контакты для управления и питания выведены на третью секцию, расположенную на другой стороне платы.

Название контакта GPIO-контакт ESP8266 Примечания
GND Заземление (0 вольт)
VIN
  • При подключении по USB: около 4,5 вольт.
  • При подключении от батареи: около 3,7 вольт.
  • Когда ничего не подключено: можно использовать в качестве входного контакта, подающего напряжение на 3,3-вольтовый регулятор.
5 5
0 0
4 4
13 13 Контакт MOSI для аппаратного SPI
12 12 Контакт MISO для аппаратного SPI
XPD 16 Можно подключить к RST, чтобы перевести ESP8266 в режим глубокого сна
ADC A0 10-битный АЦП (максимальное напряжение – 1 вольт)
EN Контакт для управления ESP8266. Если подать HIGH, чип включится, а если LOW – выключится. По умолчанию притянут к HIGH.

Куда делись остальные GPIO-контакты ESP8266? Почему такая странная распиновка? К сожалению, большинство остальных GPIO-контактов ESP8266 подключены к SPI-памяти чипа, где хранится его программная память и прочие данные.

Обратная сторона Thing

На задней стороне Thing находится несколько перемычек и тестовых контактов.

Перемычки

Название перемычки Настройка по умолчанию Примечания
DTR Закрыта Позволяет выполнить автоматический сброс при программировании ESP8266, но затрудняет передачу отладочных данных по последовательному порту
I2C PU Закрыта Подключает к контактам SDA и SCL подтягивающие резисторы на 10 кОм
FTDI VCC Открыта Подключает контакт 3V3, находящийся на участке для последовательной коммуникации, напрямую к 3,3-вольтовому питанию ESP8266

Перемычку DTR вам, скорее всего, придется переключать чаще всего. На 3,3-вольтовой плате FTDI (к примеру, SparkFun выпускает модель FTDI Basic Breakout - 3.3V) эта перемычка используется для двух целей: для сброса ESP8266 и для того, чтобы притянуть контакт GPIO0 к значению LOW (это переведет чип в режим загрузчика). Будучи закрытой, эта перемычка позволяет программировать Thing, но затрудняет отладку при помощи монитора порта, потому что при каждом открытии терминала плата будет переключаться в режим загрузчика. Более подробно об использовании перемычки DTR можно прочесть ниже, в разделе «Использование монитора порта IDE Arduino».

Перемычка FTDI VCC по умолчанию открыта. Это предотвращает случайную подачу на плату 5-вольтового напряжения в ситуации, если для программирования Thing используется кабель FTDI с 3,3-вольтовой логикой, но 5-вольтовым питанием. Кроме того, большинство 3,3-вольтовых плат FTDI не способны обеспечить достаточным питанием 3,3-вольтовую шину Thing (они выдают, как правило, не более 50 мА).

Тестовые контакты

Это 6 контактов, которые сгруппированы вместе и подключены к flash-памяти SPI-чипа ESP8266. Ими можно воспользоваться, если вам понадобятся дополнительные GPIO-контакты или, к примеру, если вы захотите просто поэкспериментировать.

Но более полезным, скорее всего, будет контакт RST. Как пишут разработчики, на лицевой стороне Thing для него не хватило места, из-за чего его поместили на заднюю сторону. Контакт RST через конденсатор на 0,1 мкФ подключен к контакту DTR – чтобы у вас была возможность выполнять автоматический сброс во время программирования. Контактом DTR можно пользоваться всегда, когда вашему проекту понадобится контакт RST. К примеру, если ESP8266 нужно перевести в режим глубокого сна.

Выбор антенны

По умолчанию Thing использует печатную WiFi-антенну, встроенную в плату. Она, как пишут разработчики, недорогая и очень неплохо работает.

Но к Thing можно подключить и более чувствительную антенну. Для этого плата оснащена коннектором U.FL, но он по умолчанию не подключен к антенному контакту ESP8266. Чтобы подключить его, вам нужно нагреть 0-омовый резистор, показанный на картинке ниже, и повернуть его на 90°.

Резистор, переставленный с печатной антенны на антенну, подключенную к коннектору U.FL

Для выполнения этой задачи понадобятся паяльник, щипчики, а также по паре прямых рук и зорких глаз!

Для чего предназначены пустые участки?

Изначально Thing задумывалась как сенсорная станция с повышенным уровнем безопасности. Именно поэтому на ней имеются пустые посадочные площадки, предназначенные для следующих компонентов:

  • ATECC108A – это микросхема аутентификации с алгоритмом генерации цифровой подписи на базе эллиптических кривых (от англ. «Elliptic Curve Digital Signature Algorithm» или просто «ECDSA»). Ее можно использовать для генерации уникальных серийных номеров, хеширования, хранения ключей или случайных чисел. Этот компонент позволяет сделать ваш проект более защищенным
  • [ww.sparkfun.com/products/13314 TMP102] – это простой 12-битный цифровой температурный датчик
  • TSL2561 – это датчик освещения

Кроме того, на Thing имеется несколько посадочных мест для развязывающих конденсаторов.

Разработчики признаются, что на определенном этапе разработки решили сделать плату как можно дешевле (именно этим, в конце концов, и хорош ESP8266), но оставив возможности для дальнейшего расширения.

Поэтому, если вы пожелаете оснастить Thing дополнительным функционалом, то контактные площадки к вашим услугам. Для работы вам понадобятся лишь термовоздушная паяльная станция (вроде этой) и щипчики.

Питание

Плату Thing можно питать двумя способами – от USB или от литий-полимерной батареи. Тип USB-коннектора Thing – это Micro-B. USB-кабель, идущий от Thing, можно подключить либо к USB-порту компьютера, либо к настенному 5-вольтовому адаптеру.

Если вы хотите запитать Thing от литий-полимерной батареи, то можно воспользоваться, к примеру, одноэлементной литий-полимерной батареей от той же SparkFun – она, как и Thing, тоже оснащена 2-контактным коннектором JST.

Плата Thing, к которой подключены литий-полимерная батарея на 850 мА и датчик движения LSM9DS0

Если к Thing подключена и батарея, и USB-кабель, то питание будет идти от USB, а батарея начнет заряжаться (максимальный заряд – 500 мА).

Электрические характеристики

Максимальное напряжение для ESP8266 – это 3,6 вольта. Поэтому, чтобы на Thing поступало стабильное и безопасное напряжение, она оснащена 3,3-вольтовым регулятором. Это значит, что GPIO-контакты ESP8266 тоже работают на 3,3 вольтах, поэтому любые 5-вольтовые сигналы, идущие к плате, нужно конвертировать в 3,3-вольтовую логику.

Входное напряжение на встроенный регулятор может быть подано тремя способами: через USB, от литий-полимерной батареи и через контакт VIN.

Примечание: Если напряжение подается на плату через контакт VIN, оно не должно превышать 6 вольт. Это максимально допустимое напряжение для встроенного 3,3-вольтового регулятора AP2112K.

Впрочем, если вы располагаете стабильным внешним источником питания, то плату можно питать и через контакт 3V3 (он находится на участке с контактами для шины SPI). Этому напряжению не обязательно быть 3,3-вольтовым – оно может быть в диапазоне от 1,7 до 3,6 вольт.

Сила тока

В среднем Thing потребляет около 80 мА, но при приеме и отправке WiFi-сигнала эта цифра может моментально увеличиться. Ниже таблица из даташита ESP8266, описывающая самые распространенные ситуации энергопотребления:

Параметр Тип. сила тока Макс. сила тока Единица измерения
Передача 802.11b (1 Мбит/с) 215 мА
Передача 802.11b (11 Мбит/с) 197 мА
Передача 802.11g (54 Мбит/с) 145 мА
Передача 802.11n 135 мА
Передача 802.11b 60 мА
Передача 802.11g 60 мА
Передача 802.11n 62 мА
Режим ожидания 0,9 мА
Режим глубокого сна 10 мкА
Макс. выходная сила тока на одном IO-контакте 12 мА

Если ваш проект питается от батареи, и вы хотите, чтобы она проработала как можно дольше, почаще пользуйтесь режимом глубокого сна. Более подробно об этом смотрите ниже, в разделе «Скетч-пример: Спокойной ночи, Thing (режим глубокого сна)».

Программирование

В чип ESP8266 уже встроен загрузчик, что упрощает не только первое, но и все последующие программирования. Другими словами, чтобы запрограммировать плату, вам уже не понадобится дорогой внешний программатор – достаточно будет простого конвертера USB-Serial.

Для этих целей подойдет, к примеру, 3.3-вольтовая плата FTDI, а также плата FTDI SmartBasic, кабель FTDI или плата FT231X.

Примечание: Во время программирования Thing лучше питать от USB. Наш опыт показывает, что при питании от батареи запрограммировать плату, как правило, не получается. 6-контактный гребешок 3,3-вольтовой платы FTDI точно соответствует 6-контактному последовательному порту Thing. Чтобы настроить Thing на программирование, просто подключите их друг к другу. Убедитесь, что контакты DTR и GND совпадают!

Плата ESP8266 Thing, к которой подключен USB-кабель и 3,3-вольтовая плата FTDI

Пайка программного интерфейса

Перед тем, как программировать Thing, к ней нужно припаять программный интерфейс. Каким он будет – зависит от особенностей проекта и удобства подключения к компьютеру, через который будет осуществляться программирование.

Можно воспользоваться, к примеру, 10-контактными «этажерочными» гребешками. Они могут пригодиться для подключения к макетной плате или подсоединения проводов-перемычек.

Кроме того, вы вольны свободно экспериментировать с разными видами контактов. Гребешок с контактами, загнутыми под прямым углом, пригодится для создания программного интерфейса между платой FTDI и Thing. Гребешок с прямыми контактами типа «папа» идеален для низкопрофильных подключений. Гребешок с прямыми контактами типа «мама» пригодится для подключения к датчикам, использующим шину I2C. И, разумеется, к любому контакту можно просто припаять провод – для случаев, когда необходимый компонент находится далеко от Thing.

Если вы припаяли хотя бы программный порт, то Thing готова к загрузке кода!

Установка аддона ESP8266 в IDE Arduino

Есть разные среды разработки, которые можно использовать для программирования ESP8266. Можно воспользоваться GCC, средой разработки Eclipse, виртуальной машиной от самой Espressif или даже собственной разработкой.

Но теперь, благодаря аддону ESP8266 для IDE Arduino, этот выбор стал чуть шире. Если вы новичок в программировании ESP8266, то лучше начать именно с этой программы. Данное руководство, в частности, тоже написано на примере использования IDE Arduino.

Аддон ESP8266 для IDE Arduino разработан Иваном Грохотковым и другими участниками сообщества ESP8266. Более подробно смотрите в GitHub-репозитории аддона.

Установка аддона при помощи менеджера библиотек IDE Arduino

С выходом версии 1.6.4 добавлять сторонние аддоны в IDE Arduino стало проще – благодаря новому менеджеру библиотек. Поэтому, если вы продолжаете пользоваться старой версией IDE Arduino (1.6.3 или старше), настоятельно рекомендуем обновиться. Как и всегда, последнюю версию IDE Arduino можно скачать отсюда.

Сначала нужно добавить в менеджер библиотек URL к аддону. Для этого откройте IDE Arduino и кликните на Файл > Настройки (File > Preferences). В открывшемся окне найдите поле Дополнительные ссылки для менеджера плат (Additional Boards Manager URLs). Скопируйте в него вот этот URL:

http://arduino.esp8266.com/stable/package_esp8266com_index.json

Если в этом поле уже есть какие-то URL, и вы хотите их сохранить, то несколько URL’ов можно отделить друг от друга при помощи запятой. (В IDE Arduino версии 1.6.5 справа от этого поля добавлена новая кнопка, при нажатии на которую открывается меню, упрощающее добавление нескольких URL).

Нажмите на «OK». Затем откройте Менеджер плат, кликнув в IDE Arduino на Инструменты > Плата > Менеджер плат... (Tools > Board > Boards Manager…). В этом меню, помимо стандартных плат Arduino, должно быть несколько новых пунктов. Ищите пункт «esp8266», а затем кликните по нему и нажмите Установка (Install).

Инструменты и код для ESP8266 содержат новые версии gcc, g++ и прочее, так что скачиваемые данные могут быть довольно увесистыми (около 110 Мб). На их загрузку и установку может потребоваться несколько минут. Когда установка будет завершена, рядом с надписью «esp8266» появится голубая надпись INSTALLED.

Выбор платы ESP8266 Thing

Теперь, когда аддон для ESP8266 установлен, осталось лишь выбрать пункт «ESP8266 Thing» в меню Инструменты > Плата (Tools > Board).

Затем кликните по Инструменты > Порт (Tools > Port) и выберите номер порта, к которому подключена Thing.

Проверка скетчем «Blink»

Чтобы проверить, что все настроено правильно, попробуйте загрузить в IDE Arduino старый добрый скетч «Blink». Но вместо 13-ого контакта задайте 5-ый – именно к нему подключен светодиод, встроенный в Thing.

#define ESP8266_LED 5

void setup() 
{
  pinMode(ESP8266_LED, OUTPUT);
}

void loop() 
{
  digitalWrite(ESP8266_LED, HIGH);
  delay(500);
  digitalWrite(ESP8266_LED, LOW);
  delay(500);
}

Если загрузить скетч не удалось, сначала проверьте, включена ли Thing – на плате должен гореть красный светодиод «PWR».

Примечание: Загрузку скетча можно ускорить! По умолчанию скорость загрузки выставлена на 115200 бит/сек, и это стабильная скорость, но некоторым она может показаться медленной. Впрочем, ее можно увеличить в 8 раз, кликнув в IDE Arduino на Инструменты > Upload Speed (Tools > Upload Speed), а затем выбрав пункт «921600».

Эта скорость слегка нестабильна, но сэкономит вам кучу времени!

В esptool по-прежнему страдает от пары неприятных багов, поэтому скетч не всегда загружается с первого раза. Если у вас вообще не получается загрузить скетч, попробуйте выключить и снова включить Thing, или отключить и снова включить интерфейс FTDI. Если скетч не удается загрузить и после этих действий, вот по этой ссылке можно связаться со службой поддержки SparkFun.

Скетч-пример: Публикация в Phant

Главной целью разработки ESP8266 Thing было создание платформы для взаимодействия с data.sparkfun.com – бесплатным сервисом хранения онлайн-данных компании SparkFun.

В этом разделе рассказывается о скетче-примере, который просто публикует четыре значения в тестовый поток SparkFun. Можете пользоваться этим потоком в любое время, когда вам нужно будет проверить, работает ли Thing (но не злоупотребляйте!).

Сначала установите библиотеку «Phant». Она нужна, чтобы максимально упростить сборку POST-запросов к Phant. Библиотеку «Phant» можно установить при помощи Менеджера библиотек, имеющегося в IDE Arduino. Чтобы открыть его, кликните в IDE Arduino на Скетч > Подключить библиотеку > Управлять библиотеками... (Sketch > Include Library > Manage Libraries...). Затем введите в поиске слово «phant» и установите последнюю версию библиотеки или как минимум версию 2.2.0.

Кроме того, библиотеку «Phant» можно скачать с этого GitHub-репозитория, а затем установить, следуя инструкциям в этой статье.

Теперь скопируйте в IDE Arduino код, показанный ниже, или загрузите его по этой ссылке.

Перед загрузкой кода на ESP8266 убедитесь, что поменяли значения в константах WiFiSSD и WiFiPSK – в них нужно указать название вашей WiFi-сети и пароль к ней. Оставшуюся часть скетча можно оставить без изменений.

// подключаем библиотеку «ESP8266 WiFi»
// (она во многом похожа на библиотеку «Arduino WiFi»:
#include <ESP8266WiFi.h>
// подключаем библиотеку «Phant» от SparkFun:
#include <Phant.h>

//////////////////////
// Настройки WiFi ////
//////////////////////
const char WiFiSSID[] = "WiFi_Network";
const char WiFiPSK[] = "WiFi_Password";

/////////////////////////
// Настройки контактов //
/////////////////////////
const int LED_PIN = 5;      // контакт для зеленого светодиода,
                            // встроенного в Thing
const int ANALOG_PIN = A0;  // единственный аналоговый контакт Thing
const int DIGITAL_PIN = 12; // цифровой контакт, с которого 
                            // будем считывать данные

/////////////////
// Ключи Phant //
/////////////////
const char PhantHost[] = "data.sparkfun.com";
const char PublicKey[] = "wpvZ9pE1qbFJAjaGd3bn";
const char PrivateKey[] = "wzeB1z0xWNt1YJX27xdg";

//////////////////////////////////////
// Настройки для интервала публикации //
//////////////////////////////////////
const unsigned long postRate = 30000;
unsigned long lastPost = 0;

void setup() 
{
  initHardware();
  connectWiFi();
  digitalWrite(LED_PIN, HIGH);
}

void loop() 
{
  if (lastPost + postRate <= millis())
  {
    if (postToPhant())
      lastPost = millis();
    else
      delay(100);    
  }
}

void connectWiFi()
{
  byte ledStatus = LOW;

  // переключаем Thing в стационарный режим (доступны еще два режима:
  // режим точки доступа и стационарный режим + режим точки доступа):
  WiFi.mode(WIFI_STA);

  // эта функция инициализирует WiFi-соединение;
  // аргумент «ssid» – это WiFi-сеть, к которой нужно подключиться,
  // а аргумент «passkey» – это пароль; типом шифрования 
  // может быть WPA, WPA2 или WEP: 
  WiFi.begin(WiFiSSID, WiFiPSK);

  // эта функция проверяет, подключен ли ESP8266 к WiFi-сети:
  while (WiFi.status() != WL_CONNECTED)
  {
    // мигаем светодиодом:
    digitalWrite(LED_PIN, ledStatus); // задаем значение HIGH или LOW
    ledStatus = (ledStatus == HIGH) ? LOW : HIGH;

    // эта задержка позволяет ESP8266 выполнить критически важные
    // задачи, заданные вне этого скетча – настройку 
    // и обеспечение WiFi-соединения:
    delay(100);
    // потенциально бесконечные циклы – это очень опасно, 
    // поэтому как можно чаще добавляйте задержки;
    // это позволит процессору выполнять другие задачи
  }
}

void initHardware()
{
  Serial.begin(9600);
  pinMode(DIGITAL_PIN, INPUT_PULLUP);
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);
  // контакт ANALOG_PIN не нужно выставлять в режим ввода данных,
  // потому что это единственный возможный режим для этого контакта
}

int postToPhant()
{
  // при входе в Phant светодиод включится,
  // а в конце скетча, при успешной публикации – выключится: 
  digitalWrite(LED_PIN, HIGH);

  // создаем объект библиотеки «Phant» – phant:
  Phant phant(PhantHost, PublicKey, PrivateKey);

  // немного кода, чтобы создать уникальное название;
  // берем «Thing-» и добавляем последние два байта MAC-адреса:
  uint8_t mac[WL_MAC_ADDR_LENGTH];
  WiFi.macAddress(mac);
  String macID = String(mac[WL_MAC_ADDR_LENGTH - 2], HEX) +
                 String(mac[WL_MAC_ADDR_LENGTH - 1], HEX);
  macID.toUpperCase();
  String postedID = "Thing-" + macID;

  // добавляем четыре поля/значения, заданные нашим потоком:
  phant.add("id", postedID);
  phant.add("analog", analogRead(ANALOG_PIN));
  phant.add("digital", digitalRead(DIGITAL_PIN));
  phant.add("time", millis());

  // подключаемся к data.sparkfun.com и постим данные:
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(PhantHost, httpPort)) 
  {
    // если подключиться не удалось, возвращаем «0»:
    return 0;
  }
  // если подключение выполнено успешно, печатаем публикацию в Phant:
  client.print(phant.post());

  // считываем все строчки ответа от сервера
  // и печатаем их в мониторе порта:
  while(client.available()){
    String line = client.readStringUntil('\r');
    //Serial.print(line);
  }

  // перед выходом выключаем светодиод:
  digitalWrite(LED_PIN, LOW);

  return 1; // возвращаем «1», что значит «задача выполнено успешно»
}

Код запустится сразу после загрузки на Thing, после чего моргнет (с частотой около 2 Гц) статусный светодиод, подключенный к 5-ому контакту. Когда Thing подключится к WiFi-сети, загорится зеленый светодиод, после чего данные будут опубликованы в тестовый поток. После публикации зеленый светодиод потухнет, а затем будет мигать с частотой 1 раз в 30 секунд – когда Thing будет постить данные в Phant.

Если этот светодиод вообще не мигает, это значит, что у Thing проблемы с подключением к WiFi-сети. Убедитесь, что вписали правильные данные в константы WiFiSSD и WiFiPSK.

Четыре значения, которые Thing публикует в Phant – это данные с контакта ADC, цифровые данные с 12-ого контакта, идентификатор Thing (слово «Thing», к которому добавлены последние два байта MAC-адреса) и время, считанное функцией millis(). Теперь откройте тестовый поток, чтобы увидеть там собственную Thing.

Скриншот тестового потока data.sparkfun.com

Подробнее о том, что происходит в скетче, читайте в комментариях к коду.

Скетч-пример: Веб-сервер, работающий в режиме точки доступа

Чип ESP8266 способен не только подключаться к WiFi-сети и через нее взаимодействовать с интернетом, но и сам быть WiFi-сетью, к которой могут подключаться другие устройства. Данный скетч-пример демонстрирует, как превратить ESP8266 в точку доступа, хранящую веб-страницы и по запросу отправляющую их подключенным клиентам.

Скопируйте код, показанный ниже, в IDE Arduino. Или загрузите его отсюда.

#include <ESP8266WiFi.h>

//////////////////////
// Настройки WiFi ////
//////////////////////
const char WiFiAPPSK[] = "sparkfun";

/////////////////////////
// Настройки контактов //
/////////////////////////
const int LED_PIN = 5;      // контакт для зеленого светодиода,
                            // подключенного к Thing
const int ANALOG_PIN = A0;  // единственный аналоговый контакт Thing 
const int DIGITAL_PIN = 12; // цифровой контакт, с которого 
                            // надо прочесть данные 

WiFiServer server(80);

void setup() 
{
  initHardware();
  setupWiFi();
  server.begin();
}

void loop() 
{
  // проверяем, подключился ли клиент:
  WiFiClient client = server.available();
  if (!client) {
    return;
  }

  // считываем первую строчку запроса:
  String req = client.readStringUntil('\r');
  Serial.println(req);
  client.flush();

  // проверяем, корректен ли запрос:
  int val = -1; // переменная «val» будет использоваться 
                // для отслеживания типа запроса (считывание/запись) 
                // и значения (если оно задано)
  if (req.indexOf("/led/0") != -1)
    val = 0; // задает светодиоду значение LOW
  else if (req.indexOf("/led/1") != -1)
    val = 1; // задает светодиоду значение HIGH
  else if (req.indexOf("/read") != -1)
    val = -2; // печатает данные, считанные с контакта
  // если в «val» будет другое значение, запрос 
  // будет признан некорректным; 
  // подробнее смотрите в секции с HTML

  // задаем значение контакта GPIO5 согласно данным из запроса:
  if (val >= 0)
    digitalWrite(LED_PIN, val);

  client.flush();

  // подготавливаем ответ; начинаем с обычного заголовка:
  String s = "HTTP/1.1 200 OK\r\n";
  s += "Content-Type: text/html\r\n\r\n";
  s += "<!DOCTYPE HTML>\r\n<html>\r\n";
  // если поменяли значение светодиода, сообщаем об этом:
  if (val >= 0)
  {
    s += "LED is now ";  //  "Светодиод теперь "
    s += (val)?"on":"off";  //  "включен":"выключен"
  }
  else if (val == -2)
  { // если прочитали значения контактов, печатаем их:
    s += "Analog Pin = ";  //  "Аналоговый контакт = "
    s += String(analogRead(ANALOG_PIN));
    s += "<br>"; // переходим к следующей строчке
    s += "Digital Pin 12 = ";  //  "Цифровой контакт 12 = "
    s += String(digitalRead(DIGITAL_PIN));
  }
  else
  {
    s += "Invalid Request.<br> Try /led/1, /led/0, or /read.";
     //  "Некорректный запрос"
  }
  s += "</html>\n";

  // отправляем ответ клиенту:
  client.print(s);
  delay(1);
  Serial.println("Client disonnected");  //  "Клиент отключился"

  // когда эта функция вернет свое значение, клиент будет отключен,
  // а объект «client» - удален
}

void setupWiFi()
{
  WiFi.mode(WIFI_AP);

  // небольшой фрагмент кода, создающий уникальное имя для Thing;
  // просто прибавляем к «Thing-» два последних байта MAC-адреса:
  uint8_t mac[WL_MAC_ADDR_LENGTH];
  WiFi.softAPmacAddress(mac);
  String macID = String(mac[WL_MAC_ADDR_LENGTH - 2], HEX) +
                 String(mac[WL_MAC_ADDR_LENGTH - 1], HEX);
  macID.toUpperCase();
  String AP_NameString = "ESP8266 Thing " + macID;

  char AP_NameChar[AP_NameString.length() + 1];
  memset(AP_NameChar, 0, AP_NameString.length() + 1);

  for (int i=0; i<AP_NameString.length(); i++)
    AP_NameChar[i] = AP_NameString.charAt(i);

  WiFi.softAP(AP_NameChar, WiFiAPPSK);
}

void initHardware()
{
  Serial.begin(115200);
  pinMode(DIGITAL_PIN, INPUT_PULLUP);
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);
  // контакт ANALOG_PIN не нужно выставлять в режим вывода данных;
  // это единственный режим, в котором он умеет работать
}

Этот скетч сделает паролем WiFi-сети «sparkfun».

Подключившись к WiFi-сети на базе Thing, загрузите браузер и откройте ссылку «192.168.4.1/read». Откроется страница, показывающая данные, считанные с аналогового контакта и цифрового контакта 12. Это значит, что все настроено правильно – ваша Thing работает как веб-сервер.


После этого попробуйте ввести в браузер ссылки «192.168.4.1/led/0» и «192.168.4.1/led/1», попутно следя за зеленым светодиодом Thing.

Как и всегда, подробнее об устройстве скетча можно узнать в комментариях к коду.

Скетч-пример: Спокойной ночи, Thing! (спящий режим)

Одна из уникальных функций Thing – это встроенная поддержка литий-полимерных батарей. Но, к сожалению, ESP8266 все еще достаточно прожорлив. Если вы хотите, чтобы ваш проект проработал на батарее дольше нескольких часов, у вас есть два варианта: обзавестись ОГРОМНОЙ батареей или просто переключить Thing в спящий режим.

Чтобы перевести плату в спящий режим, нужно подключить контакт XPD на Thing к контакту RST на ESP8266. Контакт RST на плату Thing не выведен, но в нашем случае достаточно будет и контакта DTR.

Соединяем контакт XPD с контактом DTR, чтобы включить функцию спящего режима

Осторожно! Чип ESP8266 нельзя будет программировать, когда контакты XPD и DTR подключены друг к другу. Поэтому перед загрузкой скетча убедитесь, что разъединили их.

После того, как вы прикажете ESP8266 перейти в спящий режим, чип подождет заданное количество микросекунд, а затем активирует контакт XPD, чтобы переключить линию RST. Когда ESP8266 «проснется», то начнет с самого начала скетча.

Теперь давайте возьмем скетч с постингом в Phant, о котором рассказывалось выше, и добавим в него функцию переключения в спящий режим. Это должно значительно увеличить срок работы батареи. Код показан ниже, но вы также можете скачать его отсюда.

Опять же, не забудьте отредактировать значения в константах WiFiSSID и WiFiPSK. Они находятся в самом верху скетча.

// подключаем библиотеку «ESP8266 WiFi»
// (она во многом похожа на библиотеку «Arduino WiFi»:
#include <ESP8266WiFi.h>
// подключаем библиотеку «Phant» от SparkFun:
#include <Phant.h>

//////////////////////
// Настройки WiFi ////
//////////////////////
const char WiFiSSID[] = "WiFi_Network";
const char WiFiPSK[] = "WiFi_Password";

/////////////////////////
// Настройки контактов //
/////////////////////////
const int LED_PIN = 5;      // контакт для зеленого светодиода,
                            // встроенного в Thing
const int ANALOG_PIN = A0;  // единственный аналоговый контакт Thing
const int DIGITAL_PIN = 12; // цифровой контакт, с которого 
                            // будем считывать данные

/////////////////
// Ключи Phant //
/////////////////
const char PhantHost[] = "data.sparkfun.com";
const char PublicKey[] = "wpvZ9pE1qbFJAjaGd3bn";
const char PrivateKey[] = "wzeB1z0xWNt1YJX27xdg";

// время сна (в секундах):
const int sleepTimeS = 30;

void setup() 
{
  initHardware();
  connectWiFi();
  digitalWrite(LED_PIN, HIGH);
  while (postToPhant() != 1)
  {
    delay(100);
  }
  digitalWrite(LED_PIN, LOW);
  // время сна задано в микросекундах, 
  // поэтому умножаем секунды на 1000000:
  ESP.deepSleep(sleepTimeS * 1000000);
}

void loop() 
{
}

void connectWiFi()
{
  byte ledStatus = LOW;

  // переключаем ESP8266 в стационарный режим; кроме того,
  // ESP8266 можно переключить в режим точки доступа
  // и комбинированный режим (стационарный + точка доступа):
  WiFi.mode(WIFI_STA);

  // эта функция инициализирует WiFi-соединение;
  // аргумент «ssid» – это WiFi-сеть, к которой нужно подключиться,
  // а аргумент «passkey» – это пароль; типом шифрования
  // может быть WPA, WPA2 или WEP: 
  WiFi.begin(WiFiSSID, WiFiPSK);

  // эта функция проверяет, подключен ли ESP8266 к WiFi-сети:
  while (WiFi.status() != WL_CONNECTED)
  {
    // мигаем светодиодом:
    digitalWrite(LED_PIN, ledStatus); // задаем значение HIGH или LOW
    ledStatus = (ledStatus == HIGH) ? LOW : HIGH;

    // эта задержка позволяет ESP8266 выполнить критически важные
    // задачи, заданные вне этого скетча – настройку
    // и обеспечение WiFi-соединения:
    delay(100);
    // потенциально бесконечные циклы – это опасно, 
    // поэтому как можно чаще добавляйте задержки;
    // это позволит процессору выполнять другие задачи
  }
}

void initHardware()
{
  Serial.begin(9600);
  pinMode(DIGITAL_PIN, INPUT_PULLUP);
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);
  // контакт ANALOG_PIN не нужно выставлять в режим ввода данных,
  // потому что это единственный возможный режим для этого контакта
}

int postToPhant()
{
  // при входе в Phant светодиод включится,
  // а в конце скетча, при успешной публикации – выключится: 
  digitalWrite(LED_PIN, HIGH);

  // создаем объект библиотеки «Phant» – phant:
  Phant phant(PhantHost, PublicKey, PrivateKey);

  // немного кода, чтобы создать уникальное название;
  // берем «Thing-» и добавляем последние два байта MAC-адреса:
  uint8_t mac[WL_MAC_ADDR_LENGTH];
  WiFi.macAddress(mac);
  String macID = String(mac[WL_MAC_ADDR_LENGTH - 2], HEX) +
                 String(mac[WL_MAC_ADDR_LENGTH - 1], HEX);
  macID.toUpperCase();
  String postedID = "Thing-" + macID;

  // добавляем четыре поля/значения, заданные нашим потоком:
  phant.add("id", postedID);
  phant.add("analog", analogRead(ANALOG_PIN));
  phant.add("digital", digitalRead(DIGITAL_PIN));
  phant.add("time", millis());

  // подключаемся к data.sparkfun.com и постим данные:
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(PhantHost, httpPort)) 
  {
    // если подключиться не удалось, возвращаем «0»:
    return 0;
  }
  // если подключение выполнено успешно, печатаем публикацию в Phant:
  client.print(phant.post());

  // считываем все строчки ответа от сервера
  // и печатаем их в мониторе порта:
  while(client.available()){
    String line = client.readStringUntil('\r');
    //Serial.print(line);
  }

  // перед выходом выключаем светодиод:
  digitalWrite(LED_PIN, LOW);

  return 1; // возвращаем «1», что значит «задача выполнено успешно»
}

Этот скетч выполняет ту же задачу, что и скетч «Публикация в Phant» - постит данные в поток data.sparkfun.com каждые 30 секунд. Но между этими скетчами есть и большая разница – режим сна.

Обратите внимание, что в блоке loop() ничего нет. После вызова функции ESP.deepSleep(30000000) программа ставится на паузу. Но спустя 30 секунд, когда ESP8266 «просыпается», код снова начинает работать – начиная с блока setup().

Если мультиметром измерить ток, который тянет Thing, мы увидим примерно 80 мА, и так будет продолжаться около 5 секунд, пока Thing будет подключаться и постить данные на Phant. Затем, после переключения в режим сна, Thing будет тянуть всего 8 мА, а среднем в секунду – около 18 мА.

В режиме глубокого сна Thing тянет всего 8 мА, большая часть которых уходит на светодиод

Большая часть силы тока, которую тянет Thing, идет на питание светодиодного индикатора. Поэтому, если вы хотите, чтобы Thing требовала еще меньше питания, этот светодиод можно просто снять или даже обрезать ведущую к нему трассу (подсказка: это трасса, бегущая по букве «R» в надписи «PWR»).

Использование аддона ESP8266 для IDE Arduino

Программирование ESP8266 устроено немного иначе, чем программирование Arduino. Поэтому, если вы привыкли использовать Arduino, придется немного переучиться.

Распиновка

Как и у плат Arduino, номера контактов Thing, на которых можно осуществлять запись и считывание данных, напечатаны прямо на плате. Контакты SDA и SCL – это контакты 2 и 14.

Thing оснащена лишь одним аналоговым контактом, и это ADC. Чтобы считывать данные с этого контакта, используйте функцию analogRead(A0). Учтите, что у этого контакта странное ограничение напряжения – оно не должно превышать 1 вольт. Диапазон значений – 10-битный, т.е. вы можете считывать значения от «0» до «1023», пропорциональные диапазону от 0 до 1 вольта.

Функция yield()

Между чипом ESP8266 и более традиционными микроконтроллерами Arduino есть одно важное отличие. ESP8266 фоном выполняет очень много вспомогательных функций – поддерживает связь по WiFi, управляет стеком TCP/IP и т.д. Если заблокировать эти функции, ESP8266 может сброситься или даже крашнуться. Чтобы избежать этих загадочных крашей и «ресетов», не допускайте в скетче больших, блокирующих циклов.

Если в вашем скетче блок loop() получился слишком длинным, в нем можно вызвать функцию delay() – чтобы во время задержки ESP8266 мог выполнить свои фоновые функции.

Кроме того, разработчики библиотек для ESP8266 придумали замечательную функцию yield(), которая как раз вызывает фоновые функции, чтобы они сделали то, что им нужно. К примеру, если ваш скетч ждет, пока пользователь нажмет на кнопку, подключенную к 12-ому контакту, то избежать краша ESP8266 позволит примерно такой цикл:

pinMode(12, INPUT_PULLUP);            // выставляем контакт 12
                                      // в режим ввода данных, 
                                      // а также включаем у него 
                                      // подтягивающий резистор
while (digitalRead(12) == HIGH)       // пока контакт 12 находится
                                      // в состоянии HIGH
                                      // (т.е. не активирован)...
yield();                              // (почти) ничего не делаем – даем ESP8266 
                                      // возможность выполнить фоновые функции
Serial.println("Button is pressed!"); // печатаем сообщение о том,
                                      // что кнопка нажата

Класс ESP8266WiFi

Поскольку это ESP8266, класс для WiFi будет присутствовать почти в каждом скетче. Если вы раньше уже пользовались библиотекой WiFi для Arduino, то класс ESP8266WiFi покажется вам очень знакомым. Но у версии для ESP8266 есть и несколько отличий:

  • Чтобы подключить библиотеку ESP8266WiFi, в скетче нужно вписать #include <ESP8266WiFi.h>, а не #include <WiFi.h>
  • Чтобы подключиться к сети, нужна та же функция, что и при использовании «нормальной» WiFi-библиотеки, т.е. WiFi.begin(NetworkSSID, NetworkPassword). Кроме того, вы можете настроить ESP8266 на режим точки доступа при помощи функции WiFi.softAP(AP_SSID, AP_Password)
  • У класса ESP8266WiFi есть еще одна функция, позволяющая переключать ESP8266 в разные режимы работы с WiFi. Это WiFi.setMode([mode]), и с ее помощью чип можно выставить в стационарный режим (для этого в аргументе нужно указать WIFI_STA), в режим точки доступа (WIFI_AP) и в комбинированный режим (стационарный + точка доступа; WIFI_STA_AP).

Все эти различия демонстрируются в трех скетчах-примерах выше.

Библиотеки Arduino, переписанные под ESP8266

В сети нашлись умельцы, адаптировавшие библиотеки Arduino под работу с чипом ESP8266. Например...

Wire

Благодаря этой библиотеке ESP8266 должен работать со всеми I2C-датчиками, подключенными к его контактам. Используйте те же функции, к которым привыкли при работе с Arduino. Впрочем, есть и небольшое отличие:

  • У чипа ESP8266 нет аппаратных I2C-контактов. Разработчики просто взяли 2-ой и 14-ый контакты и решили сделать их SDA и SCL по умолчанию. То есть, если вызвать функцию Wire.begin(), то она будет работать именно со 2-ым и 14-ым контактами. Но, по сути, вы можете использовать в качестве SDA и SCL любые контакты Thing при помощи функции Wire.begin([SDA], [SCL])

SPI

Плата ESP8266 Thing может управлять шиной SPI при помощи тех же функций, что и SPI. Но между версиями для ESP8266 и Arduino тоже есть небольшие отличия:

  • В версию для ESP8266 добавлена новая функция – SPI.setFrequency([frequency]). С ее помощью можно задать тактовую частоту шины SPI. Она может понадобится, к примеру, если вы хотите немного замедлить тактовый сигнал. Так, функция SPI.setFrequency(1000000) переключит тактовую частоту шины SPI на 1 МГц.
  • Контакты MISO, MOSI, SCLK и CS жестко привязаны к контактам 12, 13, 14 и 15 соответственно. Другими словами, переместить их на другие контакты нельзя.
Номер контакта SPI функция
12 MISO
13 MOSI
14 (SCL) SCLK
15 CS

Использование монитора порта

Контакт GPIO0 можно использовать как обычный цифровой контакт для ввода/вывода данных, но у него есть и другая функция – он используется для переключения между режимами загрузчика и работы скетча. Другими словами, во время запуска ESP8266 «смотрит» на значение контакта GPIO0, чтобы понять, нужно ли ей переключиться в режим загрузчика или запустить уже загруженную программу:

Значение контакта GPIO0 Режим работы ESP8266
HIGH (3,3 вольта) Запуск программы
LOW (0 вольт) Запуск загрузчика

Чтобы упростить программирование ESP8266, контакт GPIO0 привязан к линии DTR (а также к RST). Когда программатор начинает загружать скетч, он переводит DTR в состояние LOW (и контакт GPIO0 – тоже), благодаря чему ESP8266 переходит в режим загрузчика.

К сожалению, когда вы открываете монитор порта, DTR снова переходит в состояние LOW. Таким образом, при каждом открытии монитора порта IDE Arduino чип ESP8266 переходит в режим загрузчика, а не в режим работы программы. Если вы открыли монитор порта и увидели там какой-то информационный мусор, то это значит, что ESP8266, возможно, запустился в режиме загрузчика.

Эту проблему можно обойти двумя способами.

Во-первых, на задней стороне платы есть перемычка DTR. Вы можете обрезать трассу и установить на нее гребешок с 2 контактами типа «папа», совмещенный с 2-контактной перемычкой. В результате, если перемычка будет стоять, плату можно будет программировать, а если убрать, это позволит плате работать в режиме передачи данных на монитор порта.

Во-вторых, можно найти консольную программу, позволяющую напрямую управлять контактом DTR. Для этих целей подойдет, к примеру, RealTerm – откройте вкладку Pins, а затем нажмите на кнопку Clear, которая находится в секции DTR.

К сожалению, это единственная найденная нами программа, которая решает эту проблему, и она доступна только для Windows.

Дополнительные материалы

Вокруг ESP8266 выросло потрясающее сообщество. В частности, в его недрах родился аддон ESP8266 для IDE Arduino. Поэтому, если у вас возникнут какие-то вопросы, настоятельно рекомендуем посетить форум esp8266.com. Но, помимо этого форума, в сети есть и другие полезные ресурсы, посвященные ESP8266:

Плата ESP8266 Thing – это устройство с открытым кодом. Если хотите, то на GitHub-репозитории ESP8266 можно посмотреть на файлы печатной платы.

Что дальше

Теперь, когда вы настроили свою ESP8266 Thing, можно попробовать сделать какой-нибудь проект! Подчерпнуть вдохновения можно ниже, в руководствах от SparkFun:

См.также

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