Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 16 of 16

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

  1. #1

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

    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
    
      }
    }

  2. #2
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,061
    Might be wrong, but without digging deep into this I'd say this is an alignment problem of your struct. The compiler may arrange the variables to convenient (for the compiler) positions in the memory. If you want to transfer such structs you need to force the compiler not do this. Here a nice write up from KurtE how to do this https://forum.pjrc.com/threads/56056...l=1#post205233

  3. #3
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,463
    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.

  4. #4
    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.

  5. #5
    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?

  6. #6
    I will try the easytransfer library tomorrow

  7. #7
    Member
    Join Date
    Aug 2018
    Location
    Brisbane, Australia
    Posts
    24
    Quote Originally Posted by KrisKasprzak View Post
    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

  8. #8
    Senior Member
    Join Date
    May 2017
    Posts
    106
    Maybe a problem with baud rate error.

    Take a look there: https://www.pjrc.com/teensy/td_uart.html

    Maybe try to adjust baud rate on ESP-side, don't know how software serial works.

  9. #9
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,463
    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 by KurtE; 04-17-2020 at 03:12 PM.

  10. #10
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    5,556
    @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.

  11. #11
    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!

  12. #12
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    6,920
    The ESP has a hardwareserial. I know this because I used the AT-Mode with 6Mbit.

  13. #13
    Maybe so, but I can't see to program the esp or monitor serial activity if wires are connected to Rx and Tx.

  14. #14
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    6,920
    Quote Originally Posted by KrisKasprzak View Post
    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.

  15. #15
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    6,920
    Found it. You can modify this code (remove #include <Flexiboard.h> and all dependencies - they're not needed)
    https://github.com/FrankBoesing/Flex...ashESP8266.ino

    I wrote it for a old board I made (with ESP8266 soldered to it)

  16. #16
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    12,226
    I linked my Teensy proxy code on the other thread: Super-stuck-with-ESP-01-serial-module-and-I-m-desperate-for-help

    If you can enable and work with OTA updates that frees up the Serial port - and also runs faster.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •