DHT22 - Wet­ter­sta­ti­on Anzei­ge im Internetbrowser

Lese­zeit: 8 Minu­ten
Seite als PDF
Navi­ga­ti­on

Die mit dem Tem­pe­ra­tur­sen­sor DHT22 gemes­se­nen Wer­te sol­len in einem Inter­net­brow­ser ange­zeigt werden.

So sieht es aus:

Pinbelegung DHT22

Der Sen­sor DHT22 misst die Tem­pe­ra­tur und die Luft­feuch­tig­keit. Das hier ver­wen­de­te Bau­teil besitzt drei Anschlüs­se.
Die Ver­si­on mit vier Pins muss in der Rei­hen­fol­ge 5V → Daten (Pin) → leer → GND geschal­tet werden.

Ethernet-Shield

Für die­se Anlei­tung benö­tigst du ein soge­nann­tes „Shield“, eine Pla­ti­ne, die ein­fach auf den Ardui­no auf­ge­steckt wird. Auf ihr befin­det sich ein LAN-Anschluss (RJ45).

Benö­tig­te Bauteile:

  • Tem­pe­ra­tur­sen­sor DHT22
  • Ethernet-Shield
  • RTC-Modul DS 3231
  • Lei­tungs­dräh­te

Baue die Schal­tung auf
(Fah­re mit der Maus über das Bild, um die Bezeich­nun­gen der Bau­tei­le zu sehen)

Für das Pro­gramm brauchst du eine freie IP-Adresse und eine freie MAC-Adresse in dei­nem loka­len Netz­werk.
Im Regel­fall befin­det sich in einem loka­len Netz­werk ein DHCP-Server, der jedem Gerät im Netz­werk auto­ma­tisch eine IP-Adresse zuteilt. Im Pro­gramm wird eine über DHCP ver­ge­be­ne Adres­se verwendet.

Wenn du eine ➨sta­ti­sche IP ver­wen­den willst:

Wenn die Tem­pe­ra­tur­mes­sung über einen län­ge­ren Zeit­raum (meh­re­re Tage) ein­ge­setzt wer­den soll, emp­fiehlt sich die Ver­ga­be einer fes­ten IP-Adresse, weil nach der soge­nann­ten „lea­se­time“ die IP wie­der neu ver­ge­ben wird.
Wei­te­re Informationen

Die MAC-Adresse ist die Hardware-Adresse jeder ein­zel­nen Netz­werk­schnitt­stel­le (LAN oder WLAN), mit der jedes Gerät im Netz­werk ein­deu­tig iden­ti­fi­ziert wer­den kann.

Sie besteht aus sechs Bytes in hexa­de­zi­ma­ler Schreib­wei­se, die durch „:“ oder „-“ getrennt werden.

Du kannst die im Pro­gramm ver­wen­de­te „erfun­de­ne“ MAC-Adresse über­neh­men: Die Gefahr, dass sich ein Gerät mit der glei­chen MAC-Adresse im Netz­werk befin­det, ist äußerst gering.

Benö­tig­te Biblio­the­ken:
Sketch → Biblio­thek ein­bin­den → Biblio­the­ken verwalten

Bin­de die benö­tig­ten Biblio­the­ken ein und lege die Varia­blen fest.:

# include <Ethernet.h>
# include <SimpleDHT.h>
# include <RTClib.h>

// Name des RTC-Moduls
RTC_DS3231 rtc;

int SENSOR_DHT22 = 8;

// Namen des Sensors (dht22)
SimpleDHT22 dht22(SENSOR_DHT22);

// MAC-Adresse und IP definieren
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};

// festeIP = false -> IP-Adresse über DHCP vergeben
bool festeIP = true;

// feste IP
IPAddress ip(192, 168, 1, 200);

// Name des Servers vergeben
EthernetServer Server(80);

byte Zaehler = 0;
const byte AnzahlDaten = 11;

// Arrays für die Speicherung
String gespeicherteTemperatur[AnzahlDaten];
String gespeichertesDatum[AnzahlDaten];
String gespeicherteLuftfeuchtigkeit[AnzahlDaten];

Der setup-Teil star­tet das RTC-Modul und for­dert über DHCP eine IP an oder legt manu­ell eine fest:

