Yet another issue I'm struggling with sending data to ESP8266 via serial line

Status
Not open for further replies.

KrisKasprzak

Well-known member
Still fighting with these ESP units. I'm trying to send data from a teensy 3.2 to an ESP8266. From the teensy if I Serial3.Println("Teensy is better that ESP"); all is well. if i send a struct, data gets corrupted. I can get less corruption by changing baud rates, but....

Data types are the same size for Teensy and ESP, i have no clue why data is corrupted. Help anyone?

Code that runs on a teensy
Code:
// code to run on and Teensy 3.2
// this Tx connects to ESP8266 Rx
// this Rx connects to ESP8266 Tx
struct Test {

  uint16_t Data1;
  uint16_t Data2;
  uint16_t Data3;
};

Test MyData;
  
 
void setup()
{
  Serial.begin(115200);
  Serial3.begin(115200);

}

void loop() {

  MyData.Data1 = 11;
  MyData.Data2 = 22;
  MyData.Data3 = 33;

  Serial3.write((uint8_t*) &MyData, sizeof(MyData));
  Serial3.flush();
  //Serial3.println("message from Nano"); // just this line prints fine
  Serial.println("sent...");
  delay(1000);
}


Code that runs on a ESP8266
Code:
// code to run on and ESP8266
// this Tx connects to teensy Rx
// this Rx connects to teensy Tx
#include <SoftwareSerial.h>


struct Test {
  uint16_t Data1;
  uint16_t Data2;
  uint16_t Data3;
};

Test MyData;

SoftwareSerial fromTeensy(4, 5); //Rx, Tx

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

}

void loop()
{
  if (fromTeensy.available())
  {
    fromTeensy.readBytes((uint8_t*) &MyData, sizeof(MyData));
    fromTeensy.flush();
    delay(10);
    // char inChar = fromTeensy.read(); //just these 2 lines prints fine
    // Serial.println(inChar);

    Serial.print("Data1 "); Serial.println(MyData.Data1);
    Serial.print("Data2 "); Serial.println(MyData.Data2);
    Serial.print("Data3 "); Serial.println(MyData.Data3);

    // results
    // Data1 8459
    // Data2 22
    // Data3 33
    // Data1 5632
    // Data2 8448
    // Data3 33
    // Data1 5632
    // Data2 8448
    // Data3 33
    // Data1 11
    // Data2 22
    // Data3 33

  }
}
 
In many cases like this, one of the first things I would do is to do things like: Serial.printf("size of MyData: %d\n", sizeof(MyData));

And make sure they are the same.

Also I have no idea how reliable the SoftwareSerial is on the ESP32. it may be and probably is just fine at 115200

Again I have not done much with ESP32... But I wonder with Software Serial what these lines do:
Code:
    fromTeensy.readBytes((uint8_t*) &MyData, sizeof(MyData));
    fromTeensy.flush();
Yes readBytes will iterate the number of bytes or timeout ...

But flush? is it old style flush - clears out the input queue or more recent versions, wait until any pending outputs complete?

Often times with code like this, I am a bit cautious as there is nothing synchronizing the stream between the two processors. So for example if I get misaligned, and then I might start getting junk from the other side and nothing will realign us. I believe the default timeout for readBytes is one second. I often roll my own and if I get a gap between bytes that is too long, I assume I am screwed up and then I flush the input and keep flushing, until I get a gap between bytes long enough where I would suspect the next thing I received was start of new packet.

Note: there are libraries out there that do a bunch of this stuff for you, like the EasyTransfer library.
 
Well still no go...

1. i've tried every baud in the book the faster the less corrupt
2. I did try sizeof(uint16_t) on both MCU, both returned 2 bytes
3. I did try sizeof(MyData) on both MCU, both returned 6 bytes
4. I just tried the following and still corrupt, but only like 10% of the time

#pragma pack(push, 1); // no padding
struct Test {
uint16_t Data1;
uint16_t Data2;
uint16_t Data3;
} zdo_simple_desc_resp_header_t;
#pragma pack(pop)

Test MyData;


Does anyone have a Teensy3.2 and a NodeMCU ESP8266 that can take a look? I really have no idea how to remedy this.
 
tried this as well.

#define PACKED_STRUCT struct __attribute__((packed))
struct Test {
uint16_t Data1;
uint16_t Data2;
uint16_t Data3;
} ;

Test MyData

Is this problem even fixable?
 
tried this as well.

#define PACKED_STRUCT struct __attribute__((packed))
struct Test {
uint16_t Data1;
uint16_t Data2;
uint16_t Data3;
} ;

Test MyData

Is this problem even fixable?

Try this instead
Code:
#define PACKED_STRUCT   struct __attribute__((packed))
PACKED_STRUCT Test {
  uint16_t Data1;
  uint16_t Data2;
  uint16_t Data3;
} ;

Test MyData
 
Sorry I don't know if I have any 8266s... So probably can not help here.

When starting out I would probably reduce the baud rate to 9600. Obviously you need to do on with both sketches.

My quick look through ESP8266 SoftwareSerial has too much of the newer c++ verbiage in it for me to easily read ;) (Sometimes hard to teach old dog new tricks)
Again I would probably add additional quick and dirty packet processing in to try to validate the data...
Something quick and dirty like: 0xff <count of data bytes> [ your data bytes ] <checksum of data bytes> (probably a real simple checksum. Like simply add up all of the bytes into a unit8_t ...

Edit: I did a quick search on ESP8256 SoftwareSerial - And found a github for it: https://github.com/plerup/espsoftwareserial

And it appears like 115200 is the highest speed it should handle. Also the Readme had an interesting quote:
Please note that due to the fact that the ESPs always have other activities ongoing, there will be some inexactness in interrupt timings. This may lead to inevitable, but few, bit errors when having heavy data traffic at high baud rates.
 
Last edited:
@KrisKasprzak - think I know where my 8266 but can I ask for a clarification on something I may have missed.

Did you try not using softwareserial on the 8266. If I remember right 2 h/w serial ports you can use but its been a long time since I played with an 8266.
 
I can try hardware serial unfortunately Serial1 is for USB if i recall. I've got USB connected so i'm forced to use Sofwareserial.

However.

The suggestion to use easyTransfer lib works. I'm transferring some 50 bytes every second, and so far after an hour of running it's not list a bit.

Now onto the next part (see my other post for using Teensy with Wifi).

Thanks to all for prompt, professional, helpful support!
 
Maybe so, but I can't see to program the esp or monitor serial activity if wires are connected to Rx and Tx.

Ah... I see what you mean.
I remember, that I had connected it to the Teensy, and when I wanted to program the ESP I loaded a short "proxy" Sketch to the teensy. It routed the Serial data to the ESP. It even switched the needed GPIOs.
 
Status
Not open for further replies.
Back
Top