Выбрать главу

Важно: Как можно видеть в вышеприведенном коде, соединение с сетью WiFi происходит лишь в функции setup, которая активируется только один раз при включении платы. Соответственно, при перезагрузке маршрутизатора или потере WiFi-сигнала соединение не будет восстановлено. Чтобы этого избежать, нужно добавить в функцию loop проверку на необходимость восстановления коннекта.

while (WiFi.status() != WL_CONNECTED) {

delay(1000);

WiFi.begin(ssid, password);

}

Для наших тестовых программ это не требуется, но в реально действующем коде такая проверка необходима.

3.4 Подключаем дисплей

Мы уже подключали OLED-дисплей к Arduino, сделаем то же самое и для ESP32. Дисплей пригодится нам в следующих проектах, когда мы будем получать данные по WiFi из Интернет.

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

Нам нужны выводы GPIO21 и GPIO22, которые подписаны как I2C_SCL и I2C_SDA. Для тех кто забыл предыдущую часть, напомним что дисплей подключается по I2C и выглядит вот так:

Подключаем выводы дисплея к контактам 3.3V, GND, SCL и SDA. Этот дисплей может работать и от 5В и от 3.3В, так что здесь проблем нет. Затем скачиваем и устанавливаем библиотеки для OLED-дисплея по адресу https://github.com/ThingPulse/esp8266-oled-ssd1306.

Код для работы дисплея приведен ниже. Как можно видеть, он практически не отличается по сути от предыдущей рассмотренной версии для Arduino. Значения 21 и 22 - это номера выводов, соответствующие GPIO21 и GPIO22.

#include "SSD1306.h"

SSD1306 display(0x3c, 21, 22);

void setup() {

display.init();

display.flipScreenVertically();

}

void loop() {

display.clear();

display.setFont(ArialMT_Plain_10);

display.setTextAlignment(TEXT_ALIGN_LEFT);

display.drawString(0, 0, "Hello world");

display.setFont(ArialMT_Plain_16);

display.drawString(0, 10, "Hello world");

display.setFont(ArialMT_Plain_24);

display.drawString(0, 26, String(42));

display.display();

delay(5000);

}

Из полезных моментов можно отметить функцию setFont, с помощью которой можно задать разный размер шрифта. Кстати, можно выводить не только строки, но и числа, преобразовав их с помощью String, как показано в коде.

Теперь мы можем выводить нужные нам данные на экран. Следующим шагом узнаем, как получать необходимые данные из сети Интернет.

Самостоятельная работа: изучить исходный текст библиотеки рисования по адресу https://github.com/ThingPulse/esp8266-oled-ssd1306/blob/master/OLEDDisplay.h. Помимо функции drawString, там описано множество других полезных функций, например drawCircle или drawProgressBar. Испытать их в программе.

3.5 Получаем время от атомных часов

Раз уж мы подключились к Интернет, можно сделать много чего полезного. Например, получить точное время с атомных часов от NTP-сервера, тем более что библиотеки для этого уже есть.

Добавим в программу соединения с WiFi код вывода точного времени.

#include <WiFi.h>

#include <time.h>

const char* ssid = "TP-LINK_AB11";

const char* password = "12345678";

const char* ntpServer = "pool.ntp.org";

const long gmtOffset_sec = 3600;

const int daylightOffset_sec = 3600;

void setup() {

Serial.begin(115200);

while (WiFi.status() != WL_CONNECTED) {

delay(1000);

Serial.print(".");

WiFi.begin(ssid, password);

}

Serial.println("WiFi connected!");

Serial.print("IP address: ");

Serial.println(WiFi.localIP());

// Настройки службы времени

configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);

}

void loop() {

// Получение времени

struct tm timeinfo;

if (!getLocalTime(&timeinfo)){

Serial.println("getLocalTime: error");

delay(10000);

return;

}

Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");

delay(30000);

}

Как можно видеть, мы добавили вызов двух функций: configTime и getLocalTime. Первая функция настраивает нужные параметры (например часовой пояс), вторая получает время. Кстати, само время хранится в структуре tm, которая хранится в файле time.h и имеет следующий вид:

struct tm {

int tm_sec; // Seconds after the minute [0, 59]

int tm_min; // Minutes after the hour [0, 59]

int tm_hour; // Hours since midnight [0, 23]

int tm_mday; // Day of the month [1, 31]

int tm_mon; // Months since January [0, 11]

int tm_year; // Years since 1900

int tm_wday; // Days since Sunday [0, 6]

int tm_yday; // Days since January 1 [0, 365]

int tm_isdst; // Daylight Saving Time flag

int tm_gmtoff; // Seconds east of UTC

char *tm_zone; // Timezone abbreviation

};

Все эти поля можно использовать. Например, можно зажечь светодиод (или запустить зуммер) в 8 часов утра:

if (timeinfo.tm_hour == 8 && timeinfo.tm_min == 0) {

...

}

Мы также используем строку “%A, %B %d %Y %H:%M:%S”, которая указывает в каком формате выводить дату и время. Например, чтобы вывести только время, достаточно написать “%H:%M:%S”. Список разных форматов можно найти здесь.