void setup()
{
  // RTC-Modul starten
  rtc.begin();
  /*
    wenn Datum und Zeit nicht korrekt -> Datum/Zeit setzen
    Jahr, Monat, Tag, Stunde, Minute, Sekunde
    keine führende 0 setzen
    Beispiel:
    rtc.adjust(DateTime(2018, 10, 25, 7, 2, 30));
  */
  // rtc.adjust(DateTime(2018, 12, 29, 21, 58, 30));
  Serial.begin(9600);

  // Ethernet starten feste IP
  if (festeIP) Ethernet.begin(mac, ip);

  // Ethernet starten DHCP
  else Ethernet.begin(mac);

  // Server starten
  Server.begin();

  Serial.begin(9600);

  DateTime aktuell = rtc.now();

  // Datum und Zeit holen
  char Datum[] = "DD.MM.YYYY ";
  char Zeit[] = "hh:mm:ss Uhr";

  Serial.print(aktuell.toString(Datum));
  Serial.print(aktuell.toString(Zeit));

  // zur Kontrolle IP-Adresse anzeigen
  // localIP -> Adresse, die im Browser eingegeben wird
  Serial.print(F(" IP des Ethernet-Shields: "));
  if (festeIP) Serial.print(F("statische IP: "));
  else Serial.print(F("IP DHCP: "));
  Serial.println(Ethernet.localIP());
}

Im Seri­el­len Moni­tor wird die IP des Ethernet-Shields ange­zeigt. Die­se Adres­se wird in einem Brow­ser eingegeben.

Der loop-Teil. Beach­te die Kommentare.

Um den Spei­cher­platz zu mini­mie­ren, wird bei allen print und println Anwei­sun­gen das ➨F-Makro eingesetzt.

