Asked
Resolved Resolved by Athena AI!

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 EZ-B v4

ARC Pro

Upgrade to ARC Pro

Take control of your robot's destiny by subscribing to Synthiam ARC Pro, and watch it evolve into a versatile and responsive machine.

PRO
Canada
#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.