UART Byte Array Communication Explained
Hi @Athena,
I'm asking about the best way to communicate via UART between an EZB4 (JavaScript running on the EZB) and an Arduino Mega (C++). I'm a beginner and want to keep the implementation simple but reliable. My understanding is that sending a String is not necessary and that sending an array of bytes would be a better approach. I'm using the EZB4 hardware UART functions (UART.hardwareUart*) on the EZB side and Serial3 on the Arduino Mega side.
To clarify the hardware/ARC context: the Arduino Mega is connected to the EZB4 UART (hardware UART lines). The EZB is handling the real-time hardware UART I/O, and this runs inside an ARC project where ARC scripts manage the higher-level logic. The EZB code is a single JavaScript script running on the EZB (built-in ARC/EZB scripting). The Arduino code is standard C++ running on the Mega. This is not using a separate robot skill for the serial link; the UART I/O is performed by the EZB firmware calls from the script.
I have included my C++ (Arduino) TX and RX code and my JavaScript (EZB4) TX/RX code below for your evaluation. Could you rewrite the code to reliably send data using an array-of-bytes format?
Notes:
- The Arduino C++ TX and RX must be separate sketches (not combined).
- The EZB4 code runs as a single JavaScript script on the EZB (using built-in ARC/EZB scripting).
- This is part of an ARC project where the EZB handles the real-time hardware UART and ARC scripts manage higher-level logic.
C++
Data TX
if (run == 1) {
bufferFlush();
totalStepsTaken = (abs(combinedStepsTaken));
delay(50);
int byte0 = totalStepsTaken & 0xFF;
int byte1 = (totalStepsTaken >> 8) & 0xFF;
int byte2 = (totalStepsTaken >> 16) & 0xFF;
int byte3 = (totalStepsTaken >> 24) & 0xFF;
Serial3.write('T'); //Header for Total Steps Taken
// Send the four bytes one by one.
Serial3.write(byte0);
Serial3.write(byte1);
Serial3.write(byte2);
Serial3.write(byte3);
Serial.print("Sent ");
Serial.println('T');
Serial.print("Left F+B Steps: ");
Serial.println(abs(LeftFrontWheel.currentPosition()) + abs(LeftBackWheel.currentPosition()));
Serial.print("Right F+B Steps: ");
Serial.println(abs(RightFrontWheel.currentPosition()) + abs(RightBackWheel.currentPosition()));
Serial.print("Sent combinedStepsTaken: ");
Serial.println(totalStepsTaken);
Serial.println(" ");
delay(100);
}
C++
Data RX
while ( run == 1) {
if (Serial3.available() >= 1 ) {
int incomingByte = Serial3.peek(); // do not remove it yet
// Check if this byte is our STOP command (assume 'x' is the stop command)
if ( incomingByte == 'm') {
Serial3.read();
miss = true;
actualCourse = desiredCourse;
}
if (incomingByte == 'x') {
// Consume the byte and stop motors
Serial3.read();
Serial.print("Received STOP command: ");
Serial.println('x');
stopMotors();
goto Main; // jump out to the Main section
}
if ( incomingByte == 'c') {
Serial3.read();
Serial.print( "(Received obs scan complete) command ");
Serial.println('c');
}
}
if (Serial3.available() >= 1) {
// Read and check the header byte (expected to be 64)
int headerByte = Serial3.read();
if (headerByte == 64) {
int32_t b0 = Serial3.read();
int32_t scaledValue = (b0);
actualCourse = scaledValue;
Serial.print(" ..............---------------------------- rec'd actualCourse: ");
Serial.println( actualCourse,4);
lastActualCourse = actualCourse;
initial = true;
miss = false;
loopct = 0;
}
}
if (miss == true ) {
Serial.print( " Received Missed command: ");
Serial.println('m');
actualCourse = lastActualCourse;
}
combinedStepsTaken = abs(LeftFrontWheel.currentPosition()) + abs(LeftBackWheel.currentPosition())
+ abs(RightFrontWheel.currentPosition()) + abs(RightBackWheel.currentPosition());
if (abs(combinedStepsTaken) > combinedStepsDesired) {
stopMotors();
goto Main;
}
loopct++;
}
JavaScript Data TX and RX (single script on the EZB)
var lastActualCourse = null;
setVar("$obsDet", 0);
setVar("$missedIR", 0);
setVar("$obsScanEnd", 0);
while(true) {
//Data RX
if (UART.hardwareUartAvailable(0) >= 5) { //5
var header = UART.hardwareUartReadString(0,1);
if (header == 'D'){
var desiredCourseScaled = UART.hardwareUartRead(0, 1);
setVar("$desiredCourse", desiredCourseScaled[0]);
print("rec'd desiredCourse: " + getVar("$desiredCourse")+ " cyc: " + getVar("$cycleCount"));
} else if (header == 'T') {
print("Header: " + header);
// read all 4 bytes from uart #0 that we need for this condition into the array tmpRead
var TSTRead = UART.hardwareUartRead(0, 4);
// tmpRead[3,2,1,0] are denoted as they were sent 0,1,2,3
var totalStepsTaken = (( TSTRead[3] << 24) | ( TSTRead[2] << 16) | ( TSTRead[1] << 8) | TSTRead[0]);
print("totalStepsTaken: " + totalStepsTaken);
print( "CYC: " + getVar("$cycleCount") + " $desiredCourse: " + getVar("$desiredCourse") + " $actualCourse: " + getVar("$actualCourse"));
sleep(100);
controlCommand("$IR_1", "PauseOff");
sleep( 10 );
controlCommand("IR_STEP", "ScriptStop");
sleep( 10 );
controlCommand("NRS_71.8_58_TEST", "ScriptStop");
sleep( 10 );
halt();
}
}
// Data TX
if (getVar("$obsDet") == 1) {
UART.hardwareUartWrite(0, ['x'.charCodeAt(0)]);
sleep(5);
print( "sent to ARDU...obsDet: " + getVar("$obsDet"));
print("OBS IR STOP: " + getVar("$IRADC"));
}
if ( getVar("$missedIR") == 1) {
UART.hardwareUartWrite(0, ['m'.charCodeAt(0)]);
print("sent to ARDU...missedIR: " + getVar("$missedIR"));
}
if ( getVar("$obsScanEnd") == 1 ) {
UART.hardwareUartWrite(0, ['c'.charCodeAt(0)]);
print("sent to ARDU...Scan for obs ended: " + getVar("$obsScanEnd"));
}
if(getVar("$actualCourse") != lastActualCourse) {
var scaledValue = getVar("$actualCourse");
//Send as whole number to Arduino:
var byte0 = scaledValue & 0xFF;
var header = [64];
// Combine the header with the 4 bytes and send via UART
UART.hardwareUartWrite(0, header.concat([byte0]));
lastActualCourse = getVar("$actualCourse");
print(" $actualCourse: " + getVar("$actualCourse"));
}
sleep(200);
}
Related Hardware (view all EZB hardware)
Related Robot Skills (view all robot skills)
Upgrade to ARC Pro
With ARC Pro, your robot is not just a machine; it's your creative partner in the journey of technological exploration.
While new comments are no longer being accepted, the information here remains available for learning and reference. Check the most recent comment for additional details.

Hi @Athena, I am very happy with the ARC and ARDUINO UART code that you provided. They communicate very well together and a big thanks to @DJ for the guidance he gave early on to steer this thread. I am working on putting my criteria together for the PWM and Desired Bearing portions of the Arduino sketch and will submit them in a few days on a new thread. Thanks for your wonderful assistance to robot imagineers! Jack