DHT11 Sensor mit Arduino Ethernet Shield und ThingSpeak

Da mein Rondostat HR20E, ein automatisches Heizkörperthermostat, unter der Woche einen Ausfall hatte und ich abends einen Raum mit sommerlichen 30°C vorgefunden habe, habe ich mir ein kleines Projekt zusammengestellt, mit dem ich die aktuellen Messwerte ins Internet stellen kann, um zu kontrollieren, ob das Thermostat mal wieder spinnt. Die Wahl für den Datendienst fiel relativ schnell auf ThingSpeak, da hier eine gute Arduino Unterstützung vorhanden ist.

In meiner Hardware-Grabbelkiste habe ich außerdem einen DHT11 Temperatur- und Luftfeuchtigkeitssensor gefunden, der mit 5V betrieben wird und damit direkt an den Arduino angeschlossen werden kann, was den Aufbau natürlich vereinfacht. Ein Arduino Ethernet Shield stellt die Verbindung zum Internet her.

Das Ergebnis könnte auf der ThingSpeak Seite dann bspw. so aussehen:

Hardware

Die Hardware ist aus den bereits genannten Gründen nichts besonderes. Das Arduino Ethernet Shield wird einfach nur auf den Arduino UNO aufgesteckt und das war es schon. Den DHT11 Sensor verbindet man dann noch mit +5V, GND und - in meinem Fall - mit Pin 7 des Ethernet Shields. Die folgende Fritzing Skizze zeigt das ganz schön.

Software

Die Software besteht im Prinzip aus drei Teilen:

  • Ethernet Shield initialisieren
  • DHT11 Sensor ansprechen
  • ThingSpeak Kanal aktualisieren

Ethernet Shield

Um das Ethernet Shield im Arduino Sketch anzusprechen, muss die Zeile

#include <SPI.h>
#include <Ethernet.h>

zu Beginn des Sketches eingefügt werden. Danach folgt die Konfiguration der Netzwerkadressen. Eine Konfiguration per DHCP ist auch möglich, weiteres findet man dazu in der offiziellen Referenz zum Arduino Ethernet Shield. Die eigentliche Initialisierung erfolgt dann in der „setup“-Methode mit

Ethernet.begin(mac, ip, myDns, gateway, subnet);

DHT Sensor

Zum Ansprechen des DHT11 Sensors verwende ich die DHTLib von Rob Tillaart, die neben dem DHT11 auch den DHT21, DHT22, DHT33 und DHT44 unterstützt. Um die Bibliothek einzubinden, muss man die auf der Webseite der Bibliothek angegebenen Dateien „dht.c“ und „dht.h“ in das „Libraries“ Verzeichnis eures Benutzers in ein Verzeichnis „DHT“ kopieren. Hört sich komplizierter an, als es ist. Auf meinem Windows 10 Rechner liegt das Verzeichnis unter „c:\Benutzer\<Benutzername>\Dokumente\Arduino\libraries\DHT“. Leider gibt es die Bibliothek noch nicht direkt im Arduino Bibliotheksmanager (unter Sketch-Bibliothek einbinden), aber vielleicht ändert sich das in Zukunft ja noch.

Hat man das Verzeichnis angelegt, dann kann man im Sketch die Bibliothek über

#include <dht.h>

einbinden. Um die Bibliothek im Programm zu nutzen, legt man eine Variable für den Sensor an und definiert den Pin, an dem der Sensor hängt:

#define DHT11_PIN 7
 
dht DHT;

Die Abfrage des Sensors erfolgt dann in der „loop()“ Methode und zwar über die „read11()“ Methode. Man erhält danach dann auch die Werte für die Temperatur und die Luftfeuchtigkeit:

int chk = DHT.read11(DHT11_PIN);
switch (chk)
{
  case DHTLIB_OK:  
    Serial.print("OK,\t"); 
    break;
 
  case DHTLIB_ERROR_CHECKSUM: 
    Serial.print("Checksum error,\t"); 
    break;
 
  case DHTLIB_ERROR_TIMEOUT: 
    Serial.print("Time out error,\t"); 
    break;
 
  default: 
    Serial.print("Unknown error,\t"); 
    break;
}
 
float humidity = DHT.humidity;
float temperature = DHT.temperature;

ThingSpeak

Die ThingSpeak Bibliothek kann man glücklicherweise über „Sketch-Bibliothek einbinden“ in die Umgebung integrieren. Dazu einfach den entsprechenden Menüpunkt in der Arduino IDE aufrufen und „Bibliotheken verwalten“ aufrufen. In dem „Bibliotheksverwalter“ Fenster kann man in der Suche dann „ThingSpeak“ eingeben und die entsprechende Bibliothek dann installieren.

Um die Bibliothek im Sketch verwenden zu können, muss auch hier ein Include hinzugefügt werden:

