Arduino – Temperatur- und Luftfeuchte auf Twitter posten

Meine Freundin hat eine Wäscherei, in der es schon mal vorkommen kann, das über Nacht ein Schlauch platzt. Bei der ganzen Elektronik in diesem Geschäft könnte es aber auch passieren dass ein Brand entsteht. Nun habe ich mir Gedanken darüber gemacht, wie man so schnell wie möglich davon in Kenntnis gesetzt werden könnte wenn doch mal eines dieser Szenarien eintreten sollte.

Da meine Freundin nicht so viel investieren kann, kam ich auf die Idee, die Temperatur und die Luftfeuchte durch den sowieso vorhandenen DHT22 Sensor zu ermitteln. Sobald die Temperatur einen Wert von 50°C übersteigt oder die Luftfeuchte einen Wert von über 75% erreicht, sollen diese Werte automatisch an Twitter gesendet werden.

DHT22 Sensor mit dem Arduino verbinden

DHT22 - Arduino Anschlussbelegung

  • Pin 1 (links)  an +5V
  • Pin 2  an digitalen Pin 9 am Arduino
  • Pin 3 bleibt frei
  • Pin 4 (rechts) an Ground
  • Pin 2 (data) und Pin 1 (power) werden noch mit einem 10k Widerstand verbunden

 

Vorbereitungen

Twitter Token generieren

OAuth ist ein offenes Protokoll, das eine standardisierte, sichere API-Autorisierung erlaubt. Dieses Protokoll benötigen wir um unsere Werte auf Twitter veröffentlichen zu können. Anstatt dass man nun seine Twitter Userdaten preisgibt, sendet man einen Autorisierungstoken. Diesen Token können Sie ganz leicht über folgenden link generieren lassen. [Token generieren]

 

Arduino-Libraries installieren

Falls Ihnen eine der benötigten Arduino Libraries fehlt, können Sie diese hier herunter laden.

 

Arduino-Sketch

Das Sketch ermittelt ständig die aktuelle Temperatur und die Luftfeuchtigkeit.
Wenn die Temperatur oder die Luftfeuchte einen bestimmten Wert überschreiten, wird eine Verbindung zum Twitter-Server aufgebaut. Anschließend wird die Meldung wie im untersten Bild zu sehen bei Twitter gepostet. Die Variable sleep vom Typ boolean ist dafür zuständig, dass in der Zeit, in der einer der Werte zu hoch ist, nicht ständig ein neuer Eintrag auf Twitter generiert wird. Diese Variable hat standardmäßig den Wert false. Wenn die Temperatur oder die Luftfeuchte nun den maximalwert übersteigen, wird die Variable sleep auf true gesetzt. Der Wert der Variablen bleibt so lange auf true bis beide Werte wieder im Normbereich sind.

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

#include "DHT.h"

#define DHTPIN 9     
#define DHTTYPE DHT22

DHT dht(DHTPIN, DHTTYPE);

byte mac[] = { 0x5A, 0xA2, 0xDA, 0x0D, 0x56, 0x7A };
boolean sleep = false;

Twitter twitter("TWITTERTOKEN EINTRAGEN"); //Hier bitte den Twitter Token eintragen

void setup()
{
  delay(1000);

  Ethernet.begin(mac);

  Serial.begin(9600);

  dht.begin();
}

void loop()
{
  getDHT22();
  delay(10000);
}

//Temperatur des DHT22 ermitteln
void getDHT22()
{
  int h = dht.readHumidity();     //Luftfeuchte auslesen
  int t = dht.readTemperature();  //Temperatur auslesen

  String tempString = String(t);  //Temperatur
  String humiString = String(h);  //Luftfeuchte

  //Prüfen ob eine gültige Zahl zurückgegeben wird. Wenn NaN (not a number) zurückgegeben wird, dann Fehler ausgeben.
  if (isnan(t) || isnan(h)) 
  {
    Serial.println("DHT22 konnte nicht ausgelesen werden");
  } 
  else
  {
    Serial.println("FLUUUX - TechBlog | Temperatur: " + tempString + char(186) + String("C") + ", Luftfeuchte: " + humiString + "%"); 

    if(t > 50 || h > 75)
    {
      if(sleep == false)
      {      
        Serial.println("FLUUUX - TechBlog | Temperatur: " + tempString + char(186) + String("C") + ", Luftfeuchte: " + humiString + "%"); 

        String TweetString = String("FLUUUX - TechBlog | Temperatur: " + tempString + char(186) + String("C") + ", Luftfeuchte: " + humiString + "%");

        char TempTweet[TweetString.length() + 1];

        TweetString.toCharArray(TempTweet, TweetString.length() + 1);

        sendTwitterMessage(TempTweet);

        sleep = true;
      }
    }
    else
    {
      sleep = false;    
    }
  }
}

