Tag 19: ThingSpeak

In den letzten Tagen der Adventszeit beschäftigen wir uns mit einem ganz neuen Thema, nämlich der Internetseite ThingSpeak. Diese Seite wurde speziell für das Thema Internet of Things entwickelt und hält verschiedene praktische Funktionen für Sie bereit.

Bevor Sie also wie sonst üblich, den Aufbau und das Programm angehen, müssen Sie sich zunächst einen Account auf der Seite

www.ThingSpeak.com

erstellen. Loggen Sie sich dann mit Ihren Nutzerdaten unter dem Punkt Sign In ein. Sie sehen eine Seite, die Ihre Channels zeigt. Da Sie noch keine Kanäle haben, wird diese Seite ziemlich leer aussehen. Klicken Sie auf New Channel und vergeben einen Namen, z.B. Light, denn Sie werden in diesem Projekt die Helligkeit messen. Unter dem Punkt Field1 können Sie nun noch einen Namen für das Feld vergeben, evtl. Brightness. Alle anderen Felder können vorerst leer bleiben.

Erstellen eines Kanals auf der ThingSpeak Seite

Erstellen eines Kanals auf der ThingSpeak Seite

Klicken Sie auf Save Channel, um die Einstellungen zu speichern. Sie werden zu der Seite Ihres Channels weitergeleitet, auf der aber nur ein leeres Diagramm zu sehen ist. Klicken Sie in dem darüber liegenden Reiter auf API-Keys. Die Zahlen und Buchstabenfolge die Sie unter dem Punkt Write API Key finden, werden Sie gleich benötigen.

Hier finden Sie den Write Key

Hier finden Sie den Write Key

Hinter dem heutigen Türchen finden Sie erneut ein Kabel. Sie können nun auch dreibeinige Bauteile, wie das IR-Empfangsmodul,  abseits des Steckboards platzieren. Der Aufbau des heutigen Versuchs ist mit dem Versuchsaufbau des 15. Tages identisch. Ein Spannungsteiler mit 10-kΩ-Widerstand und Fototransistor ermöglicht das Messen der aktuellen Helligkeit.

Der Aufbau mit Fototransistor an A0

Der Aufbau mit Fototransistor an A0

Das Programm: Day19_ThinkSpeak1

Das heutige Programm misst nun, ähnlich dem Programm des 15. Tages, die Helligkeit. Doch anders als im vergangenen Versuch werden die Daten direkt an die ThingSpeak Seite gesendet. Diese Seite speichert die Daten nicht nur, sondern stellt sie auch übersichtlich in einem Diagramm dar. Eine sehr praktische Funktion für eine Messstation mit Langzeitüberwachung.

Damit das Programm an die Webseite senden kann, müssen Sie außer Ihren WLAN-Daten zunächst den oben erwähnten API-Key in das Programm unter den Punkt ThingSpeakKEY eintragen. Nach dem Upload empfiehlt es sich, den Serial Monitor zu öffnen. In der Regel sollte eine Update Send Meldung die erfolgreiche Übertragung begleiten. Auf der ThingSpeak Seite können Sie nun wieder auf den Reiter Private View ihres Kanals klicken. Dort sehen Sie das Diagramm Ihres Channels welches alle 10 Sekunden neue Daten empfängt.

Die Messergebnisse im Diagramm

Die Messergebnisse im Diagramm

