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);
1 Answer 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 deviceWomble– Womble03/28/2016 20:28:03Commented Mar 28, 2016 at 20:28
-
Did you replicate the same struct on the receiving end?Majenko– Majenko03/28/2016 20:28:36Commented Mar 28, 2016 at 20:28
-
They appear to be the same, yeah. I can update that original post with my new code, if that helps.Womble– Womble03/28/2016 20:33:17Commented Mar 28, 2016 at 20:33
-
-