ThingSpeak Bulk update not running in loop.
3 views (last 30 days)
Show older comments
Hi, im trying to send data to Thingspeak in bulk/batches. I adopted this example <https://ww2.mathworks.cn/help/thingspeak/continuously-collect-data-and-bulk-update-a-thingspeak-channel-using-an-arduino-mkr1000-board-or-an-esp8266-board.html> .
After 1st batch of data is sent to thingspeak successfully, the code doesnot run loop to continue further buffer the data in JSON. That means it send data to server only once and then do nothing. Please guide to sort this issue.
#define MODEM_RST 5
#define MODEM_PWKEY 4
#define MODEM_POWER_ON 23
#define MODEM_TX 27
#define MODEM_RX 26
const char apn[] = "***********";
const char gprsUser[] = "";
const char gprsPass[] = "";
const char simPIN[] = "";
const char server[] = "api.thingspeak.com";
const int port = 80;
char jsonBuffer[500] = "["; // Initialize the jsonBuffer to hold data
#define SerialMon Serial
#define SerialAT Serial1
#define TIMEOUT 5000
// Configure TinyGSM library
#define TINY_GSM_MODEM_SIM7600 // Modem is SIM7600
#define TINY_GSM_RX_BUFFER 1024 // Set RX buffer to 1Kb
#include <TinyGsmClient.h>
#ifdef DUMP_AT_COMMANDS
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, SerialMon);
TinyGsm modem(debugger);
#else
TinyGsm modem(SerialAT);
#endif
TinyGsmClient client(modem);
#define IP5306_ADDR 0x75
#define IP5306_REG_SYS_CTL0 0x00
/* 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 = 20L * 1000L; // Post data every 2 minutes
const unsigned long updateInterval = 2L * 1000L; // Update once every 15 seconds
// Sensor Libraries
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#define DHTPIN 32
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
void setup() {
SerialMon.begin(115200);
// Set modem reset, enable, power pins
pinMode(MODEM_PWKEY, OUTPUT);
pinMode(MODEM_RST, OUTPUT);
pinMode(MODEM_POWER_ON, OUTPUT);
digitalWrite(MODEM_PWKEY, LOW);
digitalWrite(MODEM_RST, HIGH);
digitalWrite(MODEM_POWER_ON, HIGH);
// Set GSM module baud rate and UART pins
SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
delay(3000);
SerialMon.println("Initializing modem...");
modem.init();
// Configure
the wake up source as timer wake up
SerialMon.print("Connecting to APN: ");
SerialMon.print(apn);
if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
SerialMon.println(" fail");
}
else {
SerialMon.println(" OK");
SerialMon.print("Connecting to ");
SerialMon.print(server);
if (!client.connect(server, port)) {
SerialMon.println(" Fail");
}
else {
SerialMon.println(" OK");
}
}
dht.begin();
}
void loop() {
// If update time has reached 1 second, then update the jsonBuffer
if (millis() - lastUpdateTime >= updateInterval) {
updatesJson(jsonBuffer);
}
}
// Updates the josnBuffer with data
void updatesJson(char* jsonBuffer) {
// Collect Hall effect sensor data
//int h = hallRead();
float t = dht.readTemperature();
float h = dht.readHumidity();
Serial.print("Temperature: "); Serial.println(t);
// Format a single data point as a JSON object
char temp[500]; // Temporary buffer for JSON object
//sprintf(temp, "{\"delta_t\":%lu,\"field1\":%d},", (millis() - lastUpdateTime) / 1000, t);
sprintf(temp, "{\"delta_t\":%lu,\"field1\":%.2f,\"field2\":%.2f},", (millis() - lastUpdateTime) / 1000, t, h);
// Append the JSON object to the jsonBuffer
strcat(jsonBuffer, temp);
// If 15 seconds have passed since the last update, send the data to ThingSpeak
if (millis() - lastConnectionTime >= postingInterval) {
// Close the JSON array
size_t len = strlen(jsonBuffer);
jsonBuffer[len - 1] = ']';
// Send data to ThingSpeak
httpRequest(jsonBuffer);
// Reset the jsonBuffer for the next batch of data
jsonBuffer[0] = '[';
jsonBuffer[1] = '\0';
}
lastUpdateTime = millis(); // Update the last update time
}
// Updates the ThingSpeakchannel with data
void httpRequest(char* jsonBuffer) {
// Format the data buffer as noted above
char data[500] = "{\"write_api_key\":\"MY_API_KEY\",\"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/MY_CHANNEL_NUMBER/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 (ESP8266)");
client.println("Connection: close");
client.println("Content-Type: application/json");
client.println("Content-Length: "+data_length);
client.println();
client.println(data);
String answer=getResponse();
Serial.println( answer );
}
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
}
String getResponse(){
String response;
long startTime = millis();
delay( 200 );
while ( client.available() < 1 && (( millis() - startTime ) < TIMEOUT ) ){
delay( 5 );
}
if( client.available() > 0 ){ // Get response from server.
char charIn;
do {
charIn = client.read(); // Read a char from the buffer.
response += charIn; // Append the char to the string response.
} while ( client.available() > 0 );
}
client.stop();
return response;
}
3 Comments
Christopher Stapels
on 30 Sep 2023
Edited: Christopher Stapels
on 30 Sep 2023
I think you are correct on the JSON buffer overflow. One way to test would be to prefill the buffer with data and just write the same buffer each time to ThingSpeak without recording new data.
Also have you tried initializing the JSON buffer as larger than 500?
I think its great you are getting this to work with a GSM modem. Edited out your API key in the serial output above.
Answers (0)
Communities
More Answers in the ThingSpeak Community
See Also
Categories
Find more on Read Data from Channel in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!