node mcu freeheap problem and cause exception 29

I have code that measure co2 from ccs811 sensor...
but the problem is that everytime that it measures, freeheap size is decresed and cause Exception(29)

.....
23:27:30.865 -> CO2: 400ppm, TVOC: 0ppb   Temp:
23:27:30.865 -> FreeHeap Thingspeak_1: 4600
23:27:31.870 -> CO2: 400ppm, TVOC: 0ppb   Temp:
23:27:31.870 -> FreeHeap Thingspeak_1: 3496
23:27:32.878 -> CO2: 400ppm, TVOC: 0ppb   Temp:
23:27:32.878 -> FreeHeap Thingspeak_1: 2392
23:27:33.883 -> CO2: 400ppm, TVOC: 0ppb   Temp:
23:27:33.883 -> FreeHeap Thingspeak_1: 1472
23:27:34.888 -> CO2: 400ppm, TVOC: 0ppb   Temp:
23:27:34.888 -> FreeHeap Thingspeak_1: 368
23:27:35.201 -> 
23:27:35.201 -> Exception (29):
....

Full code is as below

#include "Adafruit_CCS811.h"

Adafruit_CCS811 ccs;

void setup() {
  Serial.begin(115200);
  
  Serial.println("CCS811 Reading CO2 and VOC");
  
  Wire.begin(2,14);//sda, scl 
  if(!ccs.begin()){
    Serial.println("Failed to start sensor! Please check your wiring.");
    while(1);
  }
  //calibrate temperature sensor
  while(!ccs.available());
}

void loop() {
  if(ccs.available()){

    if(!ccs.readData()){
      Serial.println("CO2: "+String(ccs.geteCO2())+"ppm, TVOC: "+String(ccs.getTVOC())+"ppb   Temp:");
      Serial.print(String("FreeHeap Thingspeak_1: "));



Serial.println(ESP.getFreeHeap(),DEC);


    }
    else{
      Serial.println("Sensor read ERROR!");
      ccs.readData();
    }
  }else{
    Serial.println("not available");
  }
  delay(1000);
}

Try getting rid of all those String objects and use plain old C strings instead.

I don't use ESP8266's but I do use the ESP32's.

Seeing as freeRTOS is a favorite of the Espressif, many calls are translated into freeRTOS macros. Example, using the delay() function in the Arduino Ide, is translated into vTaskDelay, a non CPU blocking delay. Note: Calling delay or other translated methods may cause freeRTOS to load, once freeRTOS is loaded your running in a multi-threaded environment.

I have found, for the ESP32 many Adafruit libraries are not really all that great at memory management.

If the library is using a thing like malloc, or large array counts, on an ESP32, malloc is not thread safe nor multi-core safe; Heap Memory Allocation - ESP32 - — ESP-IDF Programming Guide latest documentation. Espressif provides macros or wrappers that makes malloc thread and core safe.

I get better results when doing a search for a library for the ESP32 if I search on "esp32 ccs811". You might find doing a search on "esp8266 ccs811" would result in finding a working driver.

You, also, might gain insights with the Espressif API such as https://www.espressif.com/sites/default/files/documentation/2c-esp8266_non_os_sdk_api_reference_en.pdf.


In regards to string and the ESP32, there is a process that cleans up a fragmenting heap, which might be the case for an ESP9266.

I would start by getting rid of the use of "String":

    if (!ccs.readData())
    {
      Serial.print("CO2: ");
      Serial.print(ccs.geteCO2());
      Serial.print("ppm, TVOC: ");
      Serial.print(ccs.getTVOC());
      Serial.println("ppb   Temp:");
      
      Serial.print("FreeHeap Thingspeak_1: ");
      Serial.println(ESP.getFreeHeap(), DEC);
    }
    else