Solved: Sending structure over SoftwareSerial- need help to debug

Hi all,

Please can you help me with the below situation, let me know if you need further details.

I have
master-> Arduino nano
slave-> Nodemcu ESP8266, which is programmed by Arduino IDE

Aim is to send set of float values from Arduino to the ESP.
Issue is- I am unable to extract the data, and i get strange nan values. Also i do not get the last 2 terminators.

I had followed the discussion at below link for my execution.

The code at arduino nano, which simply sends data when i reset it.

/*
  Software serial multple serial test

 Receives from the hardware serial, sends to software serial.
 Receives from software serial, sends to hardware serial.

 The circuit:
 * RX is digital pin 10 (connect to TX of other device)
 * TX is digital pin 11 (connect to RX of other device)

 Note:
 Not all pins on the Mega and Mega 2560 support change interrupts,
 so only the following can be used for RX:
 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69

 Not all pins on the Leonardo support change interrupts,
 so only the following can be used for RX:
 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI).

 created back in the mists of time
 modified 25 May 2012
 by Tom Igoe
 based on Mikal Hart's example

 This example code is in the public domain.

 */
#include <SoftwareSerial.h>
long randNumber;
SoftwareSerial mySerial(6, 7); // RX, TX


struct mystruct {
  float temperature;
  float rainfall;
  float humidity;
  float wind1;
  float wind2;
};

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);

  Serial.println("Goodnight moon!");

  // set the data rate for the SoftwareSerial port
  mySerial.begin(9600);

struct mystruct myData;

myData.temperature = 27.434;
myData.rainfall = 3.9;
myData.humidity = 87.3;
myData.wind1 = 4.98;
myData.wind2 = 5.22;

mySerial.print("\001\002");
mySerial.write((const uint8_t *)&myData,sizeof(struct mystruct));
mySerial.print("\003\004");
Serial.println(sizeof(struct mystruct));


  
}



// ... 

void loop() // run over and over
{
}

Output at nano/master

Goodnight moon!
20

The code at the ESP/slave

/*   For Arduino 1.0 and newer, do this:   */
#include <SoftwareSerial.h>
SoftwareSerial mySerial(14, 12, false, 256);

struct myStruct {
  float temperature;
  float rainfall;
  float humidity;
  float wind1;
  float wind2;
};
char char_in1, char_in2;
char *ptr;
struct myStruct myStructVariable;
long count;
long sizex;

void setup() {
  mySerial.begin(9600);
  Serial.begin(9600);
  //start the library, pass in the data details and the name of the serial port.
  Serial.println("started");
}

void loop() {
  //check and see if a data packet has come in.

  if (mySerial.available()) {
    if (mySerial.read() == '\001') {
      Serial.println("FIRST");
      while (!mySerial.available());
      if (mySerial.read() == '\002') {
        Serial.println("SECOND");
        while (!mySerial.available());


        sizex = sizeof(struct myStruct);
        ptr = (char *)&myStructVariable;
        Serial.println(sizex);

        for (count = 0; count < sizex; count++)
        {
          *(ptr + count) = mySerial.read();
        }  //And I thought the magic should happen here.
        Serial.println("extracted data");
        Serial.println(myStructVariable.wind2);// this is what shows bad data on serial

        while (!mySerial.available());
        //reading terminators
        if (mySerial.read() == '\003') {
          Serial.println("THIRD");
          while (!mySerial.available());
          if (mySerial.read() == '\004') {
            Serial.println("FOURTH");
            while (!mySerial.available());

            Serial.println("message finish");
          }

        }
      }
    }
  }
}

Output at the slave

‚n?†$“¦£ÿ_SAûstarted
FIRST
SECOND
20
extracted data
nan

where am I going wrong? I am exhausted of trying different permutations :confused:

I think the simplest thing is to use a Union to map the struct to an array of bytes and just send the array using Serial.write().

Have the same data structure on the receiving end.

IIRC that is how I did things in this Python Binary Data demo.

...R

Robin2:
I think the simplest thing is to use a Union to map the struct to an array of bytes and just send the array using Serial.write().

Have the same data structure on the receiving end.

IIRC that is how I did things in this Python Binary Data demo.

...R

Even simpler would be waiting for data to arrive, before reading it.

Thank you very much Robin and AWOL.

I have checked Robin’s example and I modified my code to do the similar to his waiting for all bytes to come in before reading.

Thanks AWOL, I had achieved that by checking if mySerial.available()=>24; where 24bytes is the length of data I was sending over. This is the only mod I have done to my slave code and it works wonderfully.

Been a great help, changing it to solved now.