Created by Bc. Lukáš Vokurka, DiS

Zadání projektu č. 1

S využitím vývojové desky a příslušného senzoru sestavte funkční zapojení obvodu, které bude měřit požadovanou veličinu - teplotu. Tato bude přenesena prostřednictvím sítě WiFi na MQTT server, zaznamenána do k tomu určené databáze a vizualizována pomocí vhodného grafického zobrazení.

Hardware

  • Raspberry Pi 3 Model B+

  • Vývojová deska ESP32

  • Senzor pro měření teploty DHT22

  • WiFi Router (SSID, password)

Teoretický úvod

Mosquitto

Mosquitto je open - source broker zpráv pro MQTT protokol. Slouží, jako prostředník mezi zařízeními a aplikacemi, které používají MQTT protokol. Klienti mohou pomocí Mosquitto posílat zprávy do určitých témat tzv. topics a ostatní zařízení, která jsou přihlášená k odběru těchto témat, zprávy přijímají.

Node - RED

Node - RED je open - source nástroj pro vizuální programování. Umožňuje snadnou tvorbu aplikačních toků tzv. flows pomocí jednoduchého grafického rozhraní, kde uživatel propojuje různé uzly (nodes), které reprezentují vstupy, výstupy a funkční logiku. Node - RED je postaven na JavaScript a běží na platformě Node.js.

InfluxDB

InfluxDB je open - source časová databáze, která je speciálně navržena pro ukládání a správu dat s časovými značkami. Shromažďuje velké množství dat, která přicházejí v reálném čase z různých zařízení a senzorů.

Grafana

Grafana je open - source platforma pro vizualizaci dat a tvorbu interaktivních dashboardů. Umí efektivně zobrazovat a analyzovat velké objemy dat v reálném čase, které přicházejí ze senzorů.

Docker

Docker kontejner je lehká virtualizovaná jednotka, která obsahuje aplikaci a všechny její potřebné závislosti. Jsou založené na Docker image, což je statický soubor, který obsahuje všechny potřebné závislosti a konfiguraci pro aplikaci. Z tohoto image se následně vytvoří kontejner, což je běžící instalace image.

Schéma IoT sítě

Z výše uvedeného blokového schématu lze vidět celá stavba IoT (Internet of Things) sítě. Vytvořil jsem tedy server IoT na počítači Raspberry Pi. Tento server bude používat Mosquitto MQTT, InfluxDB, Node-RED a Grafanu, což bude virtualizováno v Docker kontejneru. Použil jsem užitečný nástroj IoTStack, který za mě nakonfiguruje kontejnery Docker. Tento způsob mi umožnil shromažďovat data ze senzoru, posílat je po síti na tento MQTT server a vizualizovat je ve vizualizačním nástroji Grafana. Node odesílá data ve zprávě JSON prostřednictvím protokolu MQTT na server Mosquitto v Raspberry Pi.

Konfigurace Node

Node bylo nutné nejprve správně fyzicky zapojit a připojit do PC. Napájení +3V3, GND a digitální pin 17.

Pro konfiguraci Node jsem použil bezplatný software Arduino IDE. Níže je uveden kód, ve kterém je potřeba doplnit SSID, password a název MQTT serveru.

#include <ArduinoJson.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include "DHT.h"

#define DHTPIN 17     
#define DHTTYPE DHT22   

DHT dht(DHTPIN, DHTTYPE);

const char* ssid = "ssid";
const char* password = "passw";
const char* mqtt_server = "IP_address/name_mqtt_server.local";

WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;

#define MSG_BUFFER_SIZE	(50)
char msg[MSG_BUFFER_SIZE];
int value = 0;

void setup_wifi() {

    delay(100);
    Serial.println();
    Serial.print("Connecting to ");
    Serial.println(ssid);

    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }

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

void callback(char* topic, byte* payload, unsigned int length) {

}

