Serial Communication using <SerialTransfer.h> (ArduinoUno-NodeMCU ESP8266)

I'm trying to have a serial communication between an Arduino Uno and a NodeMCU (ESP8266).
In this code there are 3 structures to send the data from the Sender(Arduino) to the Receiver(NodeMCU).

the first object is myTransfer, the second object is testStruct, the third one is arr.

If I run this code with a serial communication with ArduinoUno<-->ArduinoUno, this is working good. When I try to have a serial communication ArduinoUno<-->NodeMCU I don't obtain the values I want. The only thing that I'm able to obtain in NodeMCU serialmonitor (the receiver) is the object myTransfer.rxBuff = 200.

I've added some commentary to a really easy understanding of the serialmonitor.

ArduinoUno

#include "SerialTransfer.h"
//TX

SerialTransfer myTransfer;

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

uint16_t arr[3] = {0, 1, 2};


void setup()
{
  //Serial.begin(115200);
  Serial.begin(9600);
  myTransfer.begin(Serial);

}


void loop()
{

  testStruct.z = '|';
  testStruct.y = 4.5 + random(1,15);
  // use this variable to keep track of how many
  // bytes we're stuffing in the transmit buffer
  uint16_t sendSize = 0;

  ///////////////////////////////////////// Stuff buffer with individual bytes
  myTransfer.txBuff[0] = 'h';
  myTransfer.txBuff[1] = 200;
  sendSize += 2;

  ///////////////////////////////////////// Stuff buffer with struct
  myTransfer.txObj(testStruct, sizeof(testStruct), sendSize);
  sendSize += sizeof(testStruct);

  ///////////////////////////////////////// Stuff buffer with array
  myTransfer.txObj(arr, sizeof(arr), sendSize);
  sendSize += sizeof(arr);

  ///////////////////////////////////////// Send buffer
  myTransfer.sendData(sendSize);
  delay(100);
}

NodeMCU

#include "SerialTransfer.h"
//RX

SerialTransfer myTransfer;

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

uint16_t arr[3] = {};


void setup()
{
  Serial.begin(9600);
  myTransfer.begin(Serial);
}


void loop()
{
  if(myTransfer.available())
  {
    // use this variable to keep track of how many
    // bytes we've processed from the receive buffer
    uint16_t recSize = 0;

    Serial.println("we are printing myTransfer.rx.Buff");
    Serial.print("myTransfer.rxBuff[0]: ");
    Serial.print(myTransfer.rxBuff[0]);
    Serial.print(' ');
    Serial.print("myTransfer.rxBuff[1]: ");
    Serial.print(myTransfer.rxBuff[1]);
    Serial.print(" | ");
    Serial.println("");
    Serial.println("");
    recSize += 2;


    myTransfer.rxObj(testStruct, sizeof(testStruct), recSize);
    Serial.println("we are printing testStruct:");
    Serial.print("testStruct.z: ");
    Serial.print(testStruct.z);
    Serial.print(' ');
    Serial.print("testStruct.y: ");
    Serial.print(testStruct.y);
    Serial.print(" | ");
    recSize += sizeof(testStruct);
    Serial.println("");
    Serial.println("");


    Serial.println("we are printing arr: ");
    myTransfer.rxObj(arr, sizeof(arr), recSize);
    Serial.print("arr[0]: ");
    Serial.print(arr[0]);
    Serial.print(' ');
    Serial.print("arr[1]: ");
    Serial.print(arr[1]);
    Serial.print(' ');
    Serial.print("arr[2]: ");
    Serial.println(arr[2]);
    Serial.println("");
        Serial.println("");

  }
  else if(myTransfer.status < 0)
  {
    Serial.print("ERROR: ");
    Serial.println(myTransfer.status);
  }
  //delay(5000);  //if we put a very high delay it might be synch errors, infact I get..
                //i.e. error1, error2, ....
}

I'm posting 2 images of the output that gets the receiver: before the ArduinoUno Receiver and then the NodeMCU Receiver

Can anyone with an ArduinoUno and a NodeMCU/ESP8266 give a try?
What do I have to do/change to make a good serial communication with NodeMCU? Thank You

arduino_nodeMCU.PNG

Everything looks good with one small (but very important) problem:

myTransfer.begin(Serial);

This means you're trying to send and receive packets via USB. This is all well and good if you're trying to connect a single Arduino to your PC and pass data back and forth via an app (i.e. a Python program using pySerialTransfer), but you can't do this when communicating between two Arduinos.

What you want to do instead is something like this (for hardware serial ports):

myTransfer.begin(Serial1);

or this (for software serial ports):

myTransfer.begin(mySerial);

Edit: I see you're using an Uno - you will need to use a software serial port
What type of Arduino are you using and how are you wiring the two boards together?

So the wiring with the ArduinoUno (Tx) and the NodeMCU(Rx) is:

ArduinoUno | NodeMCU


gnd | gnd


0 (rx) | tx


1 (tx) | rx


vcc(usb.cab)| vcc(usb.cab)

Well I didn't know about this difference between software an hardware serial port.

