Serial Communication between Arduino and NodeMCU

Hello guys.
I want to send data which 2 packets ( temperature and hudimity) from arduino to ESP NodeMcu. I used Serial Communication but it didn't work. Can you help me?
Thank you somuch.

Here are my code:

Tx _ Arduino

#include <SoftwareSerial.h>
SoftwareSerial s(0,1);
char inData[24];
byte index;
int windVal;
int temp;
boolean started = false;
boolean ended = false;

void setup()
{
Serial.begin(9600);
s.begin(9600);
Serial.println("Temperature & Humidity");
}

void loop()
{
  while(Serial.available() > 0)
  {
  char aChar = Serial.read();
  if(aChar == '<')
  {
      started = true;
      index = 0;
      inData[index] = '\0';
  }
  else if(aChar == '>')
  {
      ended = true;
  }
  else if(started)
  {
      inData[index] = aChar;
      index++;
      inData[index] = ',';
  }
  }

  if(started && ended)
  {
  // Use the value
  if(inData[0] == 'T')
  {
     inData[0] = ' ';
     int windVal = atoi(inData);
                s.write(windVal);
           Serial.println(" ");
     Serial.print("Temp:");
           Serial.print(inData);
           Serial.print("C");
           Serial.println(" ");
  }
  else if(inData[0] == 'H')
     {
     inData[0] = ' ';
           int temp = atoi(inData);
           s.write(temp);
     Serial.println(" ");
           Serial.print("Humidity:");
           Serial.print(inData);
           Serial.print("%");
           Serial.println(" ");
     }

  started = false;
  ended = false;

  index = 0;
  inData[index] = '\0';
  }
}

Rx_NodeMCU

#include <SoftwareSerial.h>


// Libraries
#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"

SoftwareSerial s(3,1);


// WiFi parameters
#define WLAN_SSID       "Nangsuat-Technology"
#define WLAN_PASS       "comphone"

// Adafruit IO
#define AIO_SERVER      "io.adafruit.com"
#define AIO_SERVERPORT  1883
#define AIO_USERNAME    "nhatnguyenpt"
#define AIO_KEY         "e01a5a80956249ca886990be948e6dd7"  // Obtained from account info on io.adafruit.com



// Create an ESP8266 WiFiClient class to connect to the MQTT server.
WiFiClient client;

// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);

// Setup feeds for temperature & humidity
Adafruit_MQTT_Publish temperature = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/temp");
Adafruit_MQTT_Publish humidity = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/humidity");

/*************************** Sketch Code ************************************/
int windVal,temp;
void setup() {
  // Init sensor
 // dht.begin();

  Serial.begin(9600);
  s.begin(9600);
  Serial.println(F("Adafruit IO Example"));
 
  // Connect to WiFi access point.
  Serial.println(); Serial.println();
  delay(10);
  Serial.print(F("Connecting to "));
  Serial.println(WLAN_SSID);

  WiFi.begin(WLAN_SSID, WLAN_PASS);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(F("."));
  }
  Serial.println();

  Serial.println(F("WiFi connected"));
  Serial.println(F("IP address: "));
  Serial.println(WiFi.localIP());

  // connect to adafruit io
  connect();

}

void loop() {

  // ping adafruit io a few times to make sure we remain connected
  if(! mqtt.ping(3)) {
    // reconnect to adafruit io
    if(! mqtt.connected())
      connect();
  }

  if (Serial.available()) {
    Serial.write(Serial.read());
  }

  windVal = Serial.read(); //Read the serial data and store it
  temp = Serial.read();
  delay(1000);

  
  // Publish data
  if (! temperature.publish(windVal))
    Serial.println(F("Failed to publish temperature"));
  else
    Serial.println(F("Temperature published!"));

  if (! humidity.publish(temp))
    Serial.println(F("Failed to publish humidity"));
  else
    Serial.println(F("Humidity published!"));

  // Repeat every 10 seconds
   Serial.print("Humidity: ");
   Serial.print(windVal);
   Serial.print(",");
// Serial.print(" %\t");

   Serial.print("Temperature: ");
   Serial.println(temp);
// Serial.print(" *C ");
  delay(10000);

}


// connect to adafruit io via MQTT
void connect() {

  Serial.print(F("Connecting to Adafruit IO... "));

  int8_t ret;

  while ((ret = mqtt.connect()) != 0) {

    switch (ret) {
      case 1: Serial.println(F("Wrong protocol")); break;
      case 2: Serial.println(F("ID rejected")); break;
      case 3: Serial.println(F("Server unavail")); break;
      case 4: Serial.println(F("Bad user/pass")); break;
      case 5: Serial.println(F("Not authed")); break;
      case 6: Serial.println(F("Failed to subscribe")); break;
      default: Serial.println(F("Connection failed")); break;
    }

    if(ret >= 0)
      mqtt.disconnect();

    Serial.println(F("Retrying connection..."));
    delay(5000);

  }

  Serial.println(F("Adafruit IO Connected!"));

}

