Sending multiple float values via I2C to a RPi

Hello there, Any help would be appreciated, I am a novice programmer with a

For work, I have been tasked to implement the code for a IoT prototype. It consists of a conveyor belt motor, covered in sensors which are being read by a Raspberry Pi running a java program. As two of the sensors (Current and Voltage) output an analog signal (and the RPi has no analog inputs), we are using an Arduino Nano, connected to the RPi via I2C. I am happy enough using the Arduino to interpret the sesnor outputs and calculate a RMS.

But long story short, I need help sending the two float values, via I2C, from the Arduino to the Pi when they are requested.

All examples I have seen use Wire.write, and as we need to send two float values, we need to send the values as a byte array of length 8. (Initially though, I am currently testing the theory with one 4bytes/1float)

On the C++ Arduino, I am using signed char[], and on the Java RPi, I am using byte[], as these both result in 0-255 values (I believe).

Using the pi4j I2C Library, I can successfully send and receive bytes on the RPi through I2C, when I manually specify the bytes as in the slave code below:

#include <Wire.h>

#define SLAVE_ADDRESS 0x04 //This must match the RPi's java code.

void sendReading();

union dataUnion {  
    float f;  
    char fBuff[sizeof(float)];  
} myUnion;  


void setup() {
  Serial.begin(9600);
  Serial.println("We're in!");
  Wire.begin(SLAVE_ADDRESS);
  Wire.onRequest(sendReading);
  myUnion.fBuff[0]=12;
  myUnion.fBuff[1]=13;
  myUnion.fBuff[2]=14;
  myUnion.fBuff[3]=15;
}

void loop() {
}

void sendReading(){
  Wire.write(myUnion.fBuff, 4);
}

But if I try to send a value of 1.234for example, I load the following sketch onto my slave Arduino nano...

#include <Wire.h>

#define SLAVE_ADDRESS 0x04

void sendReading();

union dataUnion {  
    float f;  
    char fBuff[sizeof(float)];  
} myUnion;  


void setup() {
  Serial.begin(9600);
  Serial.println("We're in!");
  Wire.begin(SLAVE_ADDRESS);
  Wire.onRequest(sendReading);
  myUnion.f = 1.234;
}

void loop() {
}

void sendReading(){
  Wire.write(myUnion.fBuff, 4);
}

My RPi code receive the following bytes (-74, -13, -99, 63) which when converted to a float gives me: -7.26027E-6 (Not 1.234)

I'm sure the error is either a silly mistake or me being an idiot around how C++/Java store/convert their floats. (As I say, I'm a novice).

Any help would be appreciated.

Many Thanks,

I strongly suggest you use dtostrf() and send text to the RPi. Much easier to troubleshoot.

On the C++ Arduino, I am using signed char[], and on the Java RPi, I am using byte[], as these both result in 0-255 values (I believe).

Use byte on the Arduino.

 //char fBuff[sizeof(float)];  
byte fBuff[sizeof(float)]

cattledog:
On the C++ Arduino, I am using signed char[], and on the Java RPi, I am using byte[], as these both result in 0-255 values (I believe).

Use byte on the Arduino.

 //char fBuff[sizeof(float)];  

byte fBuff[sizeof(float)]

I did say that I was probably being an idiot around data types! I could have sworn that C/C++ didn't have byte... But that certainly helps a lot debugging, being able to have bytes as decimal values, rather odd characters.

Anyway, Thanks for the replies, but I solved it. I think the issue was around my Endian-ness and using little or big endian when converting the transferred byte array to a float in the java code.

Here is my java code with the initial wrong conversion and the correct one:

float f2 =  ByteBuffer.wrap(bufferBytes).getFloat();
float f3 = ByteBuffer.wrap(bufferBytes).order(ByteOrder.LITTLE_ENDIAN).getFloat();
System.out.println("Bytes as Float Bad: "+f2);
System.out.println("Bytes as Float Good: "+f3);

This outputs the following:

Bytes as Float Bad: -7.26027E-6
Bytes as Float Good: 1.234

I could have sworn that C/C++ didn't have byte..

It doesn't, but it is very easy to create.