• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Нужна помощь ESP8266 Thingspeak накопление и передача - съедает память.

Gecooo

New member
Приветствую.
Есть пример кода с Thingspeak - накапливает данные каждые 15 сек и затем передает каждые 2 минуты на сервер. Но с каждой передачей уменьшается freeheap и в конце зависает ESP8266.
Как побороть эту проблему?
Оригинал кода здесь. Я изменил только вывод данных.
Мой код:
Код:
/* This example shows how to bulk update a ThingSpeak channel using an Arduino MKR1000 or an ESP8266*/

#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

char jsonBuffer[500] = "["; // Initialize the jsonBuffer to hold data

char ssid[] = "XXXXXXXXXXXXX"; //  Your network SSID (name)
char pass[] = "XXXXXXXXXXXX"; // 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);
    Serial.println(jsonBuffer);
    Serial.println(sizeof(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();
  long freeheap = ESP.getFreeHeap();
  strcat(jsonBuffer, "\"field1\":");
  //lengthT = String(rssi).length();
  lengthT = String(freeheap).length();
  //String(rssi).toCharArray(temp,lengthT+1);
  String(freeheap).toCharArray(temp,lengthT+1);
  strcat(jsonBuffer,temp);
//    strcat(jsonBuffer,",");
//  long freeheap = ESP.getFreeHeap();
//  strcat(jsonBuffer, "\"field2\":");
//  lengthT = String(freeheap).length();
//  String(freeheap).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
  Serial.println(sizeof(temp));
}

// 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\":\"XXXXXXXXXX\",\"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/XXXXXX/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 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");
}
 

Gecooo

New member
попробуйте
после 81 строки написать
*jsonBuffer=0;
проходит только первый пакет данных на сервер, далее ошибка. А память с каждым пакетом уменьшается все-равно.

причем тут динамический?
Это на СИ косвенное присваивание нулевому элементу
если в дурине этого нет то напишите
jsonBuffer[0]=0;
то же самое. вот вывод в сериал:Screenshot_26.png
 
Последнее редактирование:

Юрий Ботов

Moderator
Команда форума
Попробуйте так:

Код:
// 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}]"
   */
 String temps = String("");
  // 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];
  temps = String(deltaT);
  temps.toCharArray(temp,lengthT+1);
  strcat(jsonBuffer,temp);
  strcat(jsonBuffer,",");
  //long rssi = WiFi.RSSI();
  long freeheap = ESP.getFreeHeap();
  strcat(jsonBuffer, "\"field1\":");
  //lengthT = String(rssi).length();
  lengthT = String(freeheap).length();
  //String(rssi).toCharArray(temp,lengthT+1);
  temps = String(freeheap);
  temps.toCharArray(temp,lengthT+1);
  strcat(jsonBuffer,temp);
//    strcat(jsonBuffer,",");
//  long freeheap = ESP.getFreeHeap();
//  strcat(jsonBuffer, "\"field2\":");
//  lengthT = String(freeheap).length();
//  String(freeheap).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
  Serial.println(sizeof(temp));
}
Возможно компилятор не отрабатывает деструктор необъявленного элемента...
 

Gecooo

New member
Все манипуляции были на версии SDK 2.4.1.
Попробовал поставил 2.4.0 - всё заработало, память не кушает.

Всем спасибо, что откликнулись на просьбу о помощи.
Screenshot_7.png
 
Сверху Снизу