Send two floats over uart in one message

Hi, I want to send Joystick value as two floats over uart with values from -1000 to 1000 as binary 8 bytes for motor device, but I am having trouble sending negatif number and more than 255.. I am new to programming in general, and here is my current code.

#include <SoftwareSerial.h>
#define MOSI 11   // arduino nano
#define MISO 12
#define TX MOSI
#define RX MISO
SoftwareSerial out(RX, TX); 

int potX = 512;  
int potY = 512; 
int valX, valY;      // value data
int spL = 0;   // Speed Left
int spR = 0;   // Speed Right


float spd[2];  //  speed data array

void setup() {
  out.begin(115200);
  Serial.begin(115200);
  
}

void loop() {
  int potX = analogRead(A0);   // Read pot X Horz
  int potY = analogRead(A1);   // Read pot Y Vert

  valX = map(potX, 0, 1023, -200, 200);   
  valY = map(potY, 0, 1023, -800, 800);   

  if (valX >= -30 && valX <= 30)
  {    valX = 0;  }
  if (valY >= -30 && valY <= 30)
  {    valY = 0;  }

  if (valY < 0) {
    spL = valY - valX;
    spR = valY + valX;
  }

  else {
    spL = valY + valX;
    spR = valY - valX;
  }

spd[0] = spL;
spd[1] = spR;


  Serial.print("  _valX _valY, _spL, _spR,.  ");
  Serial.print(valX);    Serial.print(" .. ");
  Serial.print(valY);    Serial.print(" .. ");
  Serial.print(spL);     Serial.print(" .. ");
  Serial.print(spR);     Serial.print(" .. ");
  Serial.print(spd[0]);
  Serial.print(" .. ");
  Serial.println(spd[1], BIN);


//  out.write(spd, BIN);
  out.write((byte *)&spd, sizeof(spd));

 
}

Please help me, how can i modify the above code so that i can send negative/positive float numbers as binary 8 bytes. Thanks in advance!

The eight bit type "char" is a signed type.
Range -128 to +127

Why are you using out.write(spd, BIN);

Wouldn't it be much simpler just to do

out.print(valX);
out.print(',');
out.print(valY);

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data.

...R

CtrlAltElite:
The eight bit type "char" is a signed type.
Range -128 to +127

Thanks for infos,.

Robin2:
Why are you using out.write(spd, BIN);

Wouldn't it be much simpler just to do

out.print(valX);

out.print(',');
out.print(valY);

I merge two float in spd, I think if i can read the value of the merge properly. my device motor has one input uart (RX, TX) to control two motors. it is requires two floats with values from -1000 to 1000 as Binary 8 bytes.

How i can send spL and spR data in one message as Binary 8 bytes?.
Sorry if i doing wrong or misunderstanding.
Thanks.

tirta:
it is requires two floats with values from -1000 to 1000 as Binary 8 bytes.

What is receiving the data?

An Arduino floating point variable is 4 bytes. And floating point values may be represented differently on other computers.

The advantage of sending a value as text is that the receiving program can convert it to its own format.

...R

Robin2:
What is receiving the data?

An Arduino floating point variable is 4 bytes. And floating point values may be represented differently on other computers.

The advantage of sending a value as text is that the receiving program can convert it to its own format.

...R

The mainboard motor base on stm32, and it is sends out the ASCII-encoded set value via UART TX, also with 115200 baud. How to send a value as text, Can you refer for example code for this, spL and spR. Thanks.

int potX = analogRead(A0); // Read pot X Horz
int potY = analogRead(A1); // Read pot Y Vert

valX = map(potX, 0, 1023, -200, 200);
valY = map(potY, 0, 1023, -800, 800);

Assume: valX = 157 and valY = -689

I can now help you by offering the IEEE-754/binary32 formatted bit patterns (in Hex Format) for the decimal values of valX and valY. It will remain on you about what to do with these bit patterns. (You can strip it into four separate bytes and send them to a remote computer as 4x8-bit binary value chunk.)

float valueX = (float)valX;    //valueX = 157.00 ==> 0x431D0000
//----------------------------------------------------------------------------
long *p1;
p1 = (long*) &x;
long m1 = *p1;
Serial.print(m1, HEX);    //prints: 431D0000
//----------------------------------------------------------------------------

Similarly:
float valueY = (float)valY; //valueY = -689.00 ==> 0xC42C4000

I can now help you by offering the IEEE-754/binary32 formatted bit patterns

That's all just padding - fluff.
At worst, it's an obfuscation.

It's four bytes of binary data.
The only important thing is that the endianess of the source and destination match.
The internal representation is irrelevant.

