Asked

Hello @Athena,
I would like some assistance with sending a floating-point value via UART from an EZ-B v4 using JavaScript to an Arduino Mega using C++. Here's a snippet of my current code:
EZ-B v4 JavaScript Code:
UART.initHardwareUart(0, 9600);
var actualCourse = 91.55;
// Need an appropriate method to send the floating-point value correctly
UART.hardwareUartWrite(0, [actualCourse]);
Arduino Mega C++ Code:
float actualCourse;
void setup() {
resetAll();
Serial3.begin(9600); // Communication with EZ-B
Serial.begin(9600); // Debugging via Serial Monitor
}
void loop() {
if (Serial3.available() >= 1) {
byte incomingByte = Serial3.read();
delay(100);
if (incomingByte == 'A') { // Confirm header byte
Serial.print("incomingByte: ");
Serial.println('A');
actualCourse = Serial3.read(); // This approach doesn't handle float correctly
Serial.print("actualCourse: ");
Serial.println(actualCourse);
}
}
}
My objective is to transmit the entire floating-point value of "actualCourse" (91.55) via UART without any loss of precision or rounding issues. Could you please advise on how to achieve accurate floating-point transmission between the EZ-B and Arduino?
Thank you,
Jack
Related Hardware Roli Rover
Related Control
Serial Toolbox
Below is an explanation and a couple of approaches to send a full precision float (e.g. 91.55) from an EZ-B using ARC scripting (JavaScript) to an Arduino without losing the value.
Problem
Right now, the EZ-B code uses:
UART.hardwareUartWrite(0, [actualCourse]);
This sends an array with one element (the JavaScript number) that isn’t automatically broken down into its full 4-byte IEEE 754 float representation. On the Arduino side, your code is reading only one byte, so it isn’t capturing the whole value.
Two Common Solutions
In this approach you convert the float into a string and send that. On the Arduino, you can use functions like Serial.parseFloat() or Serial.readStringUntil() to convert back to a float.
EZ-B JavaScript Example:
js var actualCourse = 91.55; // Optionally send a header character to help with framing, e.g., 'A' UART.hardwareUartWrite(0, "A" + actualCourse.toString() + "\n");
Arduino C++ Example:
cpp float actualCourse; void setup(){ Serial3.begin(9600); // Communication with EZ-B Serial.begin(9600); // Debugging via Serial Monitor } void loop(){ // Wait until a full line is received if (Serial3.available()){ String data = Serial3.readStringUntil('\n'); // Read until newline // Optionally check for header 'A' int idx = data.indexOf('A'); if(idx != -1){ String numStr = data.substring(idx+1); actualCourse = numStr.toFloat(); Serial.print("actualCourse: "); Serial.println(actualCourse); } } }
Pros: Simpler debugging (you see the ASCII data), no worry about platform-specific binary formats.
Cons: More overhead in terms of bytes sent and a bit slower parsing.
Convert the float into its binary representation (4 bytes) on the EZ-B, then on the Arduino read all 4 bytes into a float variable using a union or memcpy.
EZ-B JavaScript Example:
js // Convert a float to 4 bytes using typed arrays var actualCourse = 91.55; var buffer = new ArrayBuffer(4); var floatView = new Float32Array(buffer); floatView[0] = actualCourse; var byteView = new Uint8Array(buffer); // Optionally send a header byte for framing (for example 65 which is 'A') var header = [65]; // Convert the typed array to a regular array of numbers var dataBytes = Array.from(byteView); UART.hardwareUartWrite(0, header.concat(dataBytes));
Arduino C++ Example:
cpp float actualCourse; union { byte b[4]; float f; } dataUnion; void setup(){ Serial3.begin(9600); // EZ-B communication Serial.begin(9600); // Debugging } void loop(){ // Wait until at least 5 bytes (1 header + 4 data bytes) are available if (Serial3.available() >= 5) { if (Serial3.read() == 'A') { // Check for header byte // Read the next 4 bytes into the union for (int i = 0; i < 4; i++) { while (Serial3.available() == 0) ; // Wait for byte dataUnion.b[i] = Serial3.read(); } actualCourse = dataUnion.f; Serial.print("actualCourse: "); Serial.println(actualCourse); } } }
Pros: Sends the data in a compact 4-byte form without conversion overhead.
Cons: Requires careful attention to endianness (most EZ-B systems and Arduinos use little-endian) and framing to ensure you’re reading the correct bytes.
Recommendation
If precision and speed are critical (and you can guarantee the same binary format on both sides), then using the binary approach is best.
If you prefer simplicity and easier debugging (at the expense of a few extra bytes and parsing overhead), the string method is a good approach.
Follow-up
Let me know if you need help with:
Feel free to ask for further assistance or additional examples.
I am a customer support GPT-powered AI and still learning. If you have doubts about my response, please use the support documentation to verify my answer.
Hello @Athena, Can you please send the "Binary Approach"(2nd option) in a form that I can cut and paste for the JavaScript and C++? Thank you so much. Jack
Below are the complete cutandpaste code examples for the binary approach. The JavaScript code converts the float into four bytes (using a TypedArray) with a header byte, and the Arduino C++ code reads the header and then the four bytes into a union to reassemble the float.
EZ-B JavaScript Code
Arduino C++ Code
Explanation
JavaScript Side:
Float32Array
view to store our float.Uint8Array
view allows us to extract the individual bytes.Arduino Side:
Serial3
.Feel free to ask if you need any further adjustments or additional help with framing or debugging!
I am a customer support GPT-powered AI and still learning. If you have doubts about my response, please use the support documentation to verify my answer.
@athena, is it easier to send the value multiplied by 100 or 1000 into an int32 and then reverse the multiplication on the Arduino side? This is because the float may not be interpreted the same on Arduino as the float from Arc's JavaScript.
ARC uses Jint. Jint focuses on being spec-compliant with ECMAScript 5.1 and selectively implements ES6+ features-but binary data buffers like ArrayBuffer and TypedArray are not supported by default.
Below is one effective workaround-multiplying your float by 100 (or 1000) to convert it into a 32bit integer and then sending that integer’s bytes. On the Arduino side you simply reverse the scaling to recover your original value. This approach can be easier when working with ARC’s JavaScript engine (Jint), which may not support binary data buffers (ArrayBuffer/TypedArray) by default.
Below are complete cutandpaste examples.
EZB JavaScript Code
In this example, we multiply the float by 100, convert it into an integer, and then split that integer into 4 bytes using bitwise operators:
Arduino C++ Code
The Arduino code waits until it receives at least 5 bytes (1 header + 4 data bytes), then reconstructs the integer and reverses the scaling to obtain the original float:
Explanation
On the EZB Side (JavaScript):
The float value is multiplied by 100 and rounded to form an integer (e.g. 91.55 becomes 9155).
The integer is split into 4 bytes using bitwise shifts and masks.
A header byte (here, 65) is prepended for framing purposes so the Arduino knows where the data begins.
The byte array is sent over UART.
On the Arduino Side (C++):
The code waits until 5 bytes are available.
It checks the header byte, then reads the next 4 bytes.
The 4 bytes are reassembled into an int32_t using bit shifting.
Finally, the integer is divided by 100.0 to recover the original float value.
This method sidesteps the need for ArrayBuffer/TypedArray support and ensures that both sides interpret the scaled number consistently.
Feel free to ask if you need further adjustments or additional help!
I am a customer support GPT-powered AI and still learning. If you have doubts about my response, please use the support documentation to verify my answer.
Rewrite that but don’t use a for loop in the arduino read section so it’s easier for robojack to understand the code. Rebuild the int32 inline
Hello @Athena, Thank you for your help. Could you please rewrite the code using the recommendation from DJ in the previous post? Thanks. Jack
Below is an updated solution that avoids the use of a for loop. The JavaScript side multiplies the float by 100, splits the scaled integer into four bytes, and sends a header plus the bytes. On the Arduino side, each byte is read individually and then reassembled inline into an int32_t without a loop.
EZ-B JavaScript Code
Arduino C++ Code
Explanation
EZ-B JavaScript:
Arduino C++:
Feel free to ask if you have any additional questions or need further clarification!
I am a customer support GPT-powered AI and still learning. If you have doubts about my response, please use the support documentation to verify my answer.