1

Im simply trying to pass my payload to another device that has the same architecture and struct. I'm using UART to transfer, and modeling the protocol from EasyTransfer.

When I call Serial.print((char*)mydata.data); in Transfer it prints Hello World as expected.

Calling that same line in Receive prints a '?' to console. This may be some background behavior with Arduino, or I'm just not casting/handling the pointers correctly. How can I get this print out to function properly?

Transfer Sketch

#include <EasyTransfer.h>

//create object
EasyTransfer TransferObject; 

//Struct contents must be idential to struct from other board
#define PAYLOAD_SIZE 255
struct SEND_DATA_STRUCTURE
{
  int blinks;
  int pause;

  uint8_t data[PAYLOAD_SIZE];
};

//give a name to the group of data
SEND_DATA_STRUCTURE mydata;

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

  //#define details(name) (byte*)&name,sizeof(name) 
  TransferObject.begin(details(mydata), &Serial);

  pinMode(13, OUTPUT);

  //initalize not so random number generator
  randomSeed(analogRead(0));

}

void loop()
{
  //mydata.blinks = random(5);
  //mydata.pause = random(5);

  //Create payload to transfer
  char* payload = "Hello World!";

  //Fill array with data
  strncpy((char *)mydata.data, payload, PAYLOAD_SIZE);

  //Print sample
  Serial.print((char*)mydata.data);

  //send the entire struct
  TransferObject.sendData();

  delay(5000);
}

Receive Sketch

    #include <EasyTransfer.h>

//create object
EasyTransfer TransferObject; 

//Struct contents must be idential to struct from other board
#define PAYLOAD_SIZE 255
struct RECEIVE_DATA_STRUCTURE
{
  int blinks;
  int pause;

  uint8_t data[PAYLOAD_SIZE];
};

//give a name to the group of data
RECEIVE_DATA_STRUCTURE mydata;

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

  //#define details(name) (byte*)&name,sizeof(name) 
  TransferObject.begin(details(mydata), &Serial);

  pinMode(13, OUTPUT);

}

void loop()
{
  //check and see if a data packet has come in. 
  if(TransferObject.receiveData())
  {
    Serial.print("active");
    //print data payload
    Serial.print((char*)mydata.data);
    }

  //you should make this delay shorter then your transmit delay or else messages could be lost
  delay(250);

This is an exerpt and variant from this library

1

You're actually falling into a common problem with pointers in structs.

This structure:

struct SEND_DATA_STRUCTURE
{
  int blinks;
  int pause;

  uint8_t *data;
};

contains three values: blinks, pause and a pointer to the data.

uint8_t *data;

That doesn't contain the data. That only contains the address that the data is stored at in memory. When you transfer the struct it's that address that you are sending - then when the other end tries to print it all it can do is look at the address it's been told about and try and print whatever is in there - and that is complete garbage.

Instead of storing a pointer to the data you need to store the actual data itself. That means that you need to decide upon a maximum size for that data and pre-allocate the memory within the struct:

#define DATA_SIZE 40

struct SEND_DATA_STRUCTURE
{
  int blinks;
  int pause;

  uint8_t data[DATA_SIZE];
};

Now in order to get the data into that struct you need to fill that array with your payload. For strings the simplest way is:

strncpy((char *)mydata.data, payload, DATA_SIZE);

That will copy up to DATA_SIZE characters from payload into mydata.data.

Note that if payload contains more than DATA_SIZE-1 characters the data in mydata.data will not be NULL terminated. You can get round that by forcing NULL termination:

mydata.data[DATA_SIZE-1] = 0;

In your revised code your payload size is too big. The way the EasyTransfer library works is it has a single byte for the size of the payload. Your total payload size is PAYLOAD_SIZE + 2 ints - that is 255 + 2 + 2 = 259 bytes. Placed into a single byte that gets truncated to 3. That means you are actually transferring one and a half integers and nothing else.

You need to ensure that your entire struct never exceeds 255 bytes. So you can have a maximum size of data, once you have taken your two integers into account (assuming 16-bit integers on an 8-bit Arduino), of 251 bytes.

  • Thanks Majenko! And how might I read the data post transfer? Serial.print((char*)mydata.data); shows no output on the recieving device – SensationSama Mar 28 '16 at 20:28
  • Did you replicate the same struct on the receiving end? – Majenko Mar 28 '16 at 20:28
  • They appear to be the same, yeah. I can update that original post with my new code, if that helps. – SensationSama Mar 28 '16 at 20:33
  • Yes. Please do. – Majenko Mar 28 '16 at 20:33
  • Okay, done. :-) – SensationSama Mar 28 '16 at 20:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.