Czech English

6. Meteostanice 3

s odesíláním hodnot do cloudu (ThingSpeak)

V přechozích dílech jsme zprovoznili jednoduchou meteostanici poskytující informace o aktuálním stavu vzduchu (teplota, tlak, vlhkost) se zobrazením na webové stránce. Kromě toho by bylo dobré naměřená data někde ukládat pro možné zobrazení časových průběhů změn měřených veličin.


Můžeme si zprovoznit vlastní webový server, který by data ukládal do databáze. My ale použijeme raději služeb některé ze služeb, které jsou k tomuto účelu v internetu k dispozici. Pro profesionální použití jsou tyto služby placené, ale nám bude stačit některá z neplacených variant.
Velmi dobrou volbou je služba ThingSpeak, která ve volné variantě poskytuje dobré možnosti s podmínkami, které nás příliš neomezí (maximální počet uložených záznamů 3 miliony za rok, doba archivace 3 roky). Výhodou je možnost použití pro ukládání dat buď REST API nebo MQTT API. My použijeme protokol MQTT, který je v oblasti IoT standardem (výhodou jsou mimo jiné menší nároky na zařízení než při použití protokolu HTTP).

Vytvoření kanálu na ThingSpeak

Pro ukládání dat na ThingSpeak musíme mít na této službě vytvořený účet.
A dále si musíme připravit tzv. kanál, pro ukládání dat, kde specifikujeme počet hodnot a názvy položek, které budeme ukládát.
Pro ukládání dat na ThingSpeak potřebujeme přístupové údaje: Channel ID a Write API Key. Ty získáme v záložce API Keys:

ESP8266 klient

Zásadním rozdílem na straně ESP8266 bude to, že nebude vystupovat v roli serveru, ale klienta. V pravidelných intervalech změří aktulní hodnoty veličin a pošle je na ThingSpeak server.
Ve zdrojovém kódu programu musíme nastavit nejen přístupové údaje do naší wifi sítě, ale i výše uvedené položky (ChannelID a API Key):
ESP8266_ThingSpeak.ino
#include <ESP8266WiFi.h>
#include "PubSubClient.h"

#include "Adafruit_BMP280.h"
#include "Adafruit_HTU21DF.h"

// Wi-Fi Settings
const char* ssid = "REPLACE_WITH_YOUR_SSID"; // Nahradte vasim jmenem site SSID
const char* password = "REPLACE_WITH_YOUR_PASSWORD"; // Nahradte heslem do vasi site

char* APIkey = "ZS4DGYTLV4MNTLGJ";
char* ChannelID = "824688";
char* server = "mqtt.thingspeak.com";
String topic;

// Casovy interval mereni v ms
#define TIME_INTERVAL 300000

// EPS 12 SDA - GPIO5(D1), SCL - GPIO4(D2)

#define SDA 5
#define SCL 4
 
#define BMP280_ADRESA (0x77)
Adafruit_BMP280 bmp;
Adafruit_HTU21DF htu;

WiFiClient wifiClient;
PubSubClient client(server, 1883, wifiClient); 

void ConnectToWifi(){

  // We start by connecting to a WiFi network
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.persistent(false);
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println(""); 
  Serial.println("WiFi connected");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.print("MAC: ");
  Serial.println(WiFi.macAddress());
}

void ReconnectMQTT() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection ... ");
    // Create a random client ID
    String clientId = "ESP8266Client-";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}  

void setup() {
  Serial.begin(115200);
  Serial.println();
  Serial.println();

  ConnectToWifi();
  Wire.begin(SDA, SCL); // SDA, SCL  
  bmp.begin(BMP280_ADRESA);
  htu.begin();

  topic = (String)"channels/"+ChannelID+"/publish/"+APIkey; 
}

void SendToThingspeak(float t, float p, float h) {
  String payload="field1=";
  payload+=t;
  payload+="&field2=";
  payload+=p;
  payload+="&field3=";
  payload+=h;
  payload+="&status=MQTTPUBLISH";

  Serial.print((String)"Temperature: " + t + " °C Pressure: " + p + " hPa Humidity: " + h + " % ");

  if (client.publish((char*)topic.c_str(), (char*)payload.c_str())) {
    Serial.println("... publish ok");
  } else {
    Serial.println("... publish failed");
  }     
}

uint32_t timeStamp = millis() - TIME_INTERVAL;

float teplota, tlak, vlhkost;

void loop() {

  if (!client.connected()) {
    ReconnectMQTT();
  }
  client.loop(); 

  if (client.connected() && millis() - timeStamp > TIME_INTERVAL) {
    timeStamp = millis();  
    
    teplota = bmp.readTemperature();
    tlak = (bmp.readPressure()/100.00);
    vlhkost = htu.readHumidity();
    
    SendToThingspeak(teplota, tlak, vlhkost);
  }
}
Záznam měřených dat si můžeme prohlédnout přímo na stránkách ThingSpeak
nebo je můžeme použít na vlastní webové stránce stejným způsobem jako v minulém díle. Navíc můžeme přímo do naší webové stránky vložit graf průběhu naměřených hodnot ze služby ThingSpeak.
Zdrojový kód webové stránky:
index_ThingSpeak.html
File not exists !!!
Výhodou tohoto řešení je kromě bezpracné archivace dat, i možnost přístupu k naměřeným datům odkudkoliv.
Zdrojové kódy příkladu ESP8266_ThingSpeak.

WWW stránky se zdroji