Wetterstation auf Arduino von A bis Z. Teil 5

    Das Ende Der vorherige Teil .


    Inhaltsverzeichnis:



    Fenstersensor. Software


    Lassen Sie uns über die Software hinter dem Fenstersensor sprechen. Danach haben Sie ein komplettes System, mit dem Sie bereits experimentieren können.


    Ich möchte Sie daran erinnern, dass der Server eine zentrale Heimeinheit ist, die über WLAN mit dem Internet kommunizieren kann, und der Client ein entfernter Sensor ist, der die Daten per Funk an den Server überträgt.


    Der Quellcode für Server und Client ist hier .
    Ausgangstexte werden mit ausführlichen Kommentaren versehen.


    Auf dem Client muss fast nichts konfiguriert werden.


    Für den Funksender nRF24L01 + bzw. die RadioHead-Bibliothek müssen die Server- und Client-Adressen angegeben werden. Adressen werden bereitgestellt, wenn Sie mehr als einen Server und einen Client haben. Eine Adresse ist nur eine ganze Zahl. Wenn ein Client ein Paket mit Daten an den Server sendet, gibt er an, für welchen Server das Paket bestimmt ist. Der Server, der seine eigene Adresse kennt, bestimmt wiederum, ob dieses Paket dafür bestimmt ist.


    Daher sollte SERVER_ADDRESSauf dem Server und auf dem Client derselbe sein, aber CLIENT_ADDRESSfür verschiedene Clients sollte es unterschiedlich sein. Mit anderen Worten, wenn Sie unserem System in Zukunft einen neuen Sensor hinzufügen, müssen CLIENT_ADDRESSSie ihn ändern.


    // Адрес сервера и клиента#define SERVER_ADDRESS 10#define CLIENT_ADDRESS 20 // ИЗМЕНИТЬ для другого экземпляра !!!

    Die Nummer des Funkkanals RF_CHANNELmuss für alle gleich sein. Die Standardeinstellung ist 2. Wenn Sie die Standardnummer geändert haben, können Sie eine andere auswählen.


    // Номер радиоканала. Должен быть КАК И У СЕРВЕРА#define RF_CHANNEL 73

    Die Einstellungen des Voltmeters zur Messung der Batterieversorgungsspannung müssen geändert werden:


    // Резисторы делителя напряжения, фактические значенияconstfloat r1 = 100400; // 100Kconstfloat r2 = 9960; // 10K// Эту константу необходимо откалибровать индивидуально// как описано здесь http://localhost/arduino-secret-true-voltmeter/constfloat typVbg = 1.082; // обычно в пределах 1.0 -- 1.2 В

    Um Energie zu sparen, wird die Lightweight-Low-Power-Library für Arduino verwendet .


    Hier sind meine aktuellen Verbrauchsmessungen für den Arduino Pro Mini mit diesem:


    • normalerweise 25mA
    • bei der Arbeit mit DHT das gleiche
    • mit Funkübertragung 38 mA
    • mit LowPower.idle 15 mA
    • mit LowPower.powerDown 7,5 mA

    Der Client misst Temperatur, Luftfeuchtigkeit und Spannung, packt alles in eine Datenstruktur, sendet Daten an den Server und schläft ein. Wenn während der Übertragung Fehler aufgetreten sind, wird die Übertragung sofort wiederholt.


    Der Server (Zentrale, Heimeinheit) empfängt wiederum Daten, bestätigt den Empfang und verarbeitet sie.


    Datenbank, MySQL, PHP, WWW-Server


    Nach der Arbeit haben wir eine voll funktionsfähige Konstruktion der Wetterstation. Aber jetzt sind diese Wetterstationen ein Dutzend, lokales Kunsthandwerk, das ist nicht mehr in Mode. Wir haben das Internet der Dinge.


    Lassen Sie uns daher darüber sprechen, wie Sie auf Ihre Internetseiten zugreifen, an unsere Wetterstation eine Datenbank und ein Web-Face anfügen.


    Aufgabenstellung für "Webcam":


    • Wetterstationsdaten empfangen und speichern: Temperatur, Luftfeuchtigkeit, Luftdruck, Versorgungsspannung
    • Diese Daten anzeigen
    • Grafiken erstellen.

    In diesem Fall benötigen wir ein Hosting mit Unterstützung für Apache, PHP und MySQL mit dem Modul mysqli. Und diese Bedingungen werden von fast jedem Hosting auf der Erde erfüllt. Anstelle des Hostings übernimmt Ihr Computer die Rolle eines Servers, der mit einem Heimnetzwerkrouter verbunden ist und über Internetzugang verfügt.


    Datenbankerstellung


    Beginnen wir von Anfang an mit dem Entwurf und Erstellen einer Datenbank.


    Die Datenbank ist Ihre eigene Welt und Sie können sie lange studieren. Deshalb werden wir nur kurz auf die Dinge eingehen, die für uns unmittelbar notwendig sind.


    Alle SQL-Skripts befinden sich im Verzeichnis. weather-station/server/php-sql/


    Wo beginnt der Entwurf der Datenbank? Mit einer logischen und physischen Darstellung.


    Logische Darstellung oder Datenbankschema:


    • Tabelle mit DHT-Daten des Temperatur- und Feuchtigkeitssensors
    • Tabelle mit BMP-Daten des Druck- und Temperatursensors
    • Diese Tabellen haben keine Verknüpfungen untereinander, genauer gesagt, Verknüpfungen sind nicht erforderlich.

    Das physische Schema basiert auf einem bestimmten DBMS und Datentypen. Einfacheres Durchsuchen eines bestimmten Beispiels. Das SQL-Skript make_tables.sqlenthüllt das logische und physische Schema.


    Jede Tabelle sollte ein Typfeld haben


    id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT

    Der Feldname kann sich in verschiedenen Datenbanken unterscheiden, die Bedeutung ist jedoch gleich - es handelt sich um eine eindeutige Kennung, einen Datensatzschlüssel. Wenn Sie in den Tabellen eine Datenbank sehen, für die es keinen solchen Zähler gibt, sollten Sie wissen, dass diese Datenbank von einer Person entworfen wurde, die sehr weit vom Programmieren entfernt ist, höchstwahrscheinlich ein humanitärer Mitarbeiter.


    Die Daten desselben Sensortyps werden in einer Tabelle gespeichert. Für Sensoren eines anderen Typs erstellen wir eine andere Tabelle. Dies macht die Datenbank- und PHP-Bindung etwas komplizierter, vereinfacht jedoch die Erweiterung oder Modifikation des gesamten Systems in der Zukunft.


    In unserem Projekt gibt es zwei Tabellen. Die Tabelle arduino_dhtspeichert Daten von den Sensoren des Typs DHT (Temperatur, Luftfeuchtigkeit), die Tabelle arduino_bmpspeichert Daten von den Sensoren des Typs BMP (Temperatur, Druck). Wenn Sie in der Zukunft beispielsweise einen Gassensor oder einen Bewegungsmelder haben möchten, erstellen Sie zusätzliche Tabellen, seien Sie nicht faul. Wenn Sie einen anderen Sensortyp DHT11 oder DHT22 anschließen, ist das Erstellen einer zusätzlichen Tabelle nicht erforderlich. Verwenden Sie eine Tabelle arduino_dht. Ich hoffe, das Prinzip ist klar: eine separate physische Einheit - eine separate Tabelle.


    Wenn Daten von mehreren Sensoren desselben Typs in der Tabelle gespeichert sind, wie können sie unterschieden werden? Dazu wird in jede Tabelle ein Feld eingetragen.


    idSensor INTEGER

    In der Tat haben CLIENT_ADDRESSwir dies client/client.inofür jede Instanz des Remote Sensor Client und server/server.inofür den Sensor, der direkt mit dem Server verbunden ist , in die Datei geschrieben - die Zentraleinheit.


    In industriellen Systemen muss es eine andere Tabelle geben - die Korrespondenz idSensorund ihre verbale, von Menschen lesbare Beschreibung. Zum Beispiel ist der Sensor mit idSensor= 2 "Temperatur, Luftfeuchtigkeit in der Wohnung" usw. Aber in unserem Projekt werden wir es nicht komplizieren, denken Sie einfach daran:


    • Sensor mit idSensor, es ist CLIENT_ADDRESSgleich 11 - dies ist der Home-Sensor auf dem Server - die Zentraleinheit,
    • Sensor c idSensor, CLIENT_ADDRESSder gleich 20 ist, ist der erste (in unserem Projekt und der einzige) Remote-Sensor-Client.

    Weiter Folgende Daten werden in den Tabellen gespeichert:


    • ipRemote - die IP-Adresse der Wetterstation (Server), von der die Daten stammen, zum Debuggen und Überwachen,
    • dateCreate - das Datum, an dem der Datensatz erstellt wurde,
    • Millis - nützlich für das Debugging, diesmal in Millisekunden seit dem Beginn der Skizze auf dem Arduino,
    • Temperatur - Temperatur
    • Luftfeuchtigkeit - Luftfeuchtigkeit
    • Spannung - Versorgungsspannung
    • Druck - Druck
    • Fehler - die Anzahl der Fehler (nicht verwendet). Speichern der Anzahl der Fehler bei der Übertragung usw., damit Sie den Status des gesamten Systems aus der Ferne beurteilen können.

    Wie Sie die Tabelle sehen können arduino_dhtund arduino_bmpsind sehr ähnlich, der einzige Unterschied ist in den Bereichen Druck und Feuchtigkeit, und dem Wunsch , alles in einem Heap (eine Tabelle) auszugeben . Die erste Normalform erlaubt es jedoch nicht , viele Neulinge haben versucht, sie zu umgehen, aber keiner von ihnen hat es geschafft, und wir werden es nicht tun. So kann man das Gesetz der Welt nicht beachten, vorerst kann es sich herausstellen.


    Die Tabelle arduino_error_logist hilfreich für das Debugging. Hierbei werden Fehler und andere Systemmeldungen protokolliert.


    Erstellen einer Datenbank und ihres Benutzers mit den in make_db.sql


    -- см. также config.php-- создать БДCREATEDATABASEIFNOTEXISTS db_weather;
    -- создать пользователяCREATEUSER'u_weather'@'localhost'IDENTIFIEDBY'***PASSWORD***';
    GRANT ALL ON db_weather.* TO'u_weather'@'localhost';

    Dies erfolgt einmalig, der Datenbankname und der Benutzername können ihren eigenen Namen finden. Und was genau getan werden muss, ist das Festlegen Ihres Passworts.


    PHP und Webserver


    Alle Webinterface-Einstellungen werden in gespeichert config.php. Ändern Sie es entsprechend Ihren Datenbankeinstellungen.


    Stellen Sie Ihre Zeitzone im PHP-Format ein


    date_default_timezone_set(‘Europe/Prague’);

    Alle verfügbaren Zeitzonen werden hier beschrieben .


    Geben Sie Ihren geheimen Schlüssel für den Zugriff (als Nummer) an, der mit der Konstante SOURCE_KEYaus der Skizze übereinstimmen mussserver.ino


    $access_key = ‘***KEY***’;

    Bei unserem Webserver gibt es keine Autorisierung, Login durch Passwort, dies würde die gesamte Struktur komplizieren. Für den Prototyp ist dies nicht erforderlich. Daher basiert der gesamte Schutz auf der Datei robots.txt, der Abwesenheit index.phpund diesem geheimen Schlüssel für den Zugriff.


    Das PHP-Hauptskript weather.phpakzeptiert eine einfache HTTP-GET-Anforderung mit Daten und speichert sie in den entsprechenden Datenbanktabellen. Wenn der Schlüssel $access_keynicht übereinstimmt, wird die Anfrage abgelehnt.


    Das Skript weather-view.phpdient zum Anzeigen von Datentabellen und enthält Hyperlinks zu anderen Skripts der Webschnittstelle. Ruf ihn so an


    http://ваш хост/ваш путь/weather-view.php?k=ваш access_key

    Zum Beispiel


    http://yourhost/iot/weather-view.php?k=12345

    weather-view.php Zeigt einfache Tabellen an, an die Sie sich erinnern müssen:


    • Der Sensor mit der ID 11 ist der Home-Sensor auf dem Server.
    • Der Sensor mit der ID 20 ist ein Außensensor.

    Das Skript function.phpenthält Funktionen, die allen PHP-Skripts gemeinsam sind.


    Das Skript chart-dht.phpist für das Zeichnen von Diagrammen mit Google Charts verantwortlich . Hier ist zum Beispiel ein Diagramm der Versorgungsspannung eines Fenstersensors. An einem sonnigen Tag steigt die Spannung auf Kosten der Solarbatterie an, und die Stromversorgung der Batterien entlädt sich allmählich.


    Graph


    export-dht.phpexportiert Daten aus MySQL-Datenbanktabellen in eine CSV-Datei. Für den weiteren Import und die Analyse in Tabellenkalkulationen.


    export-voltage.phpexportiert Spannungsversorgungsdaten von einem Fenstersensor aus einer MySQL-Datenbank in eine CSV-Datei. Nützlich zum Debuggen.


    truncate.phplöscht alle Tabellen, d. h. löscht alle unsere Daten. Nützlich zum Debuggen. Es gibt keine Links zu diesem Skript weather-view.php, daher sollte es über einen direkten Link in der Adressleiste des Browsers mit der Angabe aufgerufen werden $access_key.


    Beim Empfangen von Daten wird häufig eine Funktion verwendet mysqli_real_escape_string(), um zu verhindern, dass falsche Werte in die Datenbank gelangen.


    Vergessen Sie nicht, das Stammverzeichnis Ihrer Website robots.txtzu setzen, um zu verhindern, dass es in die Suchmaschinen gelangt.


    ESP8266, WiFi und Datenübertragung


    Nun kehren wir zur Skizze zurück server.ino, zu dem Teil, der eine Verbindung zum WLAN-Zugangspunkt herstellt und die Daten an den Webserver sendet.


    Wie ich bereits schrieb, konnte ich keine normale Bibliothek für Arduino finden, um das ESP8266-Modul mit AT-Befehlen zu steuern. Ich musste mich selbst "kollektivieren". Ich möchte Sie auch daran erinnern, dass Sie die Firmware einer bestimmten Version in ESP8266-01 aktualisieren müssen. Und jetzt, wenn alles fertig ist, lassen Sie uns analysieren, wie es funktioniert.


    Um auf den Webserver in der Skizze zuzugreifen server.ino, müssen Sie diese Konstanten ändern.


    constString DEST_HOST = "ваш хост"; // например habr.comconstString DEST_PORT = "ваш порт"; // обычно 80constString DEST_URL = "/ваш путь/weather.php";
    constString SOURCE_KEY= "ваш ключ доступа"; // должен совпадать с $access_key из config.php

    In server.inoder Funktion void setup()wird der ESP8266 zuerst in den Stationsmodus geschaltet, d. H. er beginnt als WiFi-Client zu arbeiten


    espSendCmd(«AT+CWMODE_CUR=1», «OK», 3000);

    gefolgt von der Verbindung zum Zugangspunkt


    espState = espConnectToWiFi();

    Wenn die Verbindung nicht auftritt, wird der Versuch wiederholt (einmalig).


    if ( espState != ESP_SUCCESS ) {
      delay(5000);
      Serial.println("WiFi not connected! Try again ...");
      espConnectToWiFi();
    }

    Wählen Sie dann einen einzelnen TCP / IP-Verbindungsmodus aus.


    espSendCmd("AT+CIPMUX=0", "OK", 2000);

    Beim Senden von Daten von DHT-Sensoren an einen Webserver wird eine Funktion verwendet, die den Datentyp als angibt type=dht


    espSendData( "type=dht&t=" + String(dhtData.temperature) + "&h=" + String(dhtData.humidity) + "&v=" + String(dhtData.voltage) + "&s=" + String(CLIENT_ADDRESS) );

    Beim Senden von Daten von BMP-Sensoren an einen Webserver wird dieselbe Funktion verwendet, die den Datentyp angibt type=bmp


    espSendData( "type=bmp&t=" + String(temperature_bmp) + "&p=" + String(pressure_bmp) + "&s=" + String(CLIENT_ADDRESS) );

    Die Funktion espSendData()akzeptiert die HTTP-GET-Anforderungszeichenfolge als Eingabe und sendet sie an den Ziel-Webserver.


    Intern wird espSendData()die Verfügbarkeit des ESP-Moduls überprüft, indem der Befehl „AT“ gesendet wird. Anschließend wird die WLAN-Verbindung überprüft und gegebenenfalls erneut verbunden. Dann werden die Daten gesendet und die TCP-Verbindung wird geschlossen.


    Android App


    Wenn heute schon jeder eine LED blinken kann, werden Sie niemanden mit einer Wetterstation überraschen. Wenn aber der ungerade Job über WLAN mit dem Server kommunizieren kann, einen Web-Maulkorb und eine mobile Anwendung hat, dann ist dies schon etwas! Der Server bedeutet hier natürlich den Anwendungsserver, d.h. In unserem Fall handelt es sich hierbei um PHP-Bindung und MySQL. Nicht die Kirschen auf den Kuchen bekommen, nämlich die Anwendung für das Android-Schreiben, mit der wir uns jetzt beschäftigen.


    Architektur


    Die Architektur der gesamten Wetterstation-Softwareplattform ist einfach:


    • Der Serverteil (zentrale Einheit) der Wetterstation sammelt Daten von Remote-Sensor-Clients
    • Dann sendet er auch Daten an den Webanwendungsserver, der diese Daten in der Datenbank speichert
    • Eine Anwendung auf Android (oder einer anderen Remote-Anwendung: iOS, Browser) fordert Daten vom Webserver an und zeigt sie auf dem Bildschirm an.

    Auf dem Bildschirm des Android-Geräts werden die aktuellen Sensorwerte angezeigt.


    HTTP GET und JSON


    Die Frage, die zuerst gelöst werden muss, ist, wie Daten vom Webserver an die Android-Anwendung übertragen werden.


    Es gibt keine Notwendigkeit, etwas zu erfinden, alles wurde bereits für uns erfunden - das sind HTTP GET und JSON.


    In unserem Fall kann eine einfache GET-Anforderung an den Webserver manuell kompiliert und debuggt werden, während die Android-Anwendung noch nicht bereit ist.


    Java und Android verfügen über vorgefertigte Bibliotheken für die Verarbeitung von Daten im JSON-Format. Das JSON-Textformat ist für Menschen lesbar, was zum Debuggen nützlich ist.


    Erstellen Sie ein neues last-data-to-json.php- Skript auf dem Webserver des Webservers, um die aktuellen Daten von den Wetterstationssensoren zu generieren .


    Aufruf des Skripts:


    http://<хост>/last-data-to-json.php?k=<access_key>

    wo <access_key>, wie wir uns erinnern, der geheime Schlüssel für den Zugriff auf die Datenbank ist.


    Beispielantwort im JSON-Format:


    {
        "DHT 11":{
            "idSensor":"11",
            "dateCreate":"2016-04-20 18:06:03",
            "temperature":"19",
            "humidity":"26",
            "voltage":"5.01"
        },
        "DHT 20":{
            "idSensor":"20",
            "dateCreate":"2016-04-18 07:36:26",
            "temperature":"10",
            "humidity":"26",
            "voltage":"3.7"
        },
        "BMP 11":{
            "idSensor":"11",
            "dateCreate":"2016-04-20 18:06:22",
            "temperature":"19",
            "pressure":"987.97"
        }
    }

    Es muss daran erinnert werden, dass wir 3 Sensoren haben. Ihre ID und ihr Typ (DHT oder BMP) sind im gesamten Code der Wetterstation fest codiert. Diese Art der Hardcord-Codierung ist ideologisch falsch, aber für einen knienden Prototyp (wo eine schnelle und einfache Lösung erforderlich ist) ist dies ein vernünftiger Kompromiss.


    $idSensor = 11; // домашний DHT датчик
    $idSensor = 11; // домашний BMP датчик
    $idSensor = 20; // заоконный DHT датчик

    Das Skript last-data-to-json.phpentnimmt die neuesten Daten aus der Datenbank von diesen verschiedenen Sensortypen und packt sie im JSON-Format. Ein Beispiel von Daten aus der Datenbank "von Ende" wird auf diese Weise durchgeführt:


    SELECT <поля> FROM <таблица> ORDERBYidDESCLIMIT1;

    Android


    Jetzt schreiben wir eine einfache Android-Anwendung, die JSON-Daten abfragt, empfängt, dekodiert und Informationen auf dem Bildschirm anzeigt.


    Unsere Android-Anwendung wird so einfach wie möglich sein, nur das Wesen der Technologie. Um dieses "Skelett" herum wird es bereits möglich sein, verschiedene "Schönheiten" zu drehen.


    Hier ist ein Screenshot von dem, was enden sollte.


    Android


    Wie Sie sehen, ist die Benutzeroberfläche nur spartanisch, basierend auf LinearLayout, nichts überflüssig.


    Oben im TextView werden die ID der Sensoren und ihre meteorologischen Daten angezeigt. Die Schaltfläche "Update" löst eine wiederholte Anfrage an den Webserver aus. Next in EditText ist die einzige Einstellung des Programms - dies ist die URL der Anfrage im Formular


    http://<ваш хост>/last-data-to-json.php?k=<access_key>

    Was ist zu beachten?


    Fügen Sie im Manifest Zeilen hinzu, die das Internet zulassen, und überprüfen Sie den Status der Netzwerkverbindung:


    <uses-permissionandroid:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permissionandroid:name="android.permission.INTERNET" />

    Das Arbeiten mit dem Netzwerk und das Empfangen von Daten von der Website ist wie folgt.


    Verwenden Sie AsyncTask, um eine Hintergrundaufgabe getrennt vom Hauptbenutzeroberflächenthread zu erstellen. Diese Hintergrundaufgabe nimmt die Anforderungs-URL und verwendet sie zum Erstellen HttpURLConnection.


    Nachdem die Verbindung hergestellt wurde, lädt AsyncTask den Inhalt der Webseite (JSON) als InputStream. Als Nächstes wird InputStream in eine Zeichenfolge konvertiert, die mit JSONObject dekodiert und in der Benutzeroberflächenmethode angezeigt wird onPostExecute().


    Ändern Sie in MainActivity.java die URL in Ihre:


    privatestaticfinal String 
      defUrl = "http://host/dir/last-data-to-json.php?k=<ваш ключ>";

    Es wird standardmäßig verwendet, wenn Sie die Android-Anwendung zum ersten Mal starten.


    Epilog


    Nun, etwas hat schon verdient. Dann kann man etwas optimieren, ersetzen, alles rausschmeißen, aber auch etwas ausleihen.


    Ein separater großer Wundenpunkt ist der Energieverbrauch . Ich empfehle, Kommentare zu Beiträgen zu lesen, wo es viele praktische Ratschläge gibt.


    Bis zur Unendlichkeit ... und darüber hinaus.


    Jetzt auch beliebt: