Hans on IoT

ThingSpeak, MATLAB, and the Internet of Things

Send Bulk Sensor Data to ThingSpeak for Analysis 5

Posted by Hans Scharler,

Many IoT projects collect data from a sensor and send the data to ThingSpeak at the same time over and over. To continuously collect and send data to the cloud requires the device to be powered and connected all of the time. A battery-powered IoT device like a Particle Photon or Onion Omega2 would run out of power quickly. There are many IoT applications where you want your IoT device to collect the data offline over a long period of time, then send the data all at once to ThingSpeak for analysis.

The ThingSpeak team at MathWorks is excited to announce Bulk-Update! This new ThingSpeak feature is targeted at IoT devices trying to optimize battery use by allowing the device to update a lot of data at once. To help you get started with bulk-update, we have written examples for Arduino, ESP8266, Particle Photon, and the Raspberry Pi 3.

Once your data is on ThingSpeak, it is easy to analyze using the MATLAB Analysis and Visualization apps within ThingSpeak, MATLAB Online, or Desktop MATLAB. To read data from ThingSpeak into MATLAB, use the ThingSpeak Support Toolbox and the thingSpeakRead command. We have released documentation and examples to help you get started with bulk-update on ThingSpeak.

Resources for Bulk-Update

5 CommentsOldest to Newest

