EasyTransfer for ESP8266

I’m going to describe here the transmitting side of the EasyTransfer system as used in Arduino – the reason I did this was because I wanted to ship a bunch of binary data from the ESP8266 to the Arduino where I have a nice little wall mounted LCD display – no point in re-inventing the wheel.

EasyTransfer is a simple enough format – it starts with 0x6 and 0x85 followed by the length (all in bytes) of what you want to send, the data itself and a one-byte checksum which is the length XOR’d by every byte in the data (not including the checksum itself of the header 0x6 and 0x85.

So you point a structure to it – and off it goes and the structure is recreated at the other end. Or it is?

struct transmit_lcdX {
  //put variable definitions here for the data you want to receive
  //THIS MUST BE EXACTLY THE SAME ON THE DISPLAY BOARD
  uint8_t cmd;
  int16_t passed;
  uint8_t humidity;
  uint32_t thetime;
  int8_t internal;
  int8_t external;
  uint8_t pre;
  uint8_t heat;
  uint8_t hold;
  int8_t offset;
  uint8_t set;
  uint8_t fallback;
  uint8_t falltemp;
  uint8_t thermenable;
  uint8_t dusk_hour;
  uint8_t dusk_min;
  uint8_t dawn_hour;
  uint8_t dawn_min;
} ;

struct transmit_lcdX transmit_lcd;

 

//Sends out struct in binary, with header, length info and checksum
void ICACHE_FLASH_ATTR EasyTransfer_sendData( uint8_t *bfr, uint8_t size){
    uint8_t buf[40];
    uint8_t CS;
    CS = size;
    buf[0]=0x06;
    buf[1]=0x85;
    buf[2]=CS;
    for(int i = 0; i<size; i++){
        CS^=*(bfr+i);
        buf[i+3]=*(bfr+i);
    }
    buf[size+3]=CS;
    uart0_tx_buffer(buf,size+4);
}

There you go – what could be simpler – define the struct – make an instance of it called transmit_lcd – and call a function passing the address of the structure and it’s length.

Well the first bit I got wrong was to send it out in pieces. I did not realise that Espressif’s function uart0_tx_buffer(buf,len) doesn’t operate immediately – clearly it works in the background under interrupts – I guess the word “later” in the instructions should have made me twig but it didn’t.  So first things first, that structure buf[] has to be static – so that it stays there even after the function has done and cleaned up.

That was fine – and so I called my function – nothing… the LCD would not accept the data… I must’ve spent hours on this – I eventually grabbed a terminal with hex output and…. I’d set the time – and sure enough my checksum was working – but the time was in the wrong place.  2 8-bit integers and a 16-bit come to 4 bytes so what I should have seen was 06 86 0xff 00 00 00 00 aa bb cc dd   where ff is the checksum and aa bb cc dd is the 32 bit time.

But no – the time was much further on! How can this be! WELL it turns out that without a special optimisation, DESPITE the fact that I called some of those variables in the struct 8 bits – they were ACTUALLY being stored as 16 bits –   WHAT!!!

So here we have the version that WORKS – of course you can replace the struct data with any old variables – this just happens to be mine….

struct transmit_lcdX {
  //put variable definitions here for the data you want to receive
  //THIS MUST BE EXACTLY THE SAME ON THE DISPLAY BOARD
  uint8_t cmd;
  int16_t passed;
  uint8_t humidity;
  uint32_t thetime;
  int8_t internal;
  int8_t external;
  uint8_t pre;
  uint8_t heat;
  uint8_t hold;
  int8_t offset;
  uint8_t set;
  uint8_t fallback;
  uint8_t falltemp;
  uint8_t thermenable;
  uint8_t dusk_hour;
  uint8_t dusk_min;
  uint8_t dawn_hour;
  uint8_t dawn_min;
__attribute__((packed)) ;

struct transmit_lcdX transmit_lcd;

 

//Sends out struct in binary, with header, length info and checksum
void ICACHE_FLASH_ATTR EasyTransfer_sendData( uint8_t *bfr, uint8_t size){
    static uint8_t buf[40];
    uint8_t CS;
    CS = size;
    buf[0]=0x06;
    buf[1]=0x85;
    buf[2]=CS;
    for(int i = 0; i<size; i++){
        CS^=*(bfr+i);
        buf[i+3]=*(bfr+i);
    }
    buf[size+3]=CS;
    uart0_tx_buffer(buf,size+4);
}

Note the two additions in BOLD above – if either is missing – this does NOT work. 

So now, if you have some legacy stuff on an Arduino and you need to pass a struct back to it using EasyTransfer – you can. 

13 thoughts on “EasyTransfer for ESP8266

  1. Hi. I am trying to include your code into my project on NodeMcu Esp8266 and I get error “‘uart0_tx_buffer’ was not declared in this scope”. Is it part of some standard library that I am omitting? Could you provide an example file so I can figure how to use it?

      1. Thank you for your quick reply. I have tried including both uart.h and uart.c and both with no positive result. I would like to ask you two more troubleshooting questions: Do you use Arduino IDE for compiling or some other software? And, as you are referring to your code, is there an obvious place on this blog where I can lookup the full code and I am just to stupid to see it?

        1. I don’t use Arduino IDE – I use a PC with the unofficial development environment using Eclipse – and in the home control 2016 blog article (see links on right side) you’ll find links.

          1. Thank you, I will inspect them and hopefully I will be able to make it work in my project 🙂

  2. Hi.
    I need to do the oposite, I mean, sending data from Arduino Nano to ESP8266.
    I’m a regular programer in Arduino, not a C expert so any help is wellcome.

    Thanks

  3. can you explain the second half of the working code? where does it go? it does not match any code I have in either the example sketch or the library file. I am using arduino on the esp module, is that the difference?

  4. Hi… we want to send you a private message, but there is no email contact in your web (really there is a contact form in one of your personal websites, but we prefer not to use it without your permission).

Comments are closed.