[SOLVED] Arduino and NodeMCU Serial Communication

Hello guys,
I am making test program for my current project to send serial data from my ESP NodeMCU to Arduino Uno. I used Serial Communication to send 4 dummy variables which represent my sensor reading from MCU to arduino, but it didn't work. Can you help me?

Here are my codes:

Arduino Code

#include <ArduinoJson.h>
#include <SoftwareSerial.h>
SoftwareSerial s(5,6); //RX,TX


void setup() {
  // put your setup code here, to run once:
  s.begin(9600);
  Serial.begin(9600);
  while (!Serial) continue;
}

void loop() {
  // put your main code here, to run repeatedly:
  DynamicJsonBuffer DataNode;
  JsonObject& root = DataNode.parseObject(s);
  if (root == JsonObject::invalid()){
    Serial.println("invalid");
    return;
  }

  int SenseNode1 = root["node1"];
  int SenseNode2 = root["node2"];
  int SenseNode3 = root["node3"];
  int SenseNode4 = root["node4"];
  
  Serial.print("Node 1: " ); 
  Serial.print(SenseNode1);
  Serial.print("\n");
  Serial.print("Node 2: " ); 
  Serial.print(SenseNode2);
  Serial.print("\n");
  Serial.print("Node 3: " ); 
  Serial.print(SenseNode3);
  Serial.print("\n");
  Serial.print("Node 4: " ); 
  Serial.print(SenseNode4);
  Serial.print("\n");
  Serial.print("-------------------------------------------\n");
  delay(1000);
}

NodeMCU Code

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

SoftwareSerial s(12, 14); //D6, D5

DynamicJsonBuffer DataNode;
JsonObject& root = DataNode.createObject();

int sensorValue0 = 100;        
int sensorValue1 = 200;        
int sensorValue2 = 300;        
int sensorValue3 = 400; 

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  s.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:

  root["node1"] = sensorValue0;
  root["node2"] = sensorValue1;
  root["node3"] = sensorValue2;
  root["node4"] = sensorValue3;
  Serial.println(sensorValue0);
  Serial.println(sensorValue1);
  Serial.println(sensorValue2);
  Serial.println(sensorValue3);
  
  if(s.available()>0){
    root.printTo(s);
  }
  delay(500);
}

Here is my Serial Monitor Screenshot (COM6 for Arduino and COM7 for MCU)

I know nothing about ArduinoJson but I see no attempt in your Arduino program to read data from your SoftwareSerial instance.

Separately, please NEVER use single character variable names such as s because it is impossible to search a program to find all the instances of it.

Have a look at the examples in Serial Input Basics - simple reliable non-blocking ways to receive data. There is also a parse example to illustrate how to extract numbers from the received text.

The technique in the 3rd example will be the most reliable. It is what I use for Arduino to Arduino and Arduino to PC communication.

You can send data in a compatible format with code like this (or the equivalent in any other programming language)

Serial.print('<'); // start marker
Serial.print(value1);
Serial.print(','); // comma separator
Serial.print(value2);
Serial.println('>'); // end marker

The examples will work perfectly well with SoftwareSerial

...R

JSON is a terrible way to store and send data. Avoid it unless you have to interface with a device that requires a JSON format. A better way to store and send data would be to use a struct.

On top of that, it would be easier to use SerialTransfer.h to automatically packetize and parse your data for inter-Arduino communication without the headace. The library is installable through the Arduino IDE and includes many examples.

Here are the library's features:

This library:

  • can be downloaded via the Arduino IDE's Libraries Manager (search "SerialTransfer.h")
  • works with "software-serial" libraries
  • is non blocking
  • uses packet delimiters
  • uses consistent overhead byte stuffing
  • uses CRC-8 (Polynomial 0x9B with lookup table)
  • allows the use of dynamically sized packets (packets can have payload lengths anywhere from 1 to 254 bytes)
  • can transfer bytes, ints, floats, and even structs!!

Example TX Arduino Sketch:

#include "SerialTransfer.h"


SerialTransfer myTransfer;

struct STRUCT {
  char z;
  float y;
} testStruct;


void setup()
{
  Serial.begin(115200);
  Serial1.begin(115200);
  myTransfer.begin(Serial1);

  testStruct.z = '|';
  testStruct.y = 4.5;
}


void loop()
{
  myTransfer.txObj(testStruct, sizeof(testStruct));
  myTransfer.sendData(sizeof(testStruct));
  delay(100);
}

Example RX Arduino Sketch:

#include "SerialTransfer.h"


SerialTransfer myTransfer;

struct STRUCT {
  char z;
  float y;
} testStruct;


void setup()
{
  Serial.begin(115200);
  Serial1.begin(115200);
  myTransfer.begin(Serial1);
}


void loop()
{
  if(myTransfer.available())
  {
    myTransfer.rxObj(testStruct, sizeof(testStruct));
    Serial.print(testStruct.z);
    Serial.print(' ');
    Serial.println(testStruct.y);
    Serial.println();
  }
  else if(myTransfer.status < 0)
  {
    Serial.print("ERROR: ");

    if(myTransfer.status == -1)
      Serial.println(F("CRC_ERROR"));
    else if(myTransfer.status == -2)
      Serial.println(F("PAYLOAD_ERROR"));
    else if(myTransfer.status == -3)
      Serial.println(F("STOP_BYTE_ERROR"));
  }
}

For theory behind robust serial communication, check out the tutorials Serial Input Basics and Serial Input Advanced.

[UPDATE]
Thank you for your advice Robin2 and Power_Broker! i've tried it and my program works fine now. I am currently using the SerialTransfer library since it is simpler for me to apply to my system.