33 Kommentare

  1. phatbrasil

    Hello All, sorry to bother, does anyone have an example of adding a Authorization Bearer to the HTTP Header of an AT command?

    in curl it would be something like curl -k -X POST -H „Authorization: Bearer “ -d „“ https://

    would this be possible using the pretzel board?

    Thank you in Advance,

    Antworten
  2. stberger

    funktioniert ja prima, aber ich möchte drei werte verschicken, wie muss dann der string für thinkspeak aufgebaut sein?

    Antworten
    1. fk (Beitrag Autor)

      Hi,
      ich übernehme jetzt mal keine Garantie aber ich meine, dass du in der Funktion sendThingPost die msg-Variable so anpassen musst, dass das Ergebniss etwas so aussieht:

      field1=(Field 1 Data)&field2=(Field 2 Data)&field3=(Field 3 Data)

      also (Field X Data) muss dann durch den Messwert ersetzt werden.

      Antworten
      1. stberger

        jawohl, so geht’s! thx

        Antworten
        1. Jan

          Kannst du den Code mal schicken?

          Antworten
      2. Ronald Spitzenberger

        Hallo,

        ich bin spät dran aber, hatte leider im Dezember nicht so viel Zeit. Ich bekomme es irgendwie nicht hin 2 Werte an ThingSpeak zu übermitteln. Ich habe den Code wie folgt abgeändert:
        void loop() {
        int chk = DHT11.read(DHT11PIN);
        if (sendThingPost(ThingSpeakKEY, DHT11.temperature, DHT11.humidity)) debug(„Update Send“);
        Serial.println (String url, String key, String msg, String msg2);
        delay(15000);
        }

        //—————————————–ThingsSpeak Functions————————————

        boolean sendThingPost(String key, float value1, float value2)
        {
        boolean succes = true;
        String Host = „api.thingspeak.com“;
        String msg = „field1=“ + String(value1);
        String msg2 = „&field2=“ + String(value2);
        succes &= sendCom(„AT+CIPSTART=\“TCP\“,\““ + Host + „\“,80″, „OK“);

        String postRequest = createThingPost(„/update“, key, msg, msg2);

        if (sendCom(„AT+CIPSEND=“ + String(postRequest.length()), „>“))
        {
        esp8266.print(postRequest);
        esp8266.find(„SEND OK“);
        if (!esp8266.find(„CLOSED“)) succes &= sendCom(„AT+CIPCLOSE“, „OK“);
        }
        else
        {
        succes = false;
        }
        return succes;
        }

        String createThingPost(String url, String key, String msg, String msg2)
        {
        String xBuffer;

        for (int i = 0; i <= sizeof(thingPost); i++)
        {
        char myChar = pgm_read_byte_near(thingPost + i);
        xBuffer += myChar;
        }

        String append = "api_key=" + key + "&" + msg;
        xBuffer.replace("*URL*", url);
        xBuffer.replace("*LEN*", String( append.length()));
        xBuffer.replace("*APPEND*", append);

        return xBuffer;
        }

        String createThingGet(String url, String key)
        {
        String xBuffer;

        for (int i = 0; i <= sizeof(thingPost); i++)
        {
        char myChar = pgm_read_byte_near(thingPost + i);
        xBuffer += myChar;
        }

        String append = "api_key=" + key;
        xBuffer.replace("POST", "GET");
        xBuffer.replace("*URL*", url);
        xBuffer.replace("*LEN*", String( append.length()));
        xBuffer.replace("*APPEND*", append);

        return xBuffer;
        }

        String createThingGet(String url, String key, String msg, String msg2)
        {
        String xBuffer;

        for (int i = 0; i <= sizeof(thingPost); i++)
        {
        char myChar = pgm_read_byte_near(thingPost + i);
        xBuffer += myChar;
        }

        String append = "api_key=" + key + "&" + msg + msg2;

        xBuffer.replace("POST", "GET");
        xBuffer.replace("*URL*", url);
        xBuffer.replace("*LEN*", String( append.length()));
        xBuffer.replace("*APPEND*", append);

        return xBuffer;
        }

        Wäre schön wenn mir jemand helfen könnte meinen Fehler zu finden. oder einen Tipp zur lösung geben könnte.

        Mit freundlichem Gruß

        Ronald

        Antworten
        1. Kurandas

          Hi, bin ich zu spät?

          Bin kein Pro aber dass du 2 msg strings generierst und zu übergeben suchst sieht schräg aus.
          Dein Code
          String msg = „field1=“ + String(value1);
          String msg2 = „&field2=“ + String(value2);
          succes &= sendCom(„AT+CIPSTART=\“TCP\“,\““ + Host + „\“,80″, „OK“);

          String postRequest = createThingPost(„/update“, key, msg, msg2);

          Mein Code funkst soweit, ich verlängere nur den String msg, keine neue Message:
          String msg = „field1=“ + String(value1) +“&field2=“ + String(value2);

          Hoffe es hilft!

          Antworten
          1. Radla

            Also ich wollte 4 Werte versenden und habe mir den entsprechenden String zusammengebaut. Seltsamerweise wurde dann aber gar nichts mehr übertragen. Sobald ich einen Wert rausgenommen habe, ging es wieder. Dabei war es egal, welchen Wert ich entfernte.
            Nach vielen herumprobieren habe ich den Fehler soweit lokalisiert, das der String einfach zu lang ist und dann gar nichts mehr gesendet wird.
            Ich habe mir jetzt damit geholfen, die Übertragung aufzusplitten und in 15s Abständen zu senden und anschliessend das delay wieder auf den normalen Messabstand zu erhöhen.

  3. Thorsten Jansen

    Hat schon mal jemand versucht, die Daten an eine eigene Website zu schicken?
    Wäre schön, wenn man die Messwerte selber in einer Datenbank sammeln könnte.
    Würde ich mir im Quelltext ja gerne selber erarbeiten, leider ist dieser – wie alle – nicht Dokumentiert.
    Diese „friss oder stirb“ Methode ist einfach zum K++++

    Antworten
    1. Der Sprachgestörte

      Diesen Beitrag finde ich auch nicht gerade appetitlich!

      In den diversen Tagen wurden beide Seiten, senden und empfangen von Daten, gezeigt (und geübt).

      Antworten
    2. Nikdro

      Hallo Thorsten,

      ich habe auch bereits daran gedacht, die Daten in einer eigenen Datenbank abzulegen. Jedoch habe ich bisher nicht die Zeit dazu gefunden eine API zu programmieren, die Daten entgegen nehmen und in der DB ablegen kann. Den Code anzupassen ist glaube das kleinere Übel, wenn die Gegenseite steht. (Natürlich unter der Voraussetzung man hat die Arduinosprache verstanden…)

      Antworten
      1. Sarlochin

        Hallo Nikdro,

        du könntest dir eine Menge Arbeit sparen wenn du einfach die API von thingspeak nimmst. Man greift dann zwar immer noch auf externe quellen zurück aber man hat eben schon mal eine sehr gute Basis und muss nicht alles selber programmieren. Das Programm für den Arduino zu ändern sollte ja nicht allzu schwer sein da muss man sich halt mal ein bisschen einlesen um das komplett zu verstehen. Sen Server kann man dann auch prima auf einem der vielen Einplatinencomputern (RasPi usw) laufen lassen.

        Antworten
  4. NM

    Sendet leider nur 1-3 mal den Wert und bricht dann ab mit:

    OK

    Update Send
    ESP SEND ERROR: AT+CIPCLOSE
    ESP SEND ERROR: AT+CIPSTART=“TCP“,“api.thingspeak.com“,80
    ESP SEND ERROR: AT+CIPSEND=169

    Antworten
    1. Dirk

      Hi,

      bei mir kam die Fehlermeldung nach 2 mal senden, danach sendet das NanoESP einfach weiter und es funktioniert.
      Allerdings habe ich eine Fehlermeldung mit 170

      Antworten
      1. NM

        Habe inzwischen nach vielen Versuchen möglicherweise den Grund für die Probleme gefunden. Mein AccessPoint für WLAN ist über das Stromnetz mit Powerlan-Adaptern an den Router angeschlossen. Vielleicht gibt es hier irgendwelche Übertragungsverluste/Anschlussprobleme. Wenn ich direkt am Router-WLAN ankopple funktioniert alles reibungslos.

        Antworten
  5. Damian

    Hat jemand versucht die sendeinterval von 10sek zu verändern?

    Antworten
    1. Felix

      Bin nicht der Profi aber aus meiner sind es 15sek und nicht 10
      Im Code steht

      void loop() {
      if (sendThingPost(ThingSpeakKEY, analogRead(SENSOR))) debug(„Update Send“);
      delay(15000);

      Das Delay steht für 15000 ms warten also 15 sek
      Versuche mal hier die Zeit zu ändern

      Antworten
      1. Felix

        Aber ich gebe dir keine Garantie, dass das stimmt ;)

        Antworten
        1. Damian

          Danke

          Antworten
  6. Klaus

    Ich sag mal als Hilfe: Abtastung

    Antworten
    1. Klaus

      Sorry, sollte als Antwort in einem Beitrag erscheinen

      Antworten
  7. Markus

    Kann mir jemand die Codes von einem Medion Life P24008 (MD 28000)

    Antworten
  8. KUD

    Hat schon Jemand versucht die Daten an FHEM zu schicken da dort ja auch ein TCP Server läuft?
    Wäre ja echt spannend die Arduino-Sensorwelt anzubinden.

    Antworten
    1. Ralf

      Ich habe FHEM mit dem NanoESP gerade mal ausprobiert. Funktioniert ganz gut, die Daten werden in ein Log geschrieben und als Diagramm dargestellt. In der fhem.cfg habe ich sowas hier:

      define Light dummy
      define Log.Light FileLog light.log Light:L:.*
      define SVG_Log.Light_1 SVG Log.Light:SVG_Log.Light_1:CURRENT

      (Der SVG Plot ist über das Webinterface angelegt, dabei wird dann offenbar auch eine passende gnuplot config erzeugt)

      Das Programm auf dem NanoESP ist entsprechend geändert, damit es einen GET-Request mit dieser URL sendet:

      String url = „/fhem?cmd=setreading%20Light%20state%20L:%20“ + String(value);

      Zusätzliche HTTP-Header oder den POST-Body, der im Original-Programm gesendet wird, braucht man nicht.

      Antworten
      1. KUD

        Hallo Ralf,
        könntest Du mal den Sketch posten… ich kämpfe schon den ganzen Tag mit genau diesem Problem ;-((((

        Antworten
        1. Ralf

          Die wichtigsten Änderungen gegenüber dem Original-Applet sind diese hier:

          #define FhemHost „[Your Host]“

          const byte fhemGet[] PROGMEM = {
          ‚G‘, ‚E‘, ‚T‘, ‚ ‚, ‚*‘, ‚U‘, ‚R‘, ‚L‘, ‚*‘, ‚ ‚, ‚H‘, ‚T‘, ‚T‘, ‚P‘, ‚/‘, ‚1‘, ‚.‘, ‚1‘, 10, 10
          };

          void loop() {
          if (sendFhemGet(analogRead(SENSOR))) debug(„Update Send“);
          delay(15000);
          }

          boolean sendFhemGet(int value)
          {
          boolean succes = true;
          String Host = FhemHost;
          String url = „/fhem?cmd=setreading%20Light%20state%20L:%20“ + String(value);
          succes &= sendCom(„AT+CIPSTART=\“TCP\“,\““ + Host + „\“,8083″, „OK“);

          String getRequest = createFhemGet(url);

          if (sendCom(„AT+CIPSEND=“ + String(getRequest.length()), „>“))
          {
          esp8266.print(getRequest);
          esp8266.find(„SEND OK“);
          if (!esp8266.find(„CLOSED“)) succes &= sendCom(„AT+CIPCLOSE“, „OK“);
          }
          else
          {
          succes = false;
          }
          return succes;
          }

          String createFhemGet(String url)
          {
          String xBuffer;

          for (int i = 0; i <= sizeof(fhemGet); i++)
          {
          char myChar = pgm_read_byte_near(fhemGet + i);
          xBuffer += myChar;
          }

          xBuffer.replace("*URL*", url);

          return xBuffer;
          }

          Gruß,
          Ralf

          Antworten
          1. amseld

            funktioniert! Danke.

            Hast Du eine Idee wie ich auch noch die Authentifizierung von FHEM dazu bekomme?

          2. Ralf

            Zum Thema Authentifizierung mit FHEM, ich nehme an da steht in etwa sowas in der fhem.cfg:

            attr WEB basicAuth ZmhlbXVzZXI6c2VjcmV0

            Um dagegen zu authentifizieren, benötigt man im HTTP-Request einen zusätzlichen Header:

            Authorization: Basic ZmhlbXVzZXI6c2VjcmV0

            Im Applet würde sich dies hier ändern:

            const byte fhemGet[] PROGMEM = {
            ‚G‘, ‚E‘, ‚T‘, ‚ ‚, ‚*‘, ‚U‘, ‚R‘, ‚L‘, ‚*‘, ‚ ‚, ‚H‘, ‚T‘, ‚T‘, ‚P‘, ‚/‘, ‚1‘, ‚.‘, ‚1‘, 10,
            ‚A‘, ‚u‘, ‚t‘, ‚h‘, ‚o‘, ‚r‘, ‚i‘, ‚z‘, ‚a‘, ‚t‘, ‚i‘, ‚o‘, ’n‘, ‚:‘, ‚ ‚, ‚B‘, ‚a‘, ’s‘, ‚i‘, ‚c‘, ‚ ‚,
            ‚Z‘, ‚m‘, ‚h‘, ‚l‘, ‚b‘, ‚X‘, ‚V‘, ‚z‘, ‚Z‘, ‚X‘, ‚I‘, ‚6‘, ‚c‘, ‚2‘, ‚V‘, ‚j‘, ‚c‘, ‚m‘, ‚V‘, ‚0‘,
            10, 10
            };

            Bitte beachten, dass der base64-String im Authorization-Header abhängig von Username und Passwort ist, siehe FHEM-Doku zu basicAuth. Ich hab die Änderung oben jetzt nicht gegen FHEM getestet, aber von der Theorie her müsste das funktionieren ;-)

  9. Tommy

    Interessant zu sehen ist, dass die Helligkeit einer LED-Lampe zwischen zwei Werten (in meinem Fall im Diagramm so zwischen 380 und 670) schwankt, wenn der Sensor in der Nähe derselben Lichtquelle unbewegt bleibt.

    Bei Halogenlampen ist die Helligkeit dagegen fast konstant.

    Antworten
    1. Karsten

      Das läßt sich auch technisch erklären, kommst Du selbst drauf?

      Antworten
      1. Klaus

        Ich sag mal als Hilfe: Abtastung

        Antworten
        1. Tommy

          Schon klar, wenn ich eine batteriebetriebene LED-Lampe nehm, dann schwankt da nix mehr.

          Und bei ner LED-Lampe in Glühbirnenform kann man ja keinen grossen Aufwand für die Gleichrichtung treiben.

          Doch bei recht teuren Steh- und Deckenlampen, die extra als LED-Lampe gebaut wurden (also keine LED als Glühlampenersatz) hätte ich dann schon ne perfekt geglättete Gleichspannung erwartet… ;-)

          Antworten
          1. Nikdro

            Leider sind auch die meisten teureren Trafos/Umformer nicht so genau ;-)

Schreiben Sie einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.