Bulk-Update Using an Arduino or an ESP8266
This example shows how to use either an Arduino® MKR1000 board or an ESP8266 board connected to a Wi-Fi® network to continuously collect Wi-Fi signal strength and bulk-update a ThingSpeak™ channel.
You can use the Bulk-Write JSON Data API to collect data as batch and send it to ThingSpeak channels. This strategy reduces the power usage of your devices. In this example, you collect data once every 15 seconds and update your channel once every 2 minutes using an Arduino MKR1000 board. Since the Arduino MKR1000 and the ESP8266 board do not have a real-time clock, you can use the relative time stamp for bulk-update messages.
Setup
Create a channel as shown in Collect Data in a New Channel.
If you are using an Arduino MKR1000 board, include the libraries
WiFi101.handSPI.hto your Arduino sketch. If you are using an ESP8266 board, include the librariesEthernetClient.handESP8266WiFi.hto your Arduino sketch
Code
1) Begin by including the appropriate libraries for your hardware.
// #include<EthernetClient.h> //Uncomment this library to work with ESP8266 // #include<ESP8266WiFi.h> //Uncomment this library to work with ESP8266 #include<SPI.h> // Comment this to work with ESP8266 board #include<WiFi101.h> // Comment this to work with ESP8266 board
2) Initialize the jsonBuffer to hold the JSON data.
char jsonBuffer[500] = "["; // Initialize the jsonBuffer to hold data
3) Define the Wi-Fi credentials to connect your Arduino board to the network, and initialize the Wi-Fi client library.
char ssid[] = "YOUR-NETWORK-SSID"; // Your network SSID (name) char pass[] = "YOUR-NETWORK-PWD"; // Your network password WiFiClient client; // Initialize the Wi-Fi client library
4) Define the ThingSpeak server.
char server[] = "api.thingspeak.com"; // ThingSpeak Server
5) Define other global variables that track the last connection time and last update time. Also, define time intervals to update the data, and post the data to ThingSpeak.
/* 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
6) Use the setup method to initialize serial data transfer and to connect to Wi-Fi network.
void setup() {
Serial.begin(9600);
// Attempt to connect to Wi-Fi 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 Wi-Fi");
printWiFiStatus(); // Print Wi-Fi connection information
}
7) In the loop method, call the updatesJson method to update the jsonBuffer with data once every second.
void loop() {
// If update time has reached 1 second, then update the jsonBuffer
if (millis() - lastUpdateTime >= updateInterval) {
updatesJson(jsonBuffer);
}
}
8) Define the updatesJson method to continuously update the jsonBuffer with data. Since Arduino MKR1000 does not have a real-time clock, you use the 'delta_t' parameter to define a relative time stamp in seconds between successive messages. If your device has a real-time clock, you can use an absolute timestamp. Replace 'delta_t' parameter with 'created_at' parameter. Format the messages as JSON in a format mentioned in Bulk-Write JSON Data. Call the httpRequest method to send data to ThingSpeak once every 2 minutes.
// Updates the josnBuffer with data
void updatesJson(char* jsonBuffer){
/* JSON format for updates parameter in the API
* This example uses the relative timestamp as it uses the "delta_t".
* You can also provide the absolute timestamp using the "created_at" parameter instead of "delta_t".
* "[{\"delta_t\":0,\"field1\":-70},{\"delta_t\":3,\"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, 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
}
9) Define the httpRequest method to send data to ThingSpeak and to print the response code from the server. A response code 202 indicates that the server has accepted the request for precessing.
// 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".
* 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\":\"YOUR-CHANNEL-WRITEAPIKEY\",\"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
Serial.println(data);
// POST data to ThingSpeak
if (client.connect(server, 80)) {
client.println("POST /channels/YOUR-CHANNEL-ID/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(250); //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 conenction time
}
10) Define the printWiFiStatus method to print your device IP address and signal strength.
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");
}