Day 19: ThingSpeak

In the last days of the advent time, we will deal with an entirely new subject: the website ThingSpeak. This website has been specifically developed for the subject of Internet of Things and contains various practical functions for you.

Before you tackle the setup and programme as usual, you need to set up an account on the website

www.ThingSpeak.com

Log in with your user data under the item Sign In. You can see a website that shows your channels. Since you have no channels yet, this site will look rather empty. Click New Channel and assign a name, e.g. Light. In this project, you will measure brightness. In the item Field1, you can now assign a name to the field, e.g. Brightness. All other fields can be left empty for now.

Create a channel on ThingSpeak

Create a channel on ThingSpeak

Click Save Channel to save your settings. You will be forwarded to the page of your channel, on which you will only see an empty chart. Click API Keys in the tab above. The sequence of numbers and letters that you will find in the item Write API Key will be needed in a moment.

Hier finden Sie den Write Key

Here you can find you API-Key

You will find another cable behind today’s door. You can now also place three-legged parts such as the IR reception module, outside of the plug board. Today’s experiment is structured identically as the one from the 15th day. A voltage divider with 10-kΩ-resistor and photo transistor permits measuring the current brightness.

Der Aufbau mit Fototransistor an A0

The setup with photo transistor at A0

The program: Day19_ThinkSpeak1

Today’s program measures the brightness, similar to the programme from day 15 . In contrast to the past experiment, however, the data will be sent directly to the ThingSpeak page. This page will not only save the data, but also present them well-structuredly in a chart. It is a very practical function for a measuring station with long-term monitoring.

For the program to be able to send to the website, you need to enter the above API key in the program first under the item ThingSpeakKEY in addition to your WLAN data. It is recommended to open the Serial Monitor after uploading. Usually, an update-send message should accompany successful transmission. On the ThingSpeak page, you can now click the tab Private View of your channel again. There, you can see the chart of your channel, which receives new data every 15 seconds.

Die Messergebnisse im Diagramm

The results in a chart

33 Comments

  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,

    Reply
  2. stberger

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

    Reply
    1. fk (Post author)

      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.

      Reply
      1. stberger

        jawohl, so geht’s! thx

        Reply
        1. Jan

          Kannst du den Code mal schicken?

          Reply
      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

        Reply
        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!

          Reply
          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++++

    Reply
    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).

      Reply
    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…)

      Reply
      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.

        Reply
  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

    Reply
    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

      Reply
      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.

        Reply
  5. Damian

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

    Reply
    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

      Reply
      1. Felix

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

        Reply
        1. Damian

          Danke

          Reply
  6. Klaus

    Ich sag mal als Hilfe: Abtastung

    Reply
    1. Klaus

      Sorry, sollte als Antwort in einem Beitrag erscheinen

      Reply
  7. Markus

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

    Reply
  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.

    Reply
    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.

      Reply
      1. KUD

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

        Reply
        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

          Reply
          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.

    Reply
    1. Karsten

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

      Reply
      1. Klaus

        Ich sag mal als Hilfe: Abtastung

        Reply
        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… ;-)

          Reply
          1. Nikdro

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

Leave a Comment

Your email address will not be published. Required fields are marked *