ESP8266 Ежедневная задача — публикация показаний температуры на ThingSpeak

В этом проекте вы узнаете, как создать сенсорный узел на базе ESP8266, который публикует показания температуры и влажности один раз в день на бесплатном сервисе Thing Speak.

ESP8266 ежедневная задача — публикация показаний температуры на ThingSpeak

Смотрите видеоурок и демонстрацию проекта

Это руководство доступно в видеоформате (смотрите ниже) и в текстовом формате (продолжайте чтение).

Предварительные требования

Перед тем как приступить к этому руководству, мы рекомендуем ознакомиться со следующими ресурсами:

Если вам нравится ESP8266 и вы хотите узнать о нём больше, рекомендуем скачать курс: Home Automation using ESP8266.

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

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

Компоненты для проекта ESP8266 Daily Task

Вы можете использовать приведённые выше ссылки или перейти непосредственно на MakerAdvisor.com/tools, чтобы найти все компоненты для ваших проектов по лучшей цене!

Схема подключения

Схема очень проста в сборке и не требует пайки — просто следуйте приведённой ниже диаграмме.

Схема подключения ESP8266 с DHT11 для ежедневной задачи

Подготовка Arduino IDE

Примечание: у вас должен быть установлен аддон ESP8266 в Arduino IDE.

После подготовки схемы откройте Arduino IDE и установите две библиотеки Arduino. Перейдите в Sketch > Include library > Manage libraries…

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

Найдите DHT (или скачайте здесь). Нажмите кнопку «Install».

Установка библиотеки датчика DHT в Arduino IDE

Примечание: вам также может понадобиться установить библиотеку Adafruit Sensor.

Затем вам также нужно найти ESP Daily Task и установить эту библиотеку (или скачайте здесь).

Установка библиотеки ESP Daily Task в Arduino IDE

Thing Speak

Для этого проекта мы будем использовать ThingSpeak.com. Thing Speak позволяет публиковать показания ваших датчиков на их сайте и отображать их на графике с метками времени. После этого вы сможете получить доступ к своим показаниям из любой точки мира.

Платформа ThingSpeak для IoT данных

Стоит отметить, что этот проект можно легко модифицировать для публикации значений на вашем хабе домашней автоматизации или в другом приложении вместо Thing Speak.

Основная концепция, которую я хочу показать вам в этом проекте — как можно постоянно держать ESP8266 в режиме глубокого сна, публикуя значение каждые 24 часа.

Создание нового канала

Если у вас нет учётной записи на Thing Speak, вам нужно её создать. После того как ваш аккаунт будет готов, войдите в систему и откройте вкладку «Channels».

Вкладка My Channels на ThingSpeak

Нажмите кнопку создания «New Channel»:

Кнопка создания нового канала на ThingSpeak

Введите название для вашего канала, добавьте описание и включите второе поле. Field 1 будет получать показания влажности (Humidity), а Field 2 — показания температуры (Temperature). После заполнения всех полей сохраните ваш канал.

Сохранение нового канала на ThingSpeak

Настройка графика

Эти графики можно настроить — перейдите на вкладку Private View и нажмите значок редактирования:

Настройка графика полей на ThingSpeak

Вы можете дать каждому графику заголовок, например, первый график будет называться Humidity %, а второй — Temperature ºC.

Настройка графика влажности на ThingSpeak

Вы также можете настроить цвет фона, оси X и Y и многое другое, как видите. Когда закончите, нажмите кнопку «Save».

Настройка графика температуры на ThingSpeak

Write API Key

Для публикации значений с ESP8266 вам нужен Write API Key. Откройте вкладку «API Keys» и скопируйте Write API Key в безопасное место, потому что он понадобится вам через минуту.

Write API Key на ThingSpeak

Загрузка кода

Вернитесь в Arduino IDE и скопируйте приведённый ниже код:

/*
 * ESP8266 Daily Task
 * Rui Santos
 * Complete Project Details https://randomnerdtutorials.com
 */

#include <ESP8266WiFi.h>
#include <ESPDailyTask.h>
#include "DHT.h"

// Uncomment one of the lines below for whatever DHT sensor type you're using!
#define DHTTYPE DHT11   // DHT 11
//#define DHTTYPE DHT21   // DHT 21 (AM2301)
//#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321

