Using an Arduino + Ethernet Shield to Update a ThingSpeak Channel

This tutorial demonstrates how to use the Arduino to read in the analog input and update a ThingSpeak Channel by sending an HTTP POST via the Arduino Ethernet Shield or the Arduino Ethernet (all-in-one). The analog input can be the output of a sensor, like a light sensor or temperature sensor.

ThingSpeak Client Arduino Sketch

This Arduino sketch takes the value of Analog Pin 0 and updates Field 1 of a ThingSpeak Channel using the ThingSpeak API.

Arduino_to_ThingSpeak.ino [Arduino 1.0+]

ThingSpeakClient.pde [Arduino 0023 or less]

Getting Started with ThingSpeak

  • Sign Up for New User Account – https://thingspeak.com/login
  • Create a New Channel by selecting Channels and then Create New Channel
  • Enter the Write API Key in this sketch under “ThingSpeak Settings”

ThingSpeak API IP Address

The Arduino + Ethernet Shield does not have DNS by default, so you need to send data using an IP address. ThingSpeak has an API address dedicated for its API.

[cce]byte server[]  = { 184, 106, 153, 149 }; // ThingSpeak IP Address: 184.106.153.149[/cce]

HTTP POST to ThingSpeak

One option to update a ThingSpeak Channel is to use HTTP POST. You can specify any number of fields, location, or status in one message.
Here is an example HTTP POST to ThingSpeak:
[cce]POST /update HTTP/1.1
Host: api.thingspeak.com
Connection: close
X-THINGSPEAKAPIKEY: (Write API Key)
Content-Type: application/x-www-form-urlencoded
Content-Length: (number of characters in message)
field1=(Field 1 Data)&field2=(Field 2 Data)&field3=(Field 3 Data)&field4=(Field 4 Data)&field5=(Field 5 Data)&field6=(Field 6 Data)&field7=(Field 7 Data)&field8=(Field 8 Data)&lat=(Latitude in Decimal Degrees)&long=(Longitude in Decimal Degrees)&elevation=(Elevation in meters)&status=(140 Character Message)[/cce]

Watchdog Timer

Included in the sketch is a watchdog timer for the Ethernet Shield. When 5 failed transactions are detected in a row, the Arduino re-initializes the Ethernet Shield (soft-reset). This will not solve every lockup, but it will make the setup more stable.

Update Multiple Fields

You can update multiple fields inside of a ThingSpeak Channel by adding on more fields in the update request. Here’s an example:
[cce]updateThingSpeak(“field1=”+analogPin0+”&field2=”+analogPin1);[/cce]

Use Short Field Names to Save Space

If you want to save space when making a ThingSpeak update, you can use short field names. “field1” is “1” and field2= “2” and so on. Here’s an example of how the short field names would look in an Arduino update request for a ThingSpeak Channel:
[cce]updateThingSpeak(“1=”+analogPin0+”&2=”+analogPin1);[/cce]

Common Issues

The function “updateThingSpeak” is expecting a “String” as its input. So, if you use a “long” variable type, you need to convert the “long” into a “String” before passing it into “updateThingSpeak”.
[cce]long sensorValue = 6; [/cce]
[cce]updateThingSpeak(“field1=”+String(sensorValue, DEC));[/cce]

