Main Content

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

  1. Create a channel as shown in Collect Data in a New Channel.

  2. If you are using an Arduino MKR1000 board, include the libraries WiFi101.h and SPI.h to your Arduino sketch. If you are using an ESP8266 board, include the libraries EthernetClient.h and ESP8266WiFi.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

More About