Sending a struct over Serial.write()

Hi, I am trying to send serial data from accelerometer to another device.

Here's my code :-

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>
#include <SoftwareSerial.h>


// Assign a unique ID to accelerometer
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);
SoftwareSerial xbee(2, 3);
// Declare the variables for Co-ordinates
double x = 0.0;
double y = 0.0;
double z = 0.0;

void setup()
{
    xbee.begin(57600);
 
	
	// Initialise the accelerometer sensor 
  	if(!accel.begin()) {
    	/* There was a problem detecting the ADXL345 ... check your connections */
    	Serial.println("Ooops, no ADXL345 detected ... Check your wiring!");
    	while(1);
    }

	// Set the range to whatever is appropriate for your project 
	accel.setRange(ADXL345_RANGE_16_G);
	// displaySetRange(ADXL345_RANGE_8_G);
	// displaySetRange(ADXL345_RANGE_4_G);
  	// displaySetRange(ADXL345_RANGE_2_G);
	

}

void loop()
{
	sensors_event_t event; 
	accel.getEvent(&event);
	
	xbee.write(event);
 
}

On the other side. I use something like : -

// some code
event = xbee.read()

x = event.acceleration.x;
y = event.acceleration.y;
z = event.acceleration.z;

But It seems I cannot send the struct 'event' using xbee.write. ? Is there any work around?

I can see two options.

Either send the component elements of event one at a time - e.g. xbee.write(event.acceleration.x) (assuming I have guessed the content correctly). By the way I'm not sure if xbee.write() is limited to sending bytes and if so the elements of the struct would all need to be bytes.

OR use a Union to create a byte array that maps to the same data space as the struct and send the bytes using xbee.write(). The receiving code will need to know how to reconstruct the bytes into the struct.

...R

The problem just the same as sending an int or a double. You take it apart - send it byte by byte - and then put it back together at the other end.

Mark

	xbee.write(event);

Perhaps you should look at just exactly what this code is doing. There are two overloads for write() - one for arrays and one for other than arrays. Exactly which overload are you using, and how many bytes are you sending?

Until you KNOW that, or force the compiler to generate code where you can KNOW the answers, you are just stabbing in the dark as far as reading the data on the other end. Be careful of your foot when you are stabbing in the dark.

Ok, I think the easier option would be to send
event.acceleration.x
event.acceleration.y
event.acceleration.y

over serial.write()

A quick follow up question. Forgive me if this is too obvious but how do I read the variables on the other side?
say if I have

serial.write(event.acceleration.x )
serial.write(event.acceleration.y )
serial.write(event.acceleration.z )

Do I need three serial.read in the recieving script? If yes do I read in the same order as I write?

  1. You are sending from the arduino, but what is going to be receiving the data.? int are 2 bytes long on the arduino but 4 or more on a PC.

  2. Just doing
    serial.write(event.acceleration.x )

will only send on byte you will lose the rest.

  1. Yes you need as many reads as writes.

Mark

Have you tried compiling this?

serial.write(event.acceleration.x )

It looks like x is a double (float in reality) and will throw a compilation error.

write sends a single byte, an array of bytes of specified size or a string. So if you want to send a four byte float, you will have to send them byte by byte by some means.

On the receiving side, read returns a single byte at a time so you will need to reassemble those bytes manually into a float there.

Note also that serial data is slow - the receiving side must use serial.available before each read to verify that there is actually something in the buffer to read.

Your best bet is probably to send the struct as a whole and reassemble it on the receiver. Useful thread here: Send serialized data improvement -Union vs struct - Programming Questions - Arduino Forum

Your best bet is probably to send the struct as a whole and reassemble it on the receiver.

That won't work between arduino and PC different packing of the struct and differnt sizes of vars..

Mark

holmes4:

Your best bet is probably to send the struct as a whole and reassemble it on the receiver.

That won't work between arduino and PC different packing of the struct and differnt sizes of vars..

Mark

Good point on packing and var sizes - endian issues may occur too if you're talking to a device with different characteristics (doesn't look like it here). But what does it matter as long as the receiving code knows this? It just makes the reassembly more complex.