ThingSpeak Channel Data With More Than 8 Fields

thingspeakchannel

Are you using ThingSpeak to capture and save your IoT device data points? Ever felt constrained by the 8 field channels limit?

I was.

All 8 of my channel fields were in use. None could be deleted. And I needed to save one additional value. But the solution was quite simple and straight-forward. This short post will serve as a reference “note to self”, and perhaps others who may stumble upon this issue…

A Simple Solution

First of all, as noted, I needed more than 8 fields in my channel’s data set. But a ThingSpeak channel is limited to 8 fields.

Hmm, what to do?

While you are limited to 8 data fields, a channel is not constrained by it’s own channel data. So the answer is right there…just add another channel and you get another group of 8 data fields. Since the additional data fields can be accessed from any of the master channel’s “plug-in” webpages, you have just doubled the number of  entries in a single record, from 8 to 16. There is really no limit to how many channels that can be added, scaling the data set upward by 8 fields for each channel added.

// set your channel IDs here
var channel_id1 = 12345;
var channel_id2 = 12346;
var channel_id3 = 12347;
// set your channel read api keys here
var api_key1 = '9XXQ4X79WQJC72SZ';
var api_key2 = '2KJQ2Q82YTPA23CQ';
var api_key3 = '5SWQ9F87UULD86NB';