Here is my screenshoot Serial Monitor

Which Arduino board are you using?

On every Arduino I know, the hardware serial is on pins 0,1. This means you are using software serial on the hardware serial pins, which is a fatal mistake. You probably don't need software serial at all but, for the moment, move it to another pair of vacant pins.

I think you are doing the same thing on NodeMCU, and destined to get the same result, so the same applies.

If you insist on using software serial on NodeMCU, which is probably as bad an idea as it is using anywhere else, I understand you can call it on pins 13,15 i.e. connect to pins D7,D8 on the board.

@OP

There are many many logical/physical problems in your setup and codes. Therefore, I have preferred to prepare a tutorial for you rather than adjusting.correcting your system. Please, follow the steps; be familiar with the basics of hardware/software UART communications and get a working project.

1. Make the following setup among UNO, NodeMCU 1.0 (ESP-12), and DHT11 (Temp-Humidity Sensor).
uartNodeMCUUnoDHT11.png
Figure-1:

2. Hardware UART Port of UN0 (RX, TX = 0, 1) is permanently engaged with the Serial Monitor and IDE; so, leave it there. Use software UART Port (SUART Port: 2, 3 = SRX, STX) to communicate with NodeMCU. The SUART Port is created by including the following lines in the sketch.

#include<SoftwareSrial.h>
SoftwareSerial SUART( 2, 3); //SRX  = DPin-2; STX = DPin-3
SUART.begin(115200);   //to match with NodeMCU which prefers higher Bd to work

3. Similarly, Hardware UART Port of NodeMCU (RX, TX = 3, 1) is permanently engaged with the Serial Monitor and IDE; so, leave it there. Use software UART Port (SUART Port : 4/D2, 5/D1 = SRX, STX) to communicate with NodeMCU. The SUART Port is created by including the following lines in the sketch.

#include<SoftwareSrial.h>
SoftwareSerial SUART( 4, 5); //SRX  = DPin-D2; STX = DPin-D1
SUART.begin(115200);   //NodeMCU prefers higher Bd to work

4. Upload the following sketches in the UNO and NodeMCU. (Read the comments that are given aside of the codes to under the reasons for including the code in the sketch).

Codes for UNO

#include<SoftwareSerial.h>
SoftwareSerial SUART(2, 3); //SRX=Dpin-2; STX-DPin-3
//-------------------------
#include <SimpleDHT.h>
int pinDHT11 = 4;  //Humidity DATA line at A0-pin of UNO
SimpleDHT11 dht11;  //object is created from class
byte temperature = 0;
byte humidity = 0;
//--------------------------------------------

void setup()
{
  Serial.begin(115200); //enable Serial Monitor
  SUART.begin(115200); //enable SUART Port

}

void loop()
{
  //---acquire Temp and Humidity signal and save in variables
  dht11.read(pinDHT11, &temperature, &humidity, NULL);
  
  //---show temp and humidity as integers on Serial moniotr
  Serial.print("Temperature = "); Serial.print((int)temperature); Serial.print(" degC");
  Serial.print("  ");  //space
  Serial.print("Humidity = "); Serial.print((int)humidity); Serial.println(" %H");
  
  //----Send Temp and Humidity signal to NodeMCU via SUART port----
  SUART.print('<');                   //<(start mark)
  SUART.print((int)temperature,DEC);
  SUART.print(',');                   //,(data seperator)
  SUART.print((int)humidity, DEC); 
  SUART.print('>');                   //>(end mark)
  SUART.println();

  delay(1000);
}

Screenshot of the Serial Monitor of UNO in response to above codes
sm76.png

Codes for NodeMCU
The following codes written for NodeMCU just as a test routine. Bring necessary change in this sketch so that you can see the Temperature and Humidity on the Serial Monitor of NodeMCU in the same format as they are appearing on the Serial Monitor of UNO.

#include<SoftwareSerial.h>
SoftwareSerial SUART(4, 5); //SRX=Dpin-D2; STX-DPin-D1
//-------------------------
#include <SimpleDHT.h>
int temperature;
int humidity;
//--------------------------------------------

void setup()
{
  Serial.begin(115200); //enable Serial Monitor
  SUART.begin(115200); //enable SUART Port

}

void loop()
{
  byte n = SUART.available(); //n != 0 means a character has arrived
  if (n != 0)
  {
    char x = SUART.read();  //read character
    Serial.print(x);        //show character on Serial Monitor
  }
}

Screenshot of the Serial Monitor of NodeMCU in response to above codes
sm77.png

Screenshot of the Serial Monitor of NodeMCU after processing of received string
sm78.png

uartNodeMCUUnoDHT11.png

sm76.png

sm77.png

sm78.png

Have a look at the examples in Serial Input Basics - simple reliable 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

...R

GolamMostafa:

Hello, all.

