Thursday, October 28, 2021

[SOLVED] How to exchange data between Teensy4.1 and RaspberryPi 4 using serial interface

Issue

I need to exchange data (roughly 100 bytes 10 times a second) between Teensy4.1 and RaspberyPi 4. I decided to do this via serial interface. There is Teensy code:

float r=191.699997;
byte * b = (byte *) &r;
Serial8.write(b, 4);

I have hard-coded 191.699997 for test purposes.

Please find below RaspberryPi Java part:

System.out.println("----------------");
System.out.format(7 + " : " + TEENSY.getData(7) + "\n");
System.out.format(8 + " : " + TEENSY.getData(8) + "\n");
System.out.format(9 + " : " + TEENSY.getData(9) + "\n");
System.out.format(10 + " : " + TEENSY.getData(10) + "\n");

data[0]=(byte)TEENSY.getData(7);
data[1]=(byte)TEENSY.getData(8);
data[2]=(byte)TEENSY.getData(9);
data[3]=(byte)TEENSY.getData(10);

System.out.format(7 + "' : " + data[0] + "\n");
System.out.format(8 + "' : " + data[1] + "\n");
System.out.format(9 + "' : " + data[2] + "\n");
System.out.format(10 + "' : " + data[3] + "\n");

ByteBuffer buffer = ByteBuffer.wrap(data);
int first = buffer.getInt();
float second = buffer.getFloat();

System.out.print("int: " + first);      System.out.print("\n");
System.out.printf("float: %f \n", second);
System.out.println("----------------");

The output of the above code is the shown bellow:

----------------
7 : 51
8 : 179
9 : 63
10 : 67
7 : 51
8 : -77
9 : 63
10 : 67
int: 867385155
float: 0.000000
----------------

I understand why is the difference but have no idea how to make it working (by working I mean how to get 191.699997 on the Raspberry Pi side.

Thanks in advance for your hints.


Solution

You have two issues: the ByteBuffer advances position after "getting" and Java is big endian by default:

This code should demonstrate:

public static void main(String[] args) {
    byte[] b = new byte[4];
    b[0] = 51;
    b[1] = -77;
    b[2] = 63;
    b[3] = 67;

    ByteBuffer buffer = ByteBuffer.wrap(b);
    int first = buffer.getInt();
    float second = buffer.getFloat(0);
    
    System.out.println("f="+first+" s="+second);
    
    b[0] = 67;
    b[1] = 63;
    b[2] = -77;
    b[3] = 51;

    buffer = ByteBuffer.wrap(b);
    first = buffer.getInt();
    second = buffer.getFloat(0);
    
    System.out.println("f="+first+" s="+second);

}

Prints:

f=867385155 s=8.346844E-8
f=1128248115 s=191.7

And looking further the integer 1128248115 (as printed from Java ) in hex :

0x433FB333

And the integer 867385155 your code displayed (from Java on PI side) in hex :

0x33B33F43

Note that you can change the byte-order of a ByteBuffer by something like:

ByteBuffer buffer = ByteBuffer.wrap(b).order(ByteOrder.LITTLE_ENDIAN);

And then your code works (again with the getFloat(0)!:

    byte[] b = new byte[4];
    b[0] = 51;
    b[1] = -77;
    b[2] = 63;
    b[3] = 67;


    ByteBuffer buffer = ByteBuffer.wrap(b).order(ByteOrder.LITTLE_ENDIAN);

    int first = buffer.getInt();
    float second = buffer.getFloat(0);
    
    
    System.out.println("f="+first+" s="+second);

Prints

f=1128248115 s=191.7


Answered By - Andy