Anyway my goal is to have arduino that sends 2 floats to the NodeMCU, then i will be able to put it in a WebServer. So I think that I don't need an hardware port. I don't know if I have get your point..

What should I do?

This is the temporarily horrible solution I ended up with, that gives two floats output, as i would like to have.

ArduinoUno (tx)

#include "SerialTransfer.h"
//TX

SerialTransfer myTransfer;




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




void loop()
{

Transf1();
Transf2();

 delay(1000);
}


void Transf1() {
    myTransfer.begin(Serial);
    float t = 4.5 + random(1,15);
      myTransfer.txObj(t, sizeof(t));
        myTransfer.sendData(sizeof(t));
          delay(100);
}

void Transf2() {
  myTransfer.begin(Serial);
    float h = 55.6 + random(1,15);
     myTransfer.txObj(h, sizeof(h));
     myTransfer.sendData(sizeof(h));
       delay(100);
  }

NodeMCU (rx)

#include "SerialTransfer.h"
//RX

SerialTransfer myTransfer;

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



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


void loop()
{
  if(myTransfer.available())
  {
    float x;

    myTransfer.rxObj(x, sizeof(x));

    if(x < 40) {
      Serial.print("the temperature is: ");
      Serial.println(x);
      Serial.println("");
      }

     if(x>50) {
     Serial.print("the humidity is: ");
     Serial.println(x);
     Serial.println("");
     }
     }
     delay(100);
    }

You should never use the USB serial port on an Arduino if you're trying to debug via the serial monitor. As for the ESP32, you should use one of the non-usb hardware serial ports.

You need to do more research on how hardware/software serial ports need to be configured on Arduinos...

I'm trying to perform a simple serial communication using the software serial ports.

wiring: 4<-->5 || 5<--->4 || gnd<-->gnd || both on usb cable

these below are the codes:

arduino a:

//Uno Tx //COM3

#include <SoftwareSerial.h>
int a, b;

SoftwareSerial s(4, 5); // RX, TX

void setup()  
{
 
 s.begin(9600);

}

void loop()
{

 a = 10 + random(1,9);          // for testing
 
 s.write(a);            //send the numbers

 
 delay(1000);
}
//Rx

#include <SoftwareSerial.h>
int a;

SoftwareSerial s(4, 5); // RX, TX

void setup()  
{
 //Serial.begin(9600);
 s.begin(9600);
 
}

void loop()
{
 while (s.available()) {   //read the two numbers
   s.println("we are in s.available");
   a = s.read();
   s.println(a);

}
 delay(1000);
}
  • My question is why can't I see anything on the serial monitor? If I use the Hardware Serial port in the arduino b that rx, I'm able to see the data in the serial monitor. Can't I use the Sooftware serial ports in both arduino? Thanks
//Rx

#include <SoftwareSerial.h>
int a;

SoftwareSerial s(4, 5); // RX, TX

void setup()
{
   Serial.begin(9600);
   s.begin(9600);

}

void loop()
{
   while (s.available())     
   {
      Serial.println("we are in s.available");
      a = s.read();  // read one byte from the serial buffer
      Serial.println(a);
   }
   delay(1000);
}

Try this. The hardware serial (Serial) is connected to the serial monitor not software serial, unless you have an external ttl to usb converter connected to a different serial port on the PC.

Some really good information on serial communication in the serial input basics tutorial.

groundFungus:
Some really good information on serial communication in the serial input basics tutorial.

Just studied that. So basically you call both of hardware(to communicate to pc) and software serial ports(to communicate with the arduino tx) i thought one would exclude the other way.

For example the line of code s.println(a) doesn't have any sense, would mean that is printing the value to arduino that is tx?
Anyway the code now works, thank you

You can 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 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);
  }
}

