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.h
andSPI.h
to your Arduino sketch. If you are using an ESP8266 board, include the librariesEthernetClient.h
andESP8266WiFi.h
to 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"); }
Related Examples
- Bulk-Update a ThingSpeak Channel Using a Particle Photon Board
- Bulk-Update Using a Raspberry Pi Board