function getData() {
//Get Data Set 1
$.getJSON('https://api.thingspeak.com/channels/' + channel_id1 + '/feed/last.json?api_key=' + api_key1, function(data1) {
    //Get Data Set 2
    $.getJSON('https://api.thingspeak.com/channels/' + channel_id2 + '/feed/last.json?api_key=' + api_key2, function(data2) {
         //Get Data Set 3
         $.getJSON('https://api.thingspeak.com/channels/' + channel_id3 + '/feed/last.json?api_key=' + api_key3, function(data3) {
             //Do something with the data here

             //Save the maximum of data1.field2 and data3.field4 in data3.field4
             if(data1.field2 > data3.field4) {
                 maxvalURL = "https://api.thingspeak.com/update?key=" + api_key3 + "&field4=" + data1.field2;
                 $.post(maxvalURL);
             }
         });
    });
});

Note the nested jQuery “$.getJSON” to retrieve the ThingSpeak channel data. All processing needs to be performed inside the inner nest in order to keep the values in scope.

And then there was the need to capture a value that could reset, potentially anytime. In my case, one of the requirements was to save a maximum value. This value represents the device run time since it last reset. It provides a measure of the systems reliability. In the above code example:

current-run-time-since-last-reset = data1.field2;

saved-max-time-since-last-reset = data3.field4;

Instead of retrieving a constantly growing array of values from a ThingSpeak field and then evaluating the array for the maximum value, the current max value is compared against the last run time value stored. This simple running “max value” algorithm runs faster and requires minimal code.

Conclusion

Scalable ThingSpeak data sets. This short post should serve as a reference…a reminder of just how simple and obvious it is to expand your sensor data beyond the 8-field limit imposed on a ThingSpeak channel.

I hope you find this information useful…

Share This:
Facebooktwittergoogle_plusredditpinterestlinkedintumblrFacebooktwittergoogle_plusredditpinterestlinkedintumblr
Social tagging: >

14 Responses to ThingSpeak Channel Data With More Than 8 Fields

  1. Peter says:

    I’m also struggling with updating my data from greenhouse to ThingSpeak.
    I have 15 fields that I need to update to 2 channels.
    Is it possible to share the a complete sketch?
    I have an Arduino with ESP connecting to wifi.

    • facebook-profile-picture InternetOfHomeThings says:

      I am sending some Thingspeak code that uses two sets of 8 channels for an example to your email address. Not sure what you are having issues with. Hope this example helps.

      • MD MUBARAK HOSSAIN says:

        Please could you send me the the code?
        my email: mubarak111nsu@gmail.com<pre class="easycode;">
        Stuff with your code!
        </pre>

        • facebook-profile-picture InternetOfHomeThings says:

          I might create some code to upload banks of channels (8 fields each) to thingsspeak soon, and post it to this blog.

          In the meantime, have a look at my reply to MD MUBARAK HOSSAIN. With this structure, you should be able to prepare the code yourself.

          Good luck with all your projects!

          Dave

    • MD MUBARAK HOSSAIN says:

      Dear respected sir, Hope you are in good health with success and happiness. I am also facing bid problem with my 27 sensor data to upload in thinskpeak. Dear respected sir, Please could you help me with a example code where I could upload 27 sensors data?

      I am using Arduino Mega with ESP8266 wifi module.

      Please sir, I will be really grateful to you.

      • facebook-profile-picture InternetOfHomeThings says:

        It is really quite simple.
        Just use multiple channels of 8 fields each.
        If you are pushing the data up to thingsspeak, then you will need send the sensor data in sets of 8 sensor in sequence to each channel. Remember, you can only upload to a channels once every 15 seconds.

        each transfer is a simple http GET:

        GET https://api.thingspeak.com/update?api_key=YOURCH1WRITEKEY&field1=1&field2=2&field3=3&field4=4&field5=5&field6=6&field7=7&field8=8
        GET https://api.thingspeak.com/update?api_key=YOURCH2WRITEKEY&field1=1&field2=2&field3=3&field4=4&field5=5&field6=6&field7=7&field8=8
        GET https://api.thingspeak.com/update?api_key=YOURCH3WRITEKEY&field1=1&field2=2&field3=3&field4=4&field5=5&field6=6&field7=7&field8=8
        GET https://api.thingspeak.com/update?api_key=YOURCH4WRITEKEY&field1=1&field2=2&field3=3&field4=4&field5=5&field6=6&field7=7&field8=8

        Of course, just use a simple string concatenation in your sketch to set your real sensor values:

        field1=1&field2=2&field3=3&field4=4&field5=5&field6=6&field7=7&field8=8

        gets replaces with:

        field1=<sensor1 value>&field2=<sensor2 value>&field3=<sensor3 value>

        and so on…

        Since you are using the Arduino Mega for WIFI connectivity, you will need to look at the serial link API to find the proper syntax for http GET, which should be very simple and straightforward.

        Good luck with your project!

        Dave

  2. Steve says:

    Thanks for this. I was wondering just how useful the service would be if the limit were eight sensors but I guess you can have as many as you want. The only limit being how often each channel can be updated. Makes sense.

    • facebook-profile-picture InternetOfHomeThings says:

      Channels updates are limited to one update every 15 seconds. But if you have 15 channels, you can update one every second and have a total of 8 X 15 = 120 data points/sensors updated every 15 seconds.

      I like to use mySQL database on my host server when lots of data is involved. php scripts are needed, of course.

  3. Peter says:

    Great solution. do you perhaps also know a way to upload a”dynamic ” api key from thingspeak to a nodemcu ? I’m looking for a way to write one basic code to my nodemcu and have other people fill in the api key later. But they will not be using an ide like arduino ide. Hope someone knowsa workaround.

    • facebook-profile-picture InternetOfHomeThings says:

      Thanks for your comment Peter.

      This post which provides a method to set configurable parameters via an ESP8266 Webpage might be of interest to you as you seek a solution to dynamically setting a Thingspeak API key. I would consider it simply another configurable parameter that would be saved in the ESP8266 EEPROM.

      As far not using the Arduino IDE or the EspressIf SDK, well, I have to say that I have long ago abandoned using the NodeMCU LUA interpreted interface. For me, it was way too restrictive; flaky, crashed a lot, did not provide sufficient memory, and more reasons not to every look back and use it again.

      But if that is your fancy, it should not be difficult to find (with a google search) a NodeMcu LUA API to read/write to the ESP8266 EEPROM. Good luck with your project!

  4. Antony Amalraj Morais says:

    $.getJason is not working for me..
    Ive been using GET Command in my program..
    but the programs outputs only field values of one channel..even after giving a considerable delay between the fetching of data between two channels..
    Please help me out as its my final year project work..

    • facebook-profile-picture InternetOfHomeThings says:

      I hope your final project worked out!

      While it is not possible to understand why it was not working as you intended without looking at your code, it is important to note the following from my post:

      "Note the nested jQuery "$.getJSON" to retrieve the ThingSpeak channel data. All processing needs to be performed inside the inner nest in order to keep the values in scope."

  5. David Tucker says:

    Is there a way to get traces of two or more similar parameters on the same field graph?

    • facebook-profile-picture InternetOfHomeThings says:

      Of course, you can put as many traces on a graph as you wish. My channel has 3 temperature traces; indoor,outdoor,attic.

      The html/javascript/css:

      <html>
      <head>

      <title>Temperature Guages</title>

      %%PLUGIN_CSS%%
      %%PLUGIN_JAVASCRIPT%%

      </head>

      <div id="inner">
      <span id="gauge_in"></span>
      <span id="gauge_ou"></span>
      <span id="gauge_at"></span>
      </div>
      </div>
      </body>
      </html>

      <script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js'></script>
      <script type='text/javascript' src='https://www.google.com/jsapi'></script>
      <script type='text/javascript'>

      // set your channel id here
      var channel_id = 33251;
      // set your channel's read api key here if necessary
      var api_key = '9VGQ4X79MQJC90RD';
      // maximum value for the gauges
      var max_gauge_value = 130;
      // name of the gauges
      var gauge_in = 'Inside';
      var gauge_ou = 'Outside';
      var gauge_at = 'Attic';

      // global variables
      var chart_at,chart_ou,chart_in, charts, data;

      // load the google gauge visualization
      google.load('visualization', '1', {packages:['gauge']});
      google.setOnLoadCallback(initChart);

      // display the data
      function displayData(point,cht) {
      if(cht==1) {
      data.setValue(0, 0, gauge_at);
      data.setValue(0, 1, point);
      chart_at.draw(data, options);
      }
      else if(cht==2) {
      data.setValue(0, 0, gauge_ou);
      data.setValue(0, 1, point);
      chart_ou.draw(data, options);
      }
      else if(cht==3) {
      data.setValue(0, 0, gauge_in);
      data.setValue(0, 1, point);
      chart_in.draw(data, options);
      }
      }

      // load the data
      function loadData() {
      // variable for the data point
      var p_at,p_ou,p_in;

      // get the data from thingspeak
      $.getJSON('https://api.thingspeak.com/channels/' + channel_id + '/feed/last.json?api_key=' + api_key, function(data) {

      // get the data point
      p_at = data.field3;
      p_ou = data.field2;
      p_in = data.field1;

      // if there is a data point display it
      if (p_at) {
      displayData(p_at,1);
      }
      if (p_ou) {
      displayData(p_ou,2);
      }
      if (p_in) {
      displayData(p_in,3);
      }

      });
      }

      // initialize the chart
      function initChart() {

      data = new google.visualization.DataTable();
      data.addColumn('string', 'Label');
      data.addColumn('number', 'Value');
      data.addRows(1);

      chart_at = new google.visualization.Gauge(document.getElementById('gauge_at'));
      chart_ou = new google.visualization.Gauge(document.getElementById('gauge_ou'));
      chart_in = new google.visualization.Gauge(document.getElementById('gauge_in'));
      options = {width: 125, height: 125, redFrom: 100, redTo: 130, yellowFrom:85, yellowTo: 100, minorTicks: 5, max: 130, min: 35};

      loadData();

      // load new data every 60 seconds
      setInterval('loadData()', 60000);
      }

      </script>

      <style type="text/css">
      body { background-color: #ddd; }
      #container { height: 100%; width: 100%; display: table; }
      #inner { vertical-align: middle; display: table-cell; }
      #gauge_in { padding-left:25px; margin: 0; float:left; }
      #gauge_ou { margin: 0; float:left; }
      #gauge_at { margin: 0; float:left; }
      </style>

Leave a Reply