So basically you call both of hardware(to communicate to pc) and software serial ports(to communicate with the arduino

That is right.

s.println(a)

Will send 'a' out of the software serial port TX to the other Arduino software serial port's RX.

I'm studying serial communication with two arduino Unos.

I'm sending a simulated, with random(), integer value as a char array form ArduinoA to ArduinoB + a "," comma character.

When I'm sending just the integer (without the comma) the value arrives with no problems. So I'm able to print all the single values of this two element array in ArduinoB; but I'm not able to see the entire char array when I try to print it. Why is this happening?

These below are the codes:

ArduinoA

//Sender Code //ArduinoA
#include <SoftwareSerial.h>
SoftwareSerial s(4,5);
char str[2];

void setup() {
  s.begin(9600);
}

void loop() {
  //int value=1234; //this would be much more exciting if it was a sensor value
  int value = 10 + random(1,5); //integer part
  
  itoa(value, str, 10); //Turn value into a character array
  s.write(str, 2);
  //s.write(","); //try to add. this is messing up everything

}

ArduinoB

//Receiver Code //ArduinoB
#include <SoftwareSerial.h>
SoftwareSerial s(4,5);

  //char str[4];  //this work not well out of void loop
int iter;

void setup() {
  Serial.begin(9600);
  s.begin(9600);
}

void loop() {
  iter++;                        //counting the iteration

  int i = 0;
  char str[2];  //char str[1]                 //resetting the str array
Serial.print("iteration n°: ");
Serial.println(iter);
Serial.println("");

  if (s.available()) {
    delay(100); //allows all serial sent to be received together
    while(s.available() && i<2) {     //str start with [0]
      i++;   //next str element.


      str[i] = s.read();  //pulling one by one the bytes from serial buffer
      Serial.print("i: ");
      Serial.println(i);
      
      Serial.print("str[i++]: ");
      Serial.println(str[i]);
      delay(500);

    }
    str[i]='\0';
  }
      Serial.println("");
      Serial.println("str: ");
      Serial.println(str);      //why this is giving an empty element?
     // Serial.println("it gives back nothing...");
     // Serial.println("");

  if(i==3) {

    delay(2000);
  }
}

If I try Serial.write(",") a comma, everything is messing up in a way that i cannot understand.
Anyone has some good tutorials of serial communication with two arduinos? Thanks

char array strings HAVE to be long enough to hold your text plus end with a terminating zero.

char myString[] = "test"; // makes a 5 char array with elements 't', 'e', 's', 't', 0.

Did you not get the answer you wanted here?

@riemanndiy

TOPIC MERGED.

Could you take a few moments to Learn How To Use The Forum.
Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum.

I'm trying different ways to send two float numbers from an ArduinoUno to another ArduinoB.
I was trying the communication with String element. This seems to be very simple and works very good.
For what I understand many people suggest not to use String elements.. I've checked that they "weight" only 6 bytes.

wiring: gnd<-->gnd || 3<-->2 || 2<-->3 || vcc: both on usb cable

These below are the codes:

Arduino A Tx

#include <SoftwareSerial.h>

SoftwareSerial s(3,2); // rx, tx
String data;
float a;
float b;

void setup() {
  s.begin(9600);
  //Serial.begin(9600);
}


void loop() {
  a = 10.4 + random(1,6);
  b = 20.2 + random(5,8);
  data = "<"+String(b)+","+String(a)+">";
  //s.write(data);
  s.println(data);
  delay(500);
}

Arduino B Rx

#include <SoftwareSerial.h>

SoftwareSerial s(3,2); //rx, tx

String data;
String old_data;

void setup() {
  s.begin(9600);
  Serial.begin(9600);
}

void loop() {

  //data = s.read();
  if(s.available()>0) {
  data = s.readString();
  delay(100);
  Serial.print("sizeof data: ");
  Serial.println(sizeof(data)); //6 bytes
  Serial.println(data);
  }
  

  //s.println(data);
}

- My question is how can I split this string, so that I'm able to recognize that with < starts the packet, with , starts the second float number, with > ends the packet.

  • Can you do this communication with char, or in another effective way without using String?

Power_Broker:
You can use SerialTransfer.h to automatically packetize and parse your data for inter-Arduino communication without the headace.

Also without learning what goes on with serial communication.

@ballscrewbob I've already read how to use the forum. Is the problem that I'm posting too much of the same topic? I'm trying to understand serial communication having quite hard time. So I would need guidance.

Also without learning what goes on with serial communication.

I think I need to learn well Serial Communication, because my final goal is to send continuosly "a packet" of two float numbers, so I'm starting from the very basic of Serial Communication. Believe me I've tried different libraries to perform this task: ArduinoJson, SerialTransfer but with no success. I've already read Robin2 tutorial. Finally I'm able to make some serial communication work. Thanks also for your suggestions

If you did read the "how to" then you will know that multiple questions about the same and related topics is frowned on.

GoForSmoke:
Also without learning what goes on with serial communication.

Wrong. The library is written fairly straightforward such that an intermediate coder can learn "what goes on with serial communication". Not to mention you can learn all about what exactly the library does by reading the advanced version of "Serial Input Basics".

Curious, if somebody is trying to parse normal NMEA strings or trying to poll accelerate data from an MPU6050 brute force, wouldn't you suggest good libraries to use?

riemanndiy:
Believe me I've tried different libraries to perform this task: ArduinoJson, SerialTransfer but with no success. I've already read Robin2 tutorial.

What exactly were you having trouble with in terms of ArduinoJson and SerialTransfer?

@ballscrewbob I understand your point of view, but I'm encountering different problems that are all related and belongs to this topic, because I'm studying Serial Communication. Anyway I will post my topics opportunely.

What exactly were you having trouble with in terms of ArduinoJson and SerialTransfer?

In ArduinoJson I'm able to make just one Tx of a packet of serialized data(in this case int, but would be the same if were float), and after that the Deserialization doesn't work anymore. The topic is here --> ArduinoJson

In SerialTransfer we talked about the problem that I was able to have a constant communication but only with one float number, but I need to have a communication with two float numbers. The topic is here --> SerialTransfer

Another option I'm trying is to use String, where I need to split the string of these packet of data. The topic is here --> Serial.readString()

advanced version of "Serial Input Basics".

I didn't see this, I will check it asap. Thank You