Can you please tell me how you do processing receiving string in last step, what code are used?
I need to use receiving data in nodemcu in functions, assign data to variables value....

@GolamMostafa

Can you please maybe be so kind and provide the code for processing the serial monitor for NodeMCU?
(Processing of the received string?)

Thank you!

VeronicaSand:
@GolamMostafa

Can you please maybe be so kind and provide the code for processing the serial monitor for NodeMCU?
(Processing of the received string?)

Isn't the code in Reply #3?

And have you studied the code in the link in my Reply #4?

...R

Hi,

I'm only getting my values in the serial monitor to be as the screenshot answer number #3. "Screenshot of the Serial Monitor of NodeMCU in response to above codes"

I would like it to look as in the screenshot "
Screenshot of the Serial Monitor of NodeMCU after processing of received string"

I would like to be able to do the same as member qpaQ is asking in reply #5.

Regards

VeronicaSand:
Hi,

I'm only getting my values in the serial monitor to be as the screenshot answer number #3. "Screenshot of the Serial Monitor of NodeMCU in response to above codes"

I would like it to look as in the screenshot "
Screenshot of the Serial Monitor of NodeMCU after processing of received string"

I would like to be able to do the same as member qpaQ is asking in reply #5.

Regards

It means you did something wrong.
What you did wrong, we don't know.
We cannot see what you are doing and how you have everything connected.

Re-check everything.
GolamMostafa seems confident in his answer, so unless he had a mistake, you must follow everything exactly as he had it.

.

You can simply use SerialTransfer.h to automatically packetize and parse your data with no 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 255 bytes)
  • can transfer bytes, ints, floats, and even structs!!

Example TX Arduino Sketch:

#include "SerialTransfer.h"

SerialTransfer myTransfer;

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

void loop()
{
  myTransfer.txBuff[0] = 'h';
  myTransfer.txBuff[1] = 'i';
  myTransfer.txBuff[2] = '\n';
  
  myTransfer.sendData(3);
  delay(100);
}

Example RX Arduino Sketch:

#include "SerialTransfer.h"

SerialTransfer myTransfer;

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

void loop()
{
  if(myTransfer.available())
  {
    Serial.println("New Data");
    for(byte i = 0; i < myTransfer.bytesRead; i++)
      Serial.write(myTransfer.rxBuff[i]);
    Serial.println();
  }
  else if(myTransfer.status < 0)
  {
    Serial.print("ERROR: ");
    Serial.println(myTransfer.status);
  }
}

GolamMostafa:
@OP

There are many many logical/physical problems in your setup and codes. Therefore, I have preferred to prepare a tutorial for you rather than adjusting.correcting your system. Please, follow the steps; be familiar with the basics of hardware/software UART communications and get a working project.

Thanks a lot GolamMostafa, with your tutorial I managed to understand something that I could not find an answer, I googling all afternoon.

Power_Broker:
You can simply use SerialTransfer.h to automatically packetize and parse your data with no headace. The library is installable through the Arduino IDE and includes many examples.

Thank you so much Power_Broker for your suggestion to create a package

Hello guys,

I want to do the same, I also want to establish a reliable serial communication between my Arduino Uno and my ESP-12E Development Board. I have read in a few posts, that you need a level shifter because the ESP12E works with 3.3V and the Arduino with 5V. But I have also seen in other posts (Forum, Youtube) that no level shifter is used and the two boards are connected directly to each other.

What is right? And what do you recommend me to do?

Thanks everybody and with best wishes,
Lars

PS: I use the Arduino Uno for time-critical tasks, because I do not want to overload the ESP with these tasks. I also have read that the WIFI activity of the ESP should not be interrupted for a certain time, so that the Wifi connection is not interrupted.

lindnerlars:
I also want to establish a reliable serial communication between my Arduino Uno and my ESP-12E Development Board.

You need to post a link to the datasheet for your ESP-12E board. It may already have circuitry for voltage level conversion.

I have some bare ESP-12 modules and they do NOT have level conversion.

...R

Hi Robin, thank you for your answer.

I bought my ESP-12E Development Board at a local store. The closest datasheet / manual I can find on the internet, is the following:

So, what do you think? Can I connect it directly or better not?

Thanks again and and with best wishes,
Lars

lindnerlars:
So, what do you think? Can I connect it directly or better not?

Sorry. I don't know. The board in your link is definitely more elaborate than my ESP12 modules - but the link has no mention of the working voltage.

...R

Hi Robin, thank you for your answer.

What I find a little bit strange is that "GolamMostafa" in his post connects his NodeMCU ESP-12 development kit directly to the Arduino Uno without using level conversion. His NodeMCU ESP-12 development kit looks exactly as mine and I assume, that he really connected is this way and it is functioning.

That and because nobody said anything against it, was the reason why I asked again explicitly whether this is really okay.

What do you think? Thanks again and and with best wishes,
Lars

lindnerlars:
What do you think? Thanks again and and with best wishes,

I can't add anything to my Reply #15

...R