50 comments

  1. How do you update multiple fields, I tried adding another updateThinkSpeak() right after the first, but it didn’t work. Only the first field gets updated. I tried putting a delay between the two, but that didn’t work either.
    if(!client.connected() && (millis() – lastConnectionTime > updateThingSpeakInterval))
    {
    updateThingSpeak(“field1=”+analogPin0);
    updateThingSpeak(“field2=”+analogPin1);
    }

    1. @scott
      Here’s what you want to do… You want to combine the fields into one request. This way you can send all of the data at once instead of trying to send two requests with a delay.
      updateThingSpeak(“field1=”+analogPin0+”&field2=”+analogPin1);
      I hope that helps you out.
      PS. Sorry for the delay – your comment made it into the SPAM folder.

      1. When I used short field names as described above:
        updateThingSpeak(“1=”+analogPin0+”&2=”+analogPin1);
        The program only ran twice, i’m assuming because of the &2? Anyway, I reverted to using full field names and it works again. Just thought I’d post in case anyone has that problem, took me ages to work out.

  2. Thanks for the excellent Arduino Sketch. It served as a great starting point for my project and ensured I began with a well constructed foundation to which I only needed to add the specifics of the live IO I was gathering.

  3. By the way, I added a check to see if millis() is less than lastConnectionTime to address the instance in which millis() wraps after about 50 days. If this were to happen, it will never be greater than updateThingSpeakInterval and the code will never send another update. I simply reset lastConnectionTime to zero, which isn’t the most sophisticated, but only introduces a briefer update period roughly once every 50 days.

  4. Is there a way in the POST to tell the ThingSpeak server to be less verbose? Once I disconnected the USB cable, the Arduino seemed to stall after a few hours and seemingly cleared up once I reconnected the cable. I’m guessing (and it’s really a guess) there’s an output buffer on the Arduino that’s getting full and stopping the Serial.print commands from being processed. In the meantime, I’ve added a conditional before each Serial.print to check and see if a troubleshoot flag is set. If not, the Serial.print command is not executed.

    1. Tom,
      The Arduino doesn’t have a dynamic serial buffer. That’s not the cause. I’ve had sketches run for months, pumping out serial data with the USB disconnected for months and I don’t lose a byte of memory.
      Hard to say what your problem is, but you might be dynamically creating strings that aren’t being properly deleted.

      1. Dear Mr. Keith
        Can you help me how to get the arduino to run for month. My sketch only run 2-3 days then it hang, i have to reset it or soft reset it everyday.

  5. Ladies and gentlemen,
    Maybe this is the wrong place to ask but this is my question:
    I have a ThingSpeak server running at 94.212.224.139:3000
    So thingSpeakAddress = 94.212.224.139 and the 80 has to replaced with 3000.
    But in the arduinocode do i put in: client.print(“Host: api.thingspeak.com\n”);
    to replace api.thingspeak.com?
    Please help.
    if (client.connect(thingSpeakAddress, 80))
    {
    client.print(“POST /update HTTP/1.1\n”);
    client.print(“Host: api.thingspeak.com\n”);
    client.print(“Connection: close\n”);
    client.print(“X-THINGSPEAKAPIKEY: “+writeAPIKey+”\n”);
    client.print(“Content-Type: application/x-www-form-urlencoded\n”);
    client.print(“Content-Length: “);
    client.print(tsData.length());
    client.print(“\n\n”);

    1. Sorry for the delay… questions are easier to track in the forum.
      You need to change this line:
      if (client.connect(thingSpeakAddress, 80))
      to
      if (client.connect(thingSpeakAddress, 3000))
      Does that work?

  6. Hi again,
    now i would like to plot my float temperature values…i saw that “updateThingSpeak”expects a “String” as input, therefore i did a cast:
    String temp = String(temper());
    temper() returns a float but it doesn’t work; if i change the return of function temper() in int, it works, obviously.
    How can i do to fix it?

    1. Francesco. you want to turn a float into a string. but you are not using the proper function.
      suppose ‘t’ is the temperature value coming from yr sensor and it is a float.
      Do like this:
      char t_buffer[10];
      t=(ReadSensor);
      String temp=dtostrf(t,0,5,t_buffer);

  7. I am trying to send data with an arduino and an ethernet shield, but it refuses work.
    At first attempt, many commands of the sketch had to be rewritten, because the API reports them as invalid or renamed – maybe different versions of the arduino API. Mine is updated, freshly instaled and downloades from the official arduino site.
    I added several commands to trace the program via serial monitor – it is running, the data was aquired, but it can’t send the data to the servers.
    The server side seens to be unavaible.
    Any idea?

      1. I’m new here.
        Also to me it refuses to work. I changed some coding according to EthernetClient class,
        and I used for parameter IP number, mnemonic, char[], String and so on.
        The point is that client.connect(server,80) never returns true! (see the folowing)
        void updateThingSpeak(String tsData)
        {
        Serial.println(“Connecting to ThingSpeak…”);
        if (client.connect(server,80))
        {
        Serial.println(“Connected to ThingSpeak…”);
        Serial.println();
        alway seen “Connecting to ThingSpeak…” and
        never seen “Connected to ThingSpeak…”!!!!!
        I tried a schema and it does work.
        I know it seems not a problem of ThingsSpeak….
        Thanks for help.
        Michele

        1. Sorry …
          “I tried a schema and it does work.” STANDS FOR
          I tried a “client.connect(server,80)” schema with google server (“www.google.com”,80) and it does work.
          Thanks
          Michele

          1. Solved. Just trying without any logic!! Why?
            Ethernet.begin(mac, ip, gateway, subnet);
            CHANGED TO
            Ethernet.begin(mac, ip);
            Ciao

          2. Hello,
            I think I am having a very similar problem. Can you post the version of code you have working? or the changes you made to the ethernet class?
            Thanks!

  8. I am using wifi shield instead of ethernet.
    I can connect it to ThingSpeak but after some data sent I get a message “No socket available”. This make Thingspeak connection fail.
    Here the code
    https://docs.google.com/file/d/0B6Yw5tJf9DQ2cmg0VXExZDlQTDQ/edit
    Message
    Connecting to ThingSpeak…
    4958ºC
    SSID: GuiFi
    BSSID: 0:27:22:E6:55:25
    signal strength (RSSI):-72
    Encryption Type:4
    HTTP/1.1 200 OK
    X-Frame-Options: ALLOWALL
    Access-Control-Allow-Origin: *
    Access-Control-Allow-Methods: GET, POST, PUT, OPTIONS, DELETE, PATCH
    Access-Control-Allow-Headers: origin, content-type, X- Requested-With
    Access-Control-Max-Age: 1800
    Content-Type: text/html; charset=utf-8
    Etag: “289dff07669d7a23de0ef88d2f7129e7”
    Cache-Control: max-age=0, private, must-revalidate
    X-Request-Id: 172e8293-f68c-4217-ae88-11087f06dbb8
    X-Runtime: 0.016702
    Server: WEBrick/1.3.1 (Ruby/2.1.0/2013-12-25)
    Date: Fri, 23 May 2014 08:11:26 GMT
    Content-Length: 3
    Connection: close
    234No Socket available
    Connection to ThingSpeak Failed (1)
    I also can not send more than one field, even using:
    updateThingSpeak(“field1=”+analogPin0+”&field2=”+analogPin1);
    Thanks, Rodri

    1. hey, i have similar code as yours .It has one problem in it, it PRINTS and UPDATE thingspeak only once .
      if i have to print and update again channel ,i have to run the code again.
      can you please help me .

  9. Hey!
    The above all discussion is about arduino to thingspeak. I am using STM32F4 Discovery Board instead of arduino and trying to send sensor data to thingspeak. Can any one help me how can I send? I am using simple socket programming.

  10. Hi i want a complete solution for turn on or off pins of arduino from the internet. board also connects to the internet wirelessly (using GPRS internet). Is it possible ? or any other solution for complete wireless arduino remote. please send me reply to uma5b3@gmail.com

  11. is it possible to exploit this website and the upload data from Texas Instrument’s cc3200…. and not arduino

  12. Yes its possible to use CC3000 and upload data into this site. Its very simple. If you look at this code by iobridge
    https://github.com/iobridge/ThingSpeak-Arduino-Examples/blob/master/Ethernet/Arduino_to_ThingSpeak.ino
    you just need to use cc3000 module to connect with internet. You can use either Adafruit library or TI default library (non Arduino) to connect with internet. After getting connected with internet rest of the this are very standard and almost same as the code done by iobridge. Let me know if you need any help.

    1. Yes, I could use some help with this. I’m trying to code this using the CS3000 but haven’t had any luck yet.

    1. I am using Arduino Wifi Shield with arduino UNO R3 board. So , i would like to know, how can i connect to ThingSpeak using this setup. Please share the code if any one have it.

  13. The ThingSpeak.ino (linked up top) is stuck compil”ing”. Perhaps this tutorial should be taken off the site to have it’s bugs worked out. Can someone point me to a functional ThingSpeak tutorial to get me back to learning? TYIA

  14. I spend some hours searching a problem in my code, responsible for very slow data transfer (~4min). Finally, found that I had “delay(2000)” at the end of my loop code, which was responsible for transfering letter by letter of the String in “updateThingSpeak”. Noiw it updates every ~15 seconds.
    Is this a normal behaviour of the example code?

    1. Ran into exactly the same problem.
      The code prints only one internet client output character per loop() iteration. The line Serial.print(c) is only called once every time the loop goes round. So any delay in the loop will cause a delay for the next c.
      I’ve fixed that this way:
      if (client.available())
      Changed to:
      while (client.available())
      This makes it print all characters in the buffer before continuing.

  15. I would like to make 2 separate arduino’s log to different fields on one channel.
    Arduino1 -> Channel 111 field1&field2
    Arduino2 -> Channel 111 field3&field4
    Would that be possible (because I cannot send all fields in one POST)?

  16. I am trying to update data on thingspeak using intel Edison but it only updates once.If i have to update Thingspeak agian i have to upload code again.
    All suggestions are appreciated.

  17. I am using Arduino Wifi esp8266 with arduino UNO board. So , i would like to know, how can i connect to ThingSpeak using this setup. Please share the code if any one have it.

  18. I am trying to retrieve the last value updated to a certain field of a thingspeak channel. I find it kinda difficult using GET query and turning on/off an LED in the subsequent steps. Please help me out in this case. I have successfully updated three fields in my thingspeak channel.

  19. Since I need more than 8 datafields, I thought first about exploiting the “status” field and maybe the “long” and “lat” fields to store three more sensor values.
    However, I think it is better to update two seperate Thingspeak channels. I added the following lines to the sketch:
    String Key1 = “…”;
    String Key2 = “…”;

    // update channel 1
    writeAPIKey = Key1;
    updateThingSpeak(…);
    client.stop();
    // update channel 2
    writeAPIKey = Key2;
    updateThingSpeak(…);
    Though this seems to work, I don’t know if it is the best approach. And it is only the update response from the second channel printed to the Serial Monitor.
    Any suggestions on this?

  20. Getting an error during compile. Not sure if its a library error or and IDE error
    Arduino: 1.6.5 (Windows 7), Board: “Arduino/Genuino Uno”
    thingspeak01:35: error: The Client class has been renamed EthernetClient.
    As of Arduino 1.0, the Client class in the Ethernet library has been renamed to EthernetClient.
    Any help appreciated

  21. I used the sketch you have written above.
    I have an Arduino Mega with ethernet shield W5500 processor with.
    Everything works properly, but after about an hour, telling me error in the connection to the site. To make it work I have to power cycle.
    I also tried it with several other ethernet shields (W5100, W5200), but the result and the same.
    Possible that these ethernet shield do not work all the time and always give problems? If so, it would be only of disappointments.
    Someone managed to make it all work?

  22. Hi
    I had a question about uploading string to the channel. I have a sensor that gives me two data every second. And I want to upload these data to my thingspeak channel every minute that is 120 data in total. I put them in a long string like 2,4,5,1,3,1,…….
    Can thingspeak support this kind of data format? Most of application on thingspeak only upload one single point of data every time. How to update a array of data in one time?
    Thanks a lot !

  23. Hi, I used Arduino UNO,Ethernet shield and DHT22. when i upload the code than I look at Serial monitor i have massege like this:
    Connecting Arduino to network…
    DHCP Failed, reset Arduino to try again
    Connection to ThingSpeak failed (1)
    Connection to ThingSpeak failed (2)
    pleade help me.

This site uses Akismet to reduce spam. Learn how your comment data is processed.