Send and Receive array of floats with I2C Wire between two Arduino

Hi,
I have 2 Arduino Leonardo and I need to send some floats from the second to the first board.
I've read many tutorials.. many of them don't work and I don't know where I'm wrong.
Does anyone have a simple example of this kind of communication?
Thank you

Where is your sketch ?
There are a few ways to do that, therefor I would like to see your sketch.
If you give the full sketch for Master and Slave, then I can try it with two Arduino Uno boards that are lying here on my table.

What do you prefer ?
1 ) I2C_Anything
2 ) Array of float
3 ) struct

The I2C_Anything is very nice, an array with float could be the most simple, and I like to use a struct everywhere (even when it is not appropriate).

Sorry I forgot to add them in the previous post :S . I need to transfer array of float
Master code

#include <Wire.h>
byte SLAVE_ADDRESS = 1;
const byte dataCount = 4;

union {
 float floatData[dataCount];
 byte rawData[dataCount*sizeof(float)];
}myData;

void setup() {
   Wire.begin();
   Serial.begin(115200);

}

void loop() {
   readI2C();
  for (int i = 0; i < dataCount; i++)  {
       Serial.print ("Float n. ");
       Serial.print (i);
       Serial.print (" Value: ");
       Serial.println (myData.floatData[i],6);  
       } 
}


void readI2C(){
 
  Wire.beginTransmission(SLAVE_ADDRESS);
  Wire.write((byte)1);
  if (Wire.requestFrom (SLAVE_ADDRESS, sizeof myData) == sizeof myData){
    for(byte i = 0; i < 4*dataCount; i++)
       myData.rawData[i] = Wire.read(); 
   }
  
  Wire.endTransmission();
  }

Slave code

#include <Wire.h>
#define SERIAL_BAUD 115200
#define N_FLOATS 4

volatile byte* arrayPointer;

byte SLAVE_ADDRESS = 1;
byte lastMasterCommand = 99;
float array[N_FLOATS] = {12.3456, 11.111111, 333.33333, 1};

void setup() {
   Serial.begin(SERIAL_BAUD);
   Wire.begin(SLAVE_ADDRESS);
   Wire.onReceive(receiveCommand); 
   Wire.onRequest(requestEvent); 
}

void loop() {

}

void receiveCommand(int howMany){
    lastMasterCommand = Wire.read(); 
}

void requestEvent(){
  switch(lastMasterCommand) {
    case 1:
      writeI2C();
      break;
    // maybe there could be more cases 
  }
}

void writeI2C() {
 byte buffer[4*N_FLOATS];
 arrayPointer = (byte*) &array;
 for(byte i = 0; i < 4*N_FLOATS; i++) 
     buffer[i] = arrayPointer[i];

 Wire.write(buffer,4*N_FLOATS);
}

You are on the right track, but it needs some cleanup.

Sending a command and requesting data, I like that.

Could you check every source code line and improve it ?

If you use the union for everything, and use it everywhere, the code will improve.
It is easy to create a pointer to the union.

union myData_UNION
{
  ...
};
myData_UNION myData;
myData_UNION * pMyData;
...
Wire.write ( (byte *) &myData, sizeof(myData);

The name after the word 'union' is the type.

The receiveEvent() and requestEvent() are interrupt handlers. Every global variable that you use inside those functions should be 'volatile'.

volatile byte lastCommand = 99;

The requestFrom() function is a complete I2C transfer on its own.
It does not use a Wire.beginTransmission and not a Wire.endTransmission().

Write something : Wire.beginTransmission --- Wire.write --- Wire.write --- Wire.endTransmission
Read something : Wire.requestFrom --- Wire.read --- Wire.read

Instead of a for-loop with Wire.read(), you can do this:

Wire.readBytes( (byte *) &myData, sizeof(myData));

The float 'array' in the Slave will be send to the Master in the requestFrom(). That function is an interrupt handler. It means that while you are writing new data in that array, the requestFrom() could interrupt that and the array could contain a half-written float.
To avoid that, the 'array' must be volatile and interrupts must be off when writing it. Often a copy of 'array' is used to write data in, and a fast copy to the volatile array is done while the interrupts are off.

Try to beautify your code, and use that union wherever you can (instead of temporary buffers). Upload your sketch and I check it again.

I m trying to send a byte array over I2C and i m trying to understand what you mean by the code

Wire.write ( (byte *) &myData, sizeof(myData);

My slave code looks like this

volatile byte leArray[6];
volatile boolean sendStuff;

//...
//...

void fillArray()
{
  leArray[0] = (byte)someByte1;
  leArray[1] = (byte)someByte2;
  leArray[2] = (byte)someByte3;
  leArray[3] = (byte)someByte4;
  leArray[4] = (byte)someByte5;
  leArray[5] = (byte)someByte6;

}
void requestEvent()
{   
  if(sendStuff)
  {
    Wire.write(leArray, 6);
  } 
  sendStuff= false;
}

This wont compile because of some problem with the array, however when I applied something similar to your exampls like the following,

volatile byte* leArray[6];
volatile boolean sendStuff;

//...
//...

void fillArray()
{
  leArray[0] = (volatile byte*)someByte1;
  leArray[1] = (volatile byte*)someByte2;
  leArray[2] = (volatile byte*)someByte3;
  leArray[3] = (volatile byte*)someByte4;
  leArray[4] = (volatile byte*)someByte5;
  leArray[5] = (volatile byte*)someByte6;

}
void requestEvent()
{   
  if(sendStuff)
  {
    Wire.write((byte*)&leArray, 6);
  } 
  sendStuff= false;
}

this compiles. My knowledge on pointers, referencing and dereferencing is a little shakey. So is my implementation correct?

 Wire.write(leArray, 6);

This wont compile because of some problem with the array,

This syntax is correct for sending an array of bytes. You should address the issue about why you can not fill the array with bytes and your sketch fails to compile.

rockeronline00:
Hi,
I have 2 Arduino Leonardo and I need to send some floats from the second to the first board.
I've read many tutorials.. many of them don't work and I don't know where I'm wrong.
Does anyone have a simple example of this kind of communication?
Thank you

rockeronline00,

here are a couple of prior questions that might solve your problems.
Sending FLOATs over I2C
I2C, Wire.h Communication between 2 arduinos problem

Chuck.


Check out my Kickstarter Project Memory Panes an expansion RAM Shield for Mega2560's. It adds 1MB of RAM for those projects where 8KB is not enough.

To cattledog,

I was able to fix my problem, from another thread,