#include <ThingSpeak.h>

Damit man die ThingSpeak API nutzen kann, muss sowohl die Kanalnummer (Channel Number) und der API Key definiert werden. Beides kann auf der ThingSpeak Webseite nach dem Anlegen eines Kanals gefunden werden. Im Quelltext sieht das dann etwa so aus (nein, das sind keine echten Daten ;-)):

unsigned long myChannelNumber = 12345;
const char * myWriteAPIKey = "XXYYXXYYXXYYXXYY";

In der „loop()“ Methode wird dann nach der Ethernet Shield Initialisierung die ThingSpeak API initialisiert.

ThingSpeak.begin(client);

In meinem Fall möchte ich gleichzeitig zwei Werte (Fields) bei ThingSpeak aktualisieren - die Temperatur und die Luftfeuchtigkeit. Im Schritt vorher (siehe „DHT Sensor“) haben wir bereits die Werte aus dem Sensor ausgelesen. Die Werte müssen nun nur noch in der API angelegt und an ThingSpeak gesendet werden. Das machen wir aber natürlich nur dann, wenn die Sensordaten erfolgreich ausgelesen werden konnten. Mittels der „setField(…)“ Methode der ThingSpeak API können die einzelnen Felder (Fields) in einem Kanal (Channel) gesetzt werden. Das Absenden der Daten erfolgt dann mit der Methode „writeFields(…)“, die als Übergabeparameter die Kanalnummer (Channel Number) und den API Key bekommt. Da ThingSpeak in der kostenlosen Version nur Aktualisierungen nur in 15 Sekunden Schritten erlaubt, wird am Ende noch ein „dely(20000)“ angehängt - das reicht für meine Zwecke auf jeden Fall aus.

if (chk == DHTLIB_OK)
{
  ThingSpeak.setField(1,temperature);
  ThingSpeak.setField(2,humidity);
  ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
  delay(20000); // ThingSpeak will only accept updates every 15 seconds.
}

Der komplette Sketch

Das war es dann auch schon. Abschließend folgt noch der komplette Sketch, der neben der oben beschriebenen Programmlogik zusätzlich auch noch eine halbwegs vernünftige Debugausgabe über das serielle Interface des Arduinos enthält. Evtl. hilft euch das ja bei einem eigenen kleinen Projekt mit der ThingSpeak API weiter.

#include <dht.h>
#include "ThingSpeak.h"
 
// Use wired ethernet shield
#include <SPI.h>
#include <Ethernet.h>
 
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 200, 200);
IPAddress myDns(192, 168, 200, 1);
IPAddress gateway(192, 168, 200, 1);
IPAddress subnet(255, 255, 255, 0);
EthernetClient client;
 
unsigned long myChannelNumber = 12345;
const char * myWriteAPIKey = "XXYYXXYYXXYYXXYY";
 
// use DHT library
#define DHT11_PIN 7
 
dht DHT;
 
void setup() {
  Serial.begin(115200);
  Serial.println("DHT TEST PROGRAM ");
  Serial.print("LIBRARY VERSION: ");
  Serial.println(DHT_LIB_VERSION);
  Serial.println();
  Serial.println("Type,\tstatus,\tHumidity (%),\tTemperature (C)");
 
  // initialize Ethernet Shield
  Ethernet.begin(mac, ip, myDns, gateway, subnet);
 
  // initialize ThingSpeak client
  ThingSpeak.begin(client);
}
 
void loop() {
  // READ DATA
  Serial.print("DHT11, \t");
  int chk = DHT.read11(DHT11_PIN);
  switch (chk)
  {
    case DHTLIB_OK:  
    Serial.print("OK,\t"); 
    break;
    case DHTLIB_ERROR_CHECKSUM: 
    Serial.print("Checksum error,\t"); 
    break;
    case DHTLIB_ERROR_TIMEOUT: 
    Serial.print("Time out error,\t"); 
    break;
    default: 
    Serial.print("Unknown error,\t"); 
    break;
  }
 
  float humidity = DHT.humidity;
  float temperature = DHT.temperature;
 
  // DISPLAY DATA
  Serial.print(humidity,1);
  Serial.print(",\t");
  Serial.println(temperature,1);
 
  // publish to ThingSpeak
  // Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different
  // pieces of information in a channel.  Here, we write to field 1.
 
  // only publish if everything was ok
  if (chk == DHTLIB_OK)
  {
    ThingSpeak.setField(1,temperature);
    ThingSpeak.setField(2,humidity);
    ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
    delay(20000); // ThingSpeak will only accept updates every 15 seconds.
  }
  else
  {
    delay(1000);
  }
}
elektronik/dht11_sensor_mit_arduino_ethernet_shield_und_thingspeak.txt · Zuletzt geändert: 2016/02/12 22:17 von octoate
CC Attribution-Noncommercial-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0