//Tweet an Twitter senden 
void sendTwitterMessage(char* tweet)
{
  Serial.println("Verbinde zu Twitter...");

  if (twitter.post(tweet)) 
  {
    int status = twitter.wait();
    if (status == 200) 
    {
      Serial.println("Verbindung hergestellt...");
    } 
    else 
    {
      Serial.print("Fehler: code ");
      Serial.println(status);
    }
  } 
  else 
  {
    Serial.println("Verbindung fehlgeschlagen.");
  }
}

 

Ergebnis:

DHT22-Tweet

Über Enrico S.

Programmierer, Webdesigner, Grafiker, Blogger, Screencaster, Arduino- und eMobility Enthusiast.

2 Kommentare zu “Arduino – Temperatur- und Luftfeuchte auf Twitter posten

  1. Moin Enrico, erstmal dickes Lob an deine Seite und die Arbeit die dahinter steckt. Bei solchen Leuten wie euch, lerne ich immer richtig viel.

    Zum Thema:
    Ist dir aufgefallen, dass man bei Twitter immer nur den Status ein einziges Mal senden kann? also nicht zweimal den selben? Das ist natürlich problematisch im Zusammenhang mit automatischen tweets.

    Ich hab mich mal drann gemacht und auf deiner Basis einen Zeitstempel (NTP-basiert hinten drann zu hängen um so du Duplikation von tweets zu vermeiden.

    Mein folgende Sketch sendet nun alle 15 min. ein Tweet mit der Uhrzeit. Daraus lässt sich jetzt einiges bauen;)

    Gruß Alex

    #include <SPI.h>
    #include <Ethernet.h>
    #include <EthernetUdp.h>
    #include <Time.h>
    #include <Twitter.h> 
    
    byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
    
    unsigned int localPort = 8888;     
    
    IPAddress timeServer(199,167,198,163);
    
    const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the message
    
    byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets 
    
    // A UDP instance to let us send and receive packets over UDP
    EthernetUDP Udp;
    
    time_t prevDisplay = 0; // when the digital clock was displayed
    const  int timeZoneOffset = +1; // GMT zone;
    
    //Twitter
    Twitter twitter(""); //Your Token
    
    
    void setup() 
    {
     // Open serial communications and wait for port to open:
      Serial.begin(9600);
       /*while (!Serial) {
        ; // wait for serial port to connect. Needed for Leonardo only
      }*/
    
      // start Ethernet and UDP
      if (Ethernet.begin(mac) == 0) {
        Serial.println("Failed to configure Ethernet using DHCP");
        // no point in carrying on, so do nothing forevermore:
        for(;;)
          ;
      }
      Udp.begin(localPort);
      setSyncProvider(getNtpTime);
      while(timeStatus()== timeNotSet); // wait until the time is set by the sync provider
    }
    
    void loop()
    {
        if( now() != prevDisplay) //update the display only if the time has changed
      {
        prevDisplay = now();
        digitalClockDisplay(); 
        
      }
    
        
      int h = (hour());
      int m = (minute());
      int s = (second());
      int d = (day());
      int t = (month());
      int y = (year());
      
      
      String hourString = String(h);
      String minuteString = String(m);
      String secondString = String(s);
      String dayString = String(d);
      String monthString = String(t);
      String yearString = String(y);
      
    if (minute()&lt;10 &amp;&amp; second()&lt;10) 
    {
      String TweetString = String(&quot;Arduino Zeitstempel: &quot; + hourString + &quot;:0&quot; + minuteString + &quot;:0&quot; + secondString
      + &quot; | &quot; + dayString + &quot;.&quot; + monthString + &quot;.&quot; + yearString);
    
      char timedateTweet[TweetString.length() + 1];
     
      TweetString.toCharArray(timedateTweet, TweetString.length() + 1);
     
      sendTwitterMessage(timedateTweet);
    }
    
    else if (minute()&lt;10)
    {
      String TweetString = String(&quot;Arduino Zeitstempel: &quot; + hourString + &quot;:0&quot; + minuteString + &quot;:&quot; + secondString
      + &quot; | &quot; + dayString + &quot;.&quot; + monthString + &quot;.&quot; + yearString);
    
      char timedateTweet[TweetString.length() + 1];
     
      TweetString.toCharArray(timedateTweet, TweetString.length() + 1);
     
      sendTwitterMessage(timedateTweet);
    }
    
    else if (second()&lt;10)
    {
      String TweetString = String(&quot;Arduino Zeitstempel: &quot; + hourString + &quot;:&quot; + minuteString + &quot;:0&quot; + secondString
      + &quot; | &quot; + dayString + &quot;.&quot; + monthString + &quot;.&quot; + yearString);
    
      char timedateTweet[TweetString.length() + 1];
     
      TweetString.toCharArray(timedateTweet, TweetString.length() + 1);
     
      sendTwitterMessage(timedateTweet);
    }
    
    else 
    {
      String TweetString = String(&quot;Arduino Zeitstempel: &quot; + hourString + &quot;:&quot; + minuteString + &quot;:&quot; + secondString
      + &quot; | &quot; + dayString + &quot;.&quot; + monthString + &quot;.&quot; + yearString);  
    
      char timedateTweet[TweetString.length() + 1];
     
      TweetString.toCharArray(timedateTweet, TweetString.length() + 1);
     
      sendTwitterMessage(timedateTweet);
    }
    }
    
    void sendTwitterMessage(char* tweet)
    {
      Serial.println(&quot;connecting ...&quot;);
      if (twitter.post(tweet)) {
        int status = twitter.wait(&amp;Serial);
        if (status == 200) {
          Serial.println(&quot;OK.&quot;);
        } else {
          Serial.print(&quot;failed : code &quot;);
          Serial.println(status);
        }
      } else {
        Serial.println(&quot;connection failed.&quot;);
      }
      delay(900000);
    }  
    
    void digitalClockDisplay(){
      // digital clock display of the time
      Serial.print(&quot;Time: &quot;);
      Serial.print(hour());
      printDigits(minute());
      printDigits(second());
      Serial.print(&quot; Date: &quot;);
      Serial.print(day());
      Serial.print(&quot;.&quot;);
      Serial.print(month());
      Serial.print(&quot;.&quot;);
      Serial.print(year()); 
      Serial.println(); 
    }
    
    void printDigits(int digits){
      // utility function for digital clock display: prints preceding colon and leading 0
      Serial.print(&quot;:&quot;);
      if(digits &lt; 10)
        Serial.print(&#039;0&#039;);
      Serial.print(digits);
    }
    
    /*-------- NTP code ----------*/
    unsigned long getNtpTime()
    {
      sendNTPpacket(timeServer); // send an NTP packet to a time server
      delay(1000);
      if ( Udp.parsePacket() ) {  
        // We&#039;ve received a packet, read the data from it
        Udp.read(packetBuffer,NTP_PACKET_SIZE);  // read the packet into the buffer
    
        //the timestamp starts at byte 40 of the received packet and is four bytes,
        // or two words, long. First, esxtract the two words:
    
        unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
        unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);  
        // combine the four bytes (two words) into a long integer
        // this is NTP time (seconds since Jan 1 1900):
        unsigned long secsSince1900 = highWord &lt;&lt; 16 | lowWord; 
        const unsigned long seventyYears = 2208988800UL;     
        // subtract seventy years and add the time zone:
        unsigned long epoch = secsSince1900 - seventyYears + (timeZoneOffset * 3600L);
        return epoch;
      }
      return 0;
    }
    
    // send an NTP request to the time server at the given address 
    unsigned long sendNTPpacket(IPAddress&amp; address)
    {
      // set all bytes in the buffer to 0
      memset(packetBuffer, 0, NTP_PACKET_SIZE); 
      // Initialize values needed to form NTP request
      // (see URL above for details on the packets)
      packetBuffer[0] = 0b11100011;   // LI, Version, Mode
      packetBuffer[1] = 0;     // Stratum, or type of clock
      packetBuffer[2] = 6;     // Polling Interval
      packetBuffer[3] = 0xEC;  // Peer Clock Precision
      // 8 bytes of zero for Root Delay &amp; Root Dispersion
      packetBuffer[12]  = 49; 
      packetBuffer[13]  = 0x4E;
      packetBuffer[14]  = 49;
      packetBuffer[15]  = 52;
    
      // all NTP fields have been given values, now
      // you can send a packet requesting a timestamp: 		   
      Udp.beginPacket(address, 123); //NTP requests are to port 123
      Udp.write(packetBuffer,NTP_PACKET_SIZE);
      Udp.endPacket(); 
    }