Asked
Resolved Resolved by Athena!

Inconsistent UART Data Transfer Issue

Hello ,

I am experiencing inconsistent UART data transfer from the EZ-B v4 to an Arduino Mega 2560. Single-byte transfers are very consistent between these two devices, but when I attempt to transfer 8 bytes, the reliability decreases significantly. I have attached samples of JavaScript and C++ code that I am using. Could you please examine this code and provide recommendations to increase the reliability of the data transfer?

Thank you very much.

Jack

JavaScript Code:

UART.initHardwareUart(0, 9600, 0);
sleep(10);
var pathTotalDistance = getVar("$pathTotalDistance");
var pathEndpointDistance = getVar("$pathEndpointDistance");
var oppositeDistance = getVar("$oppositeDistance");
var actualCourse = getVar("$actualCourse");
var desiredCourse = getVar("$desiredCourse");

var highByte = (pathTotalDistance >> 8) & 0xFF;
var lowByte = pathTotalDistance & 0xFF;
UART.hardwareUartWrite(0, [highByte, lowByte]);
print("Sending pathTotalDistance high byte: " + (pathTotalDistance >> 8));
print("Sending pathTotalDistance low byte: " + (pathTotalDistance & 0xFF));
print("pathTotalDistance: " + pathTotalDistance);

var highByte = (pathEndpointDistance >> 8) & 0xFF;
var lowByte = pathEndpointDistance & 0xFF;
UART.hardwareUartWrite(0, [highByte, lowByte]);
print("Sending pathEndpointDistance high byte: " + (pathEndpointDistance >> 8));
print("Sending pathEndpointDistance low byte: " + (pathEndpointDistance & 0xFF));
print("pathEndpointDistance: " + pathEndpointDistance);

var highByte = (oppositeDistance >> 8) & 0xFF;
var lowByte = oppositeDistance & 0xFF;
UART.hardwareUartWrite(0, [highByte, lowByte]);
print("Sending oppositeDistance high byte: " + (oppositeDistance >> 8));
print("Sending oppositeDistance low byte: " + (oppositeDistance & 0xFF));
print("oppositeDistance: " + oppositeDistance);

UART.hardwareUartWrite(0, [actualCourse]); // Send as one byte
UART.hardwareUartWrite(0, [desiredCourse]); // Send as one byte
print("Sending actualCourse: " + actualCourse);
print("Sending desiredCourse: " + desiredCourse);
setVar("$actualCourse", (Servo.GetPosition(17)));

halt();

C++ Code:

long pathTotalDistance = 0;
long adjacentRemainingDistance = 0;
long pathEndpointDistance = 0;
float oppositeDistance = 0;
float desiredCourse;
long actualCourse;
float diffCourse = 0;
float lastDiff = 100;
int lastIncomingByte;
int run = 0;

void setup() {
    Serial3.begin(9600); // Communication with EZ-B
    Serial.begin(9600);  // Debugging via Serial Monitor
}

void loop() {
    if (run == 0) {  // State of RUN when the robot has yet to begin movement towards the reflector.
        if (Serial3.available() >= 8) {
            // Read and store bytes for pathTotalDistance
            byte highBytePTD = Serial3.read();
            byte lowBytePTD = Serial3.read();
            pathTotalDistance = (highBytePTD << 8) | lowBytePTD;

            // Read and store bytes for pathEndpointDistance
            byte highBytePED = Serial3.read();
            byte lowBytePED = Serial3.read();
            pathEndpointDistance = (highBytePED << 8) | lowBytePED;

            // Read and store bytes for oppositeDistance
            byte highByteOD = Serial3.read();
            byte lowByteOD = Serial3.read();
            oppositeDistance = (highByteOD << 8) | lowByteOD;

            actualCourse = Serial3.read(); // Read and store actualCourse
            desiredCourse = Serial3.read(); // Read and store desiredCourse

            // Print the above received parameters
            Serial.print("pathTotalDistance: ");
            Serial.println(pathTotalDistance);
            Serial.print("pathEndpointDistance: ");
            Serial.println(pathEndpointDistance);
            Serial.print("oppositeDistance: ");
            Serial.println(oppositeDistance);
            Serial.print("actualCourse: ");
            Serial.println(actualCourse);
            Serial.print("desiredCourse: ");
            Serial.println(desiredCourse);
            delay(10);
            // run = 1;
        }
    }
}

I look forward to your insights on improving the reliability of this data transfer process.



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.
Arduinocoms by ShadowStudios
EZB v4-Arduino I2C bridge for ARC: supports custom C# code and reads gamepad or Wii controller inputs for robot control

ARC Pro

Upgrade to ARC Pro

Your robot can be more than a simple automated machine with the power of ARC Pro!

Author Avatar
PRO
Canada
Twitter YouTube GitHub
#9  

Hello Jack,Great question!You're correct in noting that flushing the buffer before checking for available bytes could inadvertently remove data you want to read. Let's clarify how to use buffer flushing effectively.

Understanding Buffer Flushing:

  • Buffer Flushing: This process removes all data currently in the buffer. It's useful for clearing out unwanted or corrupted data before starting a new read cycle.
  • When to Use: You should flush the buffer when you know the data in it is not useful or when you're resetting the communication state.

Correct Usage in Your Context:

  • Avoid Flushing Before Reading: If you flush the buffer right before checking for available bytes, you risk removing the data you intend to read.
  • Flush Only When Necessary: Use flushing when you detect an error or when you want to reset the communication state, not in every loop iteration.

Example of Proper Buffer Flushing:

Here's how you might incorporate buffer flushing only when necessary:

void loop() {
    if (run == 0) {
        // Check if there are at least 9 bytes available (1 header + 8 data bytes)
        if (Serial3.available() >= 9) {
            byte header = Serial3.read();
            if (header == 0xAA) { // Check for header byte
                // Read the rest of the data
                byte highBytePTD = Serial3.read();
                byte lowBytePTD = Serial3.read();
                pathTotalDistance = (highBytePTD << 8) | lowBytePTD;
                // Continue with the rest of the data
            } else {
                // If the header is incorrect, flush the buffer to reset
                flushBuffer();
            }
        }
    }
}

void flushBuffer() {
    while (Serial3.available()) {
        Serial3.read(); // Discard any unwanted data
    }
}

Key Points:

  • Flush on Error: Only flush the buffer when you detect an error, such as an incorrect header.
  • Avoid Unnecessary Flushing: Do not flush the buffer in every loop iteration, as this will remove data you want to read.

By using buffer flushing judiciously, you can maintain the integrity of your data while still managing errors effectively. If you have more questions or need further clarification, feel free to ask!


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.