At worst, it's an obfuscation.

When we say binary data, it implies base 2.

The 32-bit data of IEEE-754 standard can not be interpreted using base 2 considering the whole data as a chunk. It is composed of 3 sections (sign, exponent, fraction); the Real Value is extracted using a specific formula.

If 431D0000 is seen as natural binary data, it will turn to: 1125974016

If 431D0000 is seen as IEEE-754 standard bit pattern, it will turn to = 157.00

We're not talking about the representation here, we're talking about the transmission and reception of data.
It doesn't matter if the data is IEEE754, sign-and-magnitude, two's complement, fixed point ... as long as both sides agree the format and the order of the data.

tirta:
The mainboard motor base on stm32,

To get useful help you need to post a link to the datasheet for that device. Without the facts it is impossible to help you.

Can you refer for example code for this, spL and spR. Thanks.

See Reply #2

...R

GolamMostafa:
Assume: valX = 157 and valY = -689

I can now help you by offering the IEEE-754/binary32 formatted bit patterns (in Hex Format) for the decimal values of valX and valY. It will remain on you about what to do with these bit patterns. (You can strip it into four separate bytes and send them to a remote computer as 4x8-bit binary value chunk.)

float valueX = (float)valX;    //valueX = 157.00 ==> 0x431D0000

//----------------------------------------------------------------------------
long p1;
p1 = (long
) &x;
long m1 = *p1;
Serial.print(m1, HEX);    //prints: 431D0000
//----------------------------------------------------------------------------

Similarly:
float valueY = (float)valY; //valueY = -689.00 ==> 0xC42C4000

So by sending twice 4 bytes of data valueX and valueY, it is will be 8 bytes?

Robin2:
To get useful help you need to post a link to the datasheet for that device. Without the facts it is impossible to help you.

The mainboard use STM32F103 RCT6 microcontroller, it's like a ESC/ebike controller.

So by sending twice 4 bytes of data valueX and valueY, it is will be 8 bytes?

Your arithmetic is impeccable

tirta:

To get useful help you need to post a link to the datasheet for that device. Without the facts it is impossible to help you.

The mainboard use STM32F103 RCT6 microcontroller, it's like a ESC/ebike controller.

That does not help.

If the Ebike controller is designed to take control messages it will have documentation that describes the exact format of those messages.

Without that information we are all as blind as if we were trying to guess chemical composition of a distant star.

...R

Robin2:
Without that information we are all as blind as if we were trying to guess chemical composition of a distant star.

Actually, that would be a lot simpler, because we have spectrometers. :smiley:

Robin2:
If the Ebike controller is designed to take control messages it will have documentation that describes the exact format of those messages.

Without that information we are all as blind as if we were trying to guess chemical composition of a distant star.

...R

Sorry, I misunderstood. i tried opensource project ie, hoverboard hack by Niklas, it is writes new firmware to the mainboard hoverboard (motor controller). The original Hardware supports two 4-pin cables were connected to the two sensor boards via USART2 & 3.

In Master branch (my choice), uses UART DMA to receive two floats on USART2 (PA2/PA3, Tx/Rx) with 115200 baud, and uses these floats to control the motor current of each motor. It also counts the hall ticks and sends back the motor positions to use them for odometry data, for example combined with ROS.

I asked to the project owner, and he said,

In the master branch, with this you can simply send UART commands to the mainboard eg. using an arduino. Baudrate is 115200. Simply send two floats with values from -1000 to 1000 as binary 8 bytes to the mainboard with ~20-100Hz. and the mainboards sends out the ASCII-encoded set value via UART Tx, also with 115200 baud.

Mainboard image

Project link: GitHub - lucysrausch/Hoverboard-Board-Hack: Deprecated. Please use https://github.com/NiklasFauth/hoverboard-firmware-hack instead!

Thanks.

tirta:
I asked to the project owner, and he said,

In the master branch, with this you can simply send UART commands to the mainboard eg. using an arduino. Baudrate is 115200. Simply send two floats with values from -1000 to 1000 as binary 8 bytes to the mainboard with ~20-100Hz. and the mainboards sends out the ASCII-encoded set value via UART Tx, also with 115200 baud.

To my mind that is very inadequate information. However Open-Source programmers are not noted for the quality of their documentation.

Try creating an array with two float values and sending that with Serial.write(). Something like this

float myFloatArray[2];

myFloatArray[0] = -175.6;
myFloatArray[1] = 763.76;
Serial.write(&myFloatArray, sizeof(myFloatArray);

If it compiles but does not work I don't have the faintest idea how you you could figure out what is wrong.

...R