1

I am currently sending temperature and humidity readings to a Thingspeak channel via a nodemcu esp8266 wifi module using serial communication between the arduino and esp. I have set the time between sending data to Thingspeak to 30s, however the time stamps I receive on my Thingspeak channel are very inconsistent even though the data has been supposedly sent (ranging from 3 minutes to 15 minutes). I suspect this could be due to some timing error as I receive many deserialization errors when I convert the Json string (deserialize it on the NodeMCU side). Any help would be appreciated! Note, this is only a part of the project, there are multiple relays added, thus using the nodemcu on its own would be insufficient. I have also added some images, which shows the outputs.

Arduino Uno code:

//Arduino side code
#include <DHT.h>

#include <avr/wdt.h>                //Watchdog Timer

#include <SoftwareSerial.h>         //Arduino to NodeMCU Lib
#include <ArduinoJson.h>

SoftwareSerial nodemcu(5, 6);       //Initialise Arduino to NodeMCU (5=Rx & 6=Tx)

//Initialisation of DHT22 Sensor
#define DHTPIN 4
DHT dht(DHTPIN, DHT22);
float tempC;
float humidity;
float VPD;

void setup() {
  Serial.begin(9600);
  dht.begin();
  nodemcu.begin(9600);
  delay(2000);

  wdt_enable(WDTO_4S);              //Enable Watchdog timer

  Serial.println("Program started");
}

void loop() {
  StaticJsonDocument<1000> doc;

  dht22_func();                          //Obtain Temp and Hum data

  doc["humidity"] = humidity;            //Assign collected data to JSON Object
  doc["temperature"] = tempC;
  doc["VPD"] = VPD;

  serializeJson(doc, nodemcu);           //Send data to NodeMCU

  wdt_reset();                           //Reset for WDT
}

void dht22_func() {

  humidity = dht.readHumidity();
  tempC = dht.readTemperature();
  Serial.print("Humidity: ");
  Serial.println(humidity);
  Serial.print("Temperature: ");
  Serial.println(tempC);

  if (isnan(humidity) || isnan(tempC) || humidity == 0.0 || tempC == 0.0) {
    while (1) {}
  }
}

NodeMCU code:

#include <SoftwareSerial.h>
#include <ArduinoJson.h>

#include <ESP8266WiFi.h>
#include <ThingSpeak.h>    

SoftwareSerial nodemcu(D6, D5);                 //D6 = Rx & D5 = Tx

unsigned long previousMillis = 0;
unsigned long currentMillis;
const unsigned long period = 10000;             //Upload interval in ms

float tempC;
float humidity;
float VPD;

String apiKey = "";             //Write API key

unsigned long channelID = ;              //Thingspeak channel ID
const char *ssid =  "";             //Local network ssid
const char *pass =  "";                 //Local network password
const char* server = "api.thingspeak.com";      //Thingspeak server

boolean state1 = false;                         //Boolean variables
boolean state2 = false;

WiFiClient client;

void setup() {
  Serial.begin(9600);
  nodemcu.begin(9600);
  ThingSpeak.begin(client);
  while (!Serial) continue;
  delay(2000);

  Serial.println("Program Started");

  wifi_connect();                                      //Establish wifi connection
}

void loop() {
  currentMillis = millis();                                  //Get current time

  if ((currentMillis - previousMillis >= period)) {

    if (WiFi.status() != WL_CONNECTED) {                    //Check if connected to wifi, else 
connect
      wifi_connect();
}
else {
  Serial.println("Currently Connected to WiFi");
}

while (state1 == false) {                                //Connect to Thingspeak and push data

  while (state2 == false) {
    parseJsonObject();
  }
  
  cloud_connect();
}

state1 = false;
state2 = false;
Serial.println("Cloud Connect Succesful");
Serial.println("-----------------------------------------");
previousMillis = previousMillis + period;                     //Update counter   
  }
}

void wifi_connect() {
  Serial.println("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, pass);

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi Connected");
}

void cloud_connect() {
  if (client.connect(server, 80)) {           //80 is the standard port number used for web access
    String postStr = apiKey;
    postStr += "&field1=";
    postStr += String(tempC);
    postStr += "&field2=";
    postStr += String(humidity);
    postStr += "\r\n\r\n";

    client.print("POST /update HTTP/1.1\n");
    client.print("Host: api.thingspeak.com\n");
    client.print("Connection: close\n");
    client.print("X-THINGSPEAKAPIKEY: " + apiKey + "\n");
    client.print("Content-Type: application/x-www-form-urlencoded\n");
    client.print("Content-Length: ");
    client.print(postStr.length());
    client.print("\n\n");
    client.print(postStr);

    Serial.print("Temperature: ");
    Serial.print(tempC);
    Serial.print(" || Humidity: ");
    Serial.println(humidiy);
    Serial.println("Sent to Thingspeak");

    //Change state to true to break while loop
  state1 = true;
  }
  client.stop();
}

void parseJsonObject() {
  //Parse JSON object from serial port
  StaticJsonDocument<1000> doc;
  DeserializationError error = deserializeJson(doc, nodemcu);

  // Test if parsing succeeds
  if (error) {
    Serial.println("deserializeJson error");
    return;
  }

  //Parse Json values and store in variable
  humidity = doc["humidity"];
  tempC = doc["temperature"];

  if (isnan(humidity) || isnan(tempC) || humidity == 0.0 || tempC == 0.0) {
    Serial.println("Invalid Sensor Readings");
    return;
  }

  state2 = true;
  Serial.println("JSON Object Recieved");
}

Serial Monitor Output

Thingspeak Result

11
  • try much less than 1000 bytes for StaticJsonDocument Commented Sep 10, 2022 at 9:52
  • How would this help? I'm quite a newbee to the javascript file format. Commented Sep 10, 2022 at 14:47
  • Uno has only 2000 bytes of SRAM Commented Sep 10, 2022 at 15:43
  • How much would be required for this application? Thank you for the response Commented Sep 10, 2022 at 16:42
  • I guess 200 should be enough. arduinojson.org/v6/assistant Commented Sep 10, 2022 at 17:15

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.