void reconnect() {
    while (!client.connected()) {
        Serial.print("Attempting MQTT connection...");
        String clientId = "ESP8266Client-";
        clientId += String(random(0xffff), HEX);
        if (client.connect(clientId.c_str())) {
            Serial.println("connected");
            client.publish("outTopic", "hello world");
            client.subscribe("inTopic");
        } else {
            Serial.print("failed, rc=");
            Serial.print(client.state());
            Serial.println(" try again in 5 seconds");
            delay(5000);
        }
    }
}

void setup() {
    Serial.begin(115200);
    dht.begin();
    setup_wifi();
    client.setServer(mqtt_server, 1883);
    client.setCallback(callback);
}

void loop() {
    if (!client.connected()) {
        reconnect();
    }
    client.loop();
    
    StaticJsonDocument<32> doc;
    char output[55];

    long now = millis();
    if (now - lastMsg > 5000) {
        lastMsg = now;
        float temp = dht.readTemperature();
        
        if (isnan(temp)) {
            Serial.println("Failed to read from DHT sensor!");
            return;
        }

        doc["t"] = temp;
        serializeJson(doc, output);
        Serial.println(output);
        client.publish("/home/sensors", output);
        Serial.println("Sent");
    }
}

Konfigurace Raspeberry Pi

Nejprve bylo nutné na SD kartu nahrát OS prostřednictvím Rasperry Pi manager, ve kterém jsem vybral typ Pi 3 a jako OS jsem Raspberry Pi OS (64 - bit). Následně jsem přes zkratku Ctrl + Shift + X, nakonfiguroval další údaje. Důležité bylo povolit SSH protokol pro pozdější připojení do Raspberry Pi.

Po nahrání OS na SD kartu jsem se připojil přes HDMI kabel a zkontroloval WiFi připojení na Raspberry Pi. Poté jsem se připojil přes Putty a protokolem SSH (port 22) do Raspberry.

Po připojení SSH protokolem jsem zadal jméno a heslo, které jsem nastavil při nahrávání OS a pokračoval dle následujícího postupu.

Na začátek se ujistím, že je vše aktualizováno:

sudo apt update
sudo apt upgrade

Poté stáhnu IoTStack pomocí následujícího příkazu a po dokončení stahování restartuji Raspberry:

curl -fsSL https://raw.githubusercontent.com/SensorsIot/IOTstack/master/install.sh | bash
sudo shutdown -r now

Jakmile je Raspberry opět online, můžu se znovu připojit pomocí SSH a otevřít nabídku. Nejprve přejdu do složky IoTStack a poté spustím skript nabídky:

cd IOTstack/
./menu.sh

V této nabídce se pohybuji pomocí šipek nahoru a dolů a poté vyberu mezerníkem. Zadáním se vytvoří soubor docker-compose.yml. Ujistím se, že jsem vybral následující komponenty:

Grafana
InfluxDB
Mosquitto
Node-RED
Portainer-CE

Všechny tyto kontejnery pak můžu spustit příkazem „Start Stack“. Při prvním spuštění to chvíli trvá, než se vše stáhne. Po dokončení můžu příkazem zkontrolovat, zda vše běží:

docker-compose ps

Pro vytvoření databáze InfluxDB musím vstoupit do docker kontejneru influx a poté přidat databázi následujícím způsobem:

docker exec -it influxdb influx
CREATE DATABASE sensor_data
quit

Nyní můžu přejít na webová rozhraní aplikací, které potřebuji nakonfigurovat. Interpret JSON Node-RED, který jsem použil, byl tento:

{
    "temperature": msg.payload.t,
}

Pokud chci zkontrolovat, zda se data zapisují do databáze, můžu použít následující sekvenci příkazů:

docker exec -it influxdb influx
USE sensor_data
show measurements
select * from sensor_data
quit

Webové aplikace

Docker kontejner: IP_adresa_mqtt_server :9000

Node - Red: IP_adresa_mqtt_server :1880

Grafana: IP_adresa_mqtt_server :3000

Závěr

Výsledkem je tedy funkční IoT síť s měřením teploty a vizualizací naměřených dat v reálném čase ve vizualizačním nástroji Grafana.