Eight19_FC replied on : 1 of 5
I am trying to implement this bulk transfer from the Particle Electron. I have tried directly copying the example code for the photon, but in the "Response code" published I reliably get either a 1, 0, or 500, and my ThingSpeak channel is not updated. I have also attempted using the webhook method recommended by Particle, but although I have done my best to format the JSON file in the publish as it is in the documentation, there is usually a 401 (invalid API key or channel mismatch), but the API key I have put into the json and the channel number in the url are both correct. Can anyone advise me on implementing this bulk transfer method for an Electron? My project needs to be as low-powered as possible, and the methods in the particle documentation are insufficient as there does not appear to be any other way of ensuring that published data points are associated with their own particular timestamp rather than the timestamp of the publish.
Christopher Stapels replied on : 2 of 5
I recently re-verified the example code for bulk posting with a particle photon (https://www.mathworks.com/help/thingspeak/bulk-update-a-thingspeak-channel-using-particle-photon-board.html). The JSON formatting can sometimes be a pain. Or perhaps there is some difference with the libraries for the electron. We will look into this further.
Hans Scharler replied on : 3 of 5
I have taken a closer look at the issue. In your code do you have a line that looks like this? strcpy(data,”write_api_key=”+WriteAPIKey+”&time_format=absolute&updates=”); Make sure “time_format” has an underscore. Let us know if that helps.
Muhammad Ahmed Naveed replied on : 4 of 5
Hello, I am using this example as it is https://www.mathworks.com/help/thingspeak/continuously-collect-data-and-bulk-update-a-thingspeak-channel-using-an-arduino-mkr1000-board-or-an-esp8266-board.html This is my complete code. But I get a response code: 0. Can you please tell me what is wrong in this code ? I am using ESP8266 thing dev. /* This example shows how to bulk update a ThingSpeak channel using an Arduino MKR1000 or an ESP8266*/ #include //Uncomment this library to work with ESP8266 #include //Uncomment this library to work with ESP8266 //#include // Comment this to work with ESP8266 board //#include // Comment this to work with ESP8266 board char jsonBuffer[500] = "["; // Initialize the jsonBuffer to hold data char ssid[] = "Xperia Z_a769"; // Your network SSID (name) char pass[] = "7c6761b56ed2"; // Your network password WiFiClient client; // Initialize the WiFi client library char server[] = "api.thingspeak.com"; // ThingSpeak Server /* Collect data once every 15 seconds and post data to ThingSpeak channel once every 2 minutes */ unsigned long lastConnectionTime = 0; // Track the last connection time unsigned long lastUpdateTime = 0; // Track the last update time const unsigned long postingInterval = 120L * 1000L; // Post data every 2 minutes const unsigned long updateInterval = 15L * 1000L; // Update once every 15 seconds void setup() { Serial.begin(9600); // Attempt to connect to WiFi network while (WiFi.status() != WL_CONNECTED) { Serial.print("Attempting to connect to SSID: "); Serial.println(ssid); WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network delay(10000); // Wait 10 seconds to connect } Serial.println("Connected to wifi"); printWiFiStatus(); // Print WiFi connection information } void loop() { // If update time has reached 15 seconds, then update the jsonBuffer if (millis() - lastUpdateTime >= updateInterval) { updatesJson(jsonBuffer); } } // Updates the jsonBuffer with data void updatesJson(char* jsonBuffer){ /* JSON format for updates paramter in the API * This example uses the relative timestamp as it uses the "delta_t". If your device has a real-time clock, you can provide the absolute timestamp using the "created_at" parameter * instead of "delta_t". * "[{\"delta_t\":0,\"field1\":-70},{\"delta_t\":15,\"field1\":-66}]" */ // Format the jsonBuffer as noted above strcat(jsonBuffer,"{\"delta_t\":"); unsigned long deltaT = (millis() - lastUpdateTime)/1000; size_t lengthT = String(deltaT).length(); char temp[4]; String(deltaT).toCharArray(temp,lengthT+1); strcat(jsonBuffer,temp); strcat(jsonBuffer,","); long rssi = WiFi.RSSI(); strcat(jsonBuffer, "\"field1\":"); lengthT = String(rssi).length(); String(rssi).toCharArray(temp,lengthT+1); strcat(jsonBuffer,temp); strcat(jsonBuffer,"},"); // If posting interval time has reached 2 minutes, then update the ThingSpeak channel with your data if (millis() - lastConnectionTime >= postingInterval) { size_t len = strlen(jsonBuffer); jsonBuffer[len-1] = ']'; httpRequest(jsonBuffer); } lastUpdateTime = millis(); // Update the last update time } // Updates the ThingSpeakchannel with data void httpRequest(char* jsonBuffer) { /* JSON format for data buffer in the API * This example uses the relative timestamp as it uses the "delta_t". If your device has a real-time clock, you can also provide the absolute timestamp using the "created_at" parameter * instead of "delta_t". * "{\"write_api_key\":\"YOUR-CHANNEL-WRITEAPIKEY\",\"updates\":[{\"delta_t\":0,\"field1\":-60},{\"delta_t\":15,\"field1\":200},{\"delta_t\":15,\"field1\":-66}] */ // Format the data buffer as noted above char data[500] = "{\"write_api_key\":\"6OF022OLH2QM50TP\",\"updates\":"; //Replace YOUR-CHANNEL-WRITEAPIKEY with your ThingSpeak channel write API key strcat(data,jsonBuffer); strcat(data,"}"); // Close any connection before sending a new request client.stop(); String data_length = String(strlen(data)+1); //Compute the data buffer length // POST data to ThingSpeak if (client.connect(server, 80)) { client.println("POST /channels/522490/bulk_update.json HTTP/1.1"); //Replace YOUR-CHANNEL-ID with your ThingSpeak channel ID client.println("Host: api.thingspeak.com"); client.println("User-Agent: mw.doc.bulk-update (Arduino ESP8266)"); client.println("Connection: close"); client.println("Content-Type: application/json"); client.println("Content-Length: "+data_length); client.println(); client.println(data); } else { Serial.println("Failure: Failed to connect to ThingSpeak"); } delay(15000); //Wait to receive the response client.parseFloat(); String resp = String(client.parseInt()); Serial.println("Response code:"+resp); // Print the response code. 202 indicates that the server has accepted the response jsonBuffer[0] = '['; // Reinitialize the jsonBuffer for next batch of data jsonBuffer[1] = '\0'; lastConnectionTime = millis(); // Update the last connection time } void printWiFiStatus() { // Print the SSID of the network you're attached to: Serial.print("SSID: "); Serial.println(WiFi.SSID()); // Print your device IP address: IPAddress ip = WiFi.localIP(); Serial.print("IP Address: "); Serial.println(ip); // Print the received signal strength: long rssi = WiFi.RSSI(); Serial.print("signal strength (RSSI):"); Serial.print(rssi); Serial.println(" dBm"); } This is my output: Attempting to connect to SSID: Xperia Z_a769 Connected to wifi SSID: Xperia Z_a769 IP Address: ************* signal strength (RSSI):-44 dBm Response code:0
Cyril Jan Eugenio replied on : 5 of 5
Good day sir. can i ask for advice? Im trying to use the bulk_update to store frequency values from mic sensor to thingspeak. but im having trouble in the codes. i cant hardly understand the examples since im not that good in coding. i thought it would be like the temperature and humidity sensor but its different and i cant get the desired output in thingspeak.