// Replace with your SSID and Password
const char* ssid     = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

// Replace with your unique Thing Speak WRITE API KEY
const char* apiKey = "REPLACE_WITH_YOUR_ThingSpeak_WRITE_API_KEY";

const char* resource = "/update?api_key=";

// Thing Speak API server
const char* server = "api.thingspeak.com";

// Set this for what time your daily code should run
ESPDailyTask dailyTask(11*60 + 15); // 11:15am

// DHT Sensor
const int DHTPin = 5;
// Initialize DHT sensor.
DHT dht(DHTPin, DHTTYPE);

// Temporary variables
static char temperatureTemp[7];
static char humidityTemp[7];

void setup() {
  // Initializing serial port for debugging purposes
  Serial.begin(115200);
  delay(10);

  dailyTask.sleep1Day();

  // put your daily code here...
  dht.begin();

  initWifi();
  makeHTTPRequest();

  // and back to sleep once daily code is done
  dailyTask.backToSleep();
}

void loop() {
  // sleeping so wont get here
}

// Establish a Wi-Fi connection with your router
void initWifi() {
  Serial.print("Connecting to: ");
  Serial.print(ssid);
  WiFi.begin(ssid, password);

  int timeout = 10 * 4; // 10 seconds
  while(WiFi.status() != WL_CONNECTED  && (timeout-- > 0)) {
    delay(250);
    Serial.print(".");
  }
  Serial.println("");

  if(WiFi.status() != WL_CONNECTED) {
     Serial.println("Failed to connect, going back to sleep");
  }

  Serial.print("WiFi connected in: ");
  Serial.print(millis());
  Serial.print(", IP address: ");
  Serial.println(WiFi.localIP());
}

// Make an HTTP request to Thing Speak
void makeHTTPRequest() {
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  float f = dht.readTemperature(true);
  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println("Failed to read from DHT sensor!");
    strcpy(temperatureTemp,"Failed");
    strcpy(humidityTemp, "Failed");
    return;
  }
  else {
    // Computes temperature values in Celsius + Fahrenheit and Humidity
    float hic = dht.computeHeatIndex(t, h, false);
    // Comment the next line, if you prefer to use Fahrenheit
    dtostrf(hic, 6, 2, temperatureTemp);

    float hif = dht.computeHeatIndex(f, h);
    // Uncomment the next line, if you want to use Fahrenheit
    //dtostrf(hif, 6, 2, temperatureTemp);

    dtostrf(h, 6, 2, humidityTemp);
    // You can delete the following Serial.print's, it's just for debugging purposes
    Serial.print("Humidity: ");
    Serial.print(h);
    Serial.print(" %\t Temperature: ");
    Serial.print(t);
    Serial.print(" *C ");
    Serial.print(f);
    Serial.print(" *F\t Heat index: ");
    Serial.print(hic);
    Serial.print(" *C ");
    Serial.print(hif);
    Serial.print(" *F");
    Serial.print("Humidity: ");
    Serial.print(h);
    Serial.print(" %\t Temperature: ");
    Serial.print(t);
    Serial.print(" *C ");
    Serial.print(f);
    Serial.print(" *F\t Heat index: ");
    Serial.print(hic);
    Serial.print(" *C ");
    Serial.print(hif);
    Serial.println(" *F");
  }

  Serial.print("Connecting to ");
  Serial.print(server);

  WiFiClient client;
  int retries = 5;
  while(!!!client.connect(server, 80) && (retries-- > 0)) {
    Serial.print(".");
  }
  Serial.println();
  if(!!!client.connected()) {
     Serial.println("Failed to connect, going back to sleep");
  }

  Serial.print("Request resource: ");
  Serial.println(resource);
  client.print(String("GET ") + resource + apiKey + "&field1=" + humidityTemp + "&field2=" + temperatureTemp +
                  " HTTP/1.1\r\n" +
                  "Host: " + server + "\r\n" +
                  "Connection: close\r\n\r\n");

  int timeout = 5 * 10; // 5 seconds
  while(!!!client.available() && (timeout-- > 0)){
    delay(100);
  }
  if(!!!client.available()) {
     Serial.println("No response, going back to sleep");
  }
  while(client.available()){
    Serial.write(client.read());
  }

  Serial.println("\nclosing connection");
  client.stop();
}