void loop()
{
  DateTime aktuell = rtc.now();

  float Temperatur;
  float Luftfeuchtigkeit;
  String Nummer;

  // auf Clienten warten ...
  EthernetClient Client = Server.available();

  // neue Anfrage
  if (Client)
  {

    // solange der Client verbunden ist ...
    while (Client.connected())
    {
      if (Client.available())
      {
        char Zeichen = Client.read();

        // \n = Seite vom Clienten vollständig geladen
        if (Zeichen == '\n')
        {
          // HTTP-Anforderung senden
          Client.println(F("HTTP/1.1 200 OK"));
          Client.println(F("Content-Type: text/html"));
          Client.println("Connection: close");

          // Leerzeile zwingend erforderlich
          Client.println();

          /*
            HTML-Seite aufbauen
            die folgenden Anweisungen müssen
            mit print oder println gesendet werden
            println "verschönert" den Quelltext
            (jede Anweisung in einer eigenen Zeile)
          */
          Client.println(F("<!doctype html>"));
          Client.println(F("<html>"));
          Client.println(F("<body>"));

          // alle 60 Sekunden aktualisieren mit meta-Tag
          Client.println(F("<meta http-equiv=\"refresh\" content=\"60\">"));

          Client.println(F("<h1>Temperatur und Luftfeuchtigkeit messen"));
          Client.println(F("</h1>"));
          Client.println(F("<hr />"));
          Client.print(F("<h2>Letzte Messung: "));
          /*
              Wochentag anzeigen
              0 = Sonntag
              1 = Montag
              ...
              6 = Samstag
          */
          switch (aktuell.dayOfTheWeek())
          {
            case 0:
              Client.print(F("Sonntag"));
              break;
            case 1:
              Client.print(F("Montag"));
              break;
            case 2:
              Client.print(F("Dienstag"));
              break;
            case 3:
              Client.print(F("Mittwoch"));
              break;
            case 4:
              Client.print(F("Donnerstag"));
              break;
            case 5:
              Client.print(F("Freitag"));
              break;
            case 6:
              Client.print(F("Samstag"));
              break;
          }
          Client.print(", ");

          // Datum und Zeit schreiben
          char Datum[] = "DD.MM.YYYY ";
          char Zeit[] = "hh:mm:ss Uhr";

          Client.print(aktuell.toString(Datum));
          Client.print(F(" "));
          Client.print(aktuell.toString(Zeit));
          Client.println(F("</h2>"));
          Client.println(F("<hr />"));

          // Button anzeigen und formatieren
          Client.println(F("<form>"));
          Client.print(F("<td><input style='font-size:14pt; font-weight:bold;"));
          Client.print(F(" background-color:#55A96B;"));
          Client.print(F(" width:200px; cursor:pointer;"));
          Client.print(F(" border-radius:5px;border: 2px solid black;' type='button'"));
          Client.println(F(" onClick='history.go(0)'"));
          Client.println(F(" value=\"aktualisieren\">"));
          Client.println(F("</form>"));
          Client.println(F("<hr />"));

          dht22.read2(&Temperatur, &Luftfeuchtigkeit, NULL);

          // in Strings umwandeln, . durch , ersetzen
          String AnzeigeTemperatur = String(Temperatur);
          AnzeigeTemperatur.replace(".", ",");

          // Luftfeuchtigkeit lesen
          String AnzeigeLuftfeuchtigkeit = String(Luftfeuchtigkeit);
          AnzeigeLuftfeuchtigkeit.replace(".", ",");

          Client.print(F("<b>Temperatur: <br>"));
          Client.println(AnzeigeTemperatur + " &deg;C</b>");
          Client.println(F("<br>"));
          Client.print(F("<br><b>Luftfeuchtigkeit: <br>"));
          Client.println(AnzeigeLuftfeuchtigkeit + " %</b><hr />");

          // Datum speichern
          gespeichertesDatum[Zaehler] = aktuell.toString(Datum);
          gespeichertesDatum[Zaehler] = gespeichertesDatum[Zaehler] + aktuell.toString(Zeit);

          // Temperatur speichern
          gespeicherteTemperatur[Zaehler] = AnzeigeTemperatur;

          // Luftfeuchtigkeit speichern
          gespeicherteLuftfeuchtigkeit[Zaehler] = AnzeigeLuftfeuchtigkeit;

          Client.println(F("<b>Gespeicherte Werte:<br></b>"));

          // Daten anzeigen
          for (int i = 0; i <= Zaehler - 1; i ++)
          {
            Client.println(String(i + 1) + ": ");

            switch (aktuell.dayOfTheWeek())
            {
              case 0:
                Client.print(F("Sonntag"));
                break;
              case 1:
                Client.print(F("Montag"));
                break;
              case 2:
                Client.print(F("Dienstag"));
                break;
              case 3:
                Client.print(F("Mittwoch"));
                break;
              case 4:
                Client.print(F("Donnerstag"));
                break;
              case 5:
                Client.print(F("Freitag"));
                break;
              case 6:
                Client.print(F("Samstag"));
                break;
            }
            Client.print(", ");

            Client.println(gespeichertesDatum[i]);
            Client.print(F(" | Temperatur:  &#9654; "));
            Client.println(gespeicherteTemperatur[i]);
            Client.print(F(" &deg;C" ));
            Client.print(F(" | Luftfeuchtigkeit:  &#9654; "));
            Client.println(gespeicherteLuftfeuchtigkeit[Zaehler]);
            Client.println(F("%"));
            Client.println(F("<br>"));
          }
          Client.println(F("<hr />"));

          // IPs anzeigen
          Client.print(F("<b>Eigene IP: "));
          Client.print(Client.remoteIP());
          Client.println(F("<br>"));
          Client.println(F("IP des Ethernet-Shields: "));
          Client.print(Ethernet.localIP());
          Client.println(F("</b>"));
          Client.println(F("</body>"));
          Client.println(F("</html>"));

          // Zeit, um die Antwort zu übertragen
          delay(1);

          // Verbindung beenden
          Client.stop();

          // Zaehler erhöhen und bei > AnzahlDaten zurücksetzen
          if (Zaehler < AnzahlDaten) Zaehler ++;
          if (Zaehler >= AnzahlDaten) Zaehler = 0;
        }
      }
    }
  }
}

Wenn die Sei­te mit Auf­ruf der IP nicht ange­zeigt wird, ver­su­che ein http:// davorzusetzen.


Startseite
Aufgaben A-Z
Suchen
Downloads
Fehlermeldungen
Seite als PDF

Ver­wand­te Aufgaben:


Letzte Aktualisierung: 4. Apr 2021 @ 18:59