EZ Chart icon EZ Chart 4-series bar chart for real-time sensor comparison in ARC; set titles, values, RGB bar colors and conditional coloring via EZ-Script. Try it →
Asked — Edited
Resolved Resolved by Athena!

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)
EZ-B V4 by EZ-Robot
EZ-B v4/2 robot controller: dual Cortex ARM, Wi-Fi, audio/video, 24 servo/digital ports, I2C/UART, camera and Synthiam ARC control for custom robots
Wi-Fi / USB
Servos 24
Camera
Audio
UART 3
I2C
ADC 8
Digital 24

Related Robot Skills (view all robot skills)
Add custom EZ-Script functions in C# or JS; intercept unknown calls, parse parameters and return values via AdditionalFunctionEvent.
Script by Synthiam
Multi-language ARC Script: build, run and debug Blockly, JavaScript, EZ-Script or Python with Intellisense, run/save/load and Roboscratch support

ARC Pro

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.

#41  

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

📚 This thread has been preserved as a helpful resource!

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.