Просмотреть исходный код

Подготовка кода

Есть 3 переменные, которые необходимо изменить. Добавьте ваш SSID и пароль, чтобы ESP мог установить соединение с вашим роутером:

// Replace with your SSID and Password
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

Введите ваш Write API ключ Thing Speak в эту переменную:

// Replace with your unique Thing Speak WRITE API KEY
const char* apiKey = "REPLACE_WITH_YOUR_ThingSpeak_WRITE_API_KEY";

Разбор кода

Теперь мы можем подробнее рассмотреть код. Функция setup() начинается с инициализации последовательного порта.

void setup() {
 // Initializing serial port for debugging purposes
 Serial.begin(115200);
 delay(10);

Затем вызывается функция ESP daily task, чтобы определить, прошло ли 24 часа с момента последнего считывания или нет. Если нет — ESP возвращается в режим глубокого сна.

dailyTask.sleep1Day();

Однако, если с момента последнего считывания прошло 24 часа, код продолжит выполнение. Таким образом, он инициализирует датчик DHT, подключится к Wi-Fi роутеру и выполнит HTTP GET запрос к Thing Speak для публикации показаний.

// put your daily code here...
dht.begin();

initWifi();
makeHTTPRequest();

После публикации показаний ESP возвращается в режим глубокого сна.

 // and back to sleep once daily code is done
 dailyTask.backToSleep();
}

В функции loop() ничего нет, потому что ваш ESP постоянно находится в режиме глубокого сна и пробуждается самостоятельно.

void loop() {
 // sleeping so wont get here
}

Другие изменения — другой датчик и градусы Фаренгейта

Обратите внимание, что если вы используете датчик, отличный от DHT11, вы можете закомментировать и раскомментировать соответствующую строку DEFINE для использования вашего датчика.

// Uncomment one of the lines below for whatever DHT sensor type you're using!
#define DHTTYPE DHT11 // DHT 11
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
//#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321

Есть ещё одна важная вещь, которую можно изменить. По умолчанию этот код публикует температуру в градусах Цельсия, но если вы закомментируете переменную, выделенную красным, и раскомментируете переменную, выделенную зелёным, температура будет публиковаться в градусах Фаренгейта.

// Computes temperature values in Celsius + Fahrenheit and Humidity
float hic = dht.computeHeatIndex(t, h, false);
// Comment the next line, if you prefer to use Fahrenheit
dtostrf(hic, 6, 2, temperatureTemp);

float hif = dht.computeHeatIndex(f, h);
// Uncomment the next line, if you want to use Fahrenheit
//dtostrf(hif, 6, 2, temperatureTemp);

После внесения всех изменений вы можете загрузить код на вашу плату ESP.

Тестирование проекта

Наконец, откройте Serial Monitor в Arduino IDE на скорости 115200 бод. Вы можете протестировать свой проект и имитировать прохождение каждого часа. Просто отсоедините провод, соединяющий вывод RESET с D0 (GPIO 16), а затем нажмите кнопку RESET, чтобы имитировать прохождение каждого часа.

Кнопка Reset на ESP8266 для тестирования

Итак, вам нужно нажать 24 раза, чтобы опубликовать показание. Переменная-счётчик увеличивается каждый раз при нажатии кнопки сброса. Как только вы сбросите ESP8266 24 раза, он опубликует показания на Thing Speak.

Серийный монитор Arduino IDE с показаниями ESP8266

Как видите, влажность и температура были успешно опубликованы и отображены на графике в реальном времени.

График влажности на ThingSpeak График температуры на ThingSpeak

После тестирования схемы вам следует снова подключить провод от RESET к D0. ESP будет просыпаться каждый час, но публиковать значение будет только каждые 24 часа.

Заключение

Надеюсь, этот проект был полезен. Теперь вы знаете, как применить концепцию ежедневной задачи к любому проекту.

Это отрывок из курса Home Automation using ESP8266 eBook. Если вам нравится ESP8266 и вы хотите узнать о нём больше, рекомендуем скачать курс: Home Automation using ESP8266.

Надеемся, это руководство было полезным. Спасибо за чтение!