Asked
— Edited

Hello @Athena,
I am seeking guidance on how to effectively communicate larger variable values from Synthiam ARC to an Arduino via UART. Previously, I worked with smaller values using the following variable configurations:
setVar("$pathTotalDistance", 2450); // Set value in steps
setVar("$pathEndpointDistance", 1895); // Set value
setVar("$oppositeDistance", 12); // Set value
I am now required to handle larger values for these variables, as illustrated below:
setVar("$pathTotalDistance", 113511); // Set value in steps
setVar("$pathEndpointDistance", 80000); // Set value
setVar("$oppositeDistance", 11891); // Set value
Could you provide advice on how to efficiently send these larger numbers using UART communication to an Arduino? My primary concern is ensuring the integrity and accuracy of the data transmitted, given the increased size of the variables.
Thank you,
Jack
Related Hardware Roli Rover
Related Control
Serial Toolbox
Below is an annotated review of your JavaScript code. I’ve included some tips and corrections for common pitfalls to help ensure you’re sending the bytes as expected. Check out the points below:
Make sure you’re using the proper bitwise operators. For example, to extract four bytes from a 32bit value you should use:
var byte0 = pathTotalDistance & 0xFF;
var byte1 = (pathTotalDistance >> 8) & 0xFF;
var byte2 = (pathTotalDistance >> 16) & 0xFF;
var byte3 = (pathTotalDistance >> 24) & 0xFF;
In your code snippet, ensure that you have the & and >> operators in the correct positions. Sometimes a missing operator (or spacing issues) can lead to unexpected results.
You are reusing the same variable names (such as byte0-byte3) for each value (pathTotalDistance, pathEndpointDistance, and oppositeDistance). This isn’t necessarily an error in JavaScript because the variables are redeclared sequentially, but for clarity you might consider renaming or using separate blocks. For example:
// For pathTotalDistance
var PTD0 = pathTotalDistance & 0xFF;
var PTD1 = (pathTotalDistance >> 8) & 0xFF;
var PTD = [PTD0, PTD1, PTD2, PTD3];
You are mixing two methods to send data:
UART.hardwareUartWrite(0, header) for the header and later for the onebyte values (actualCourse and desiredCourse)
UART.sendSerial(0, 9600, array) for sending the fourbyte arrays.
This is acceptable as long as your Arduino code uses the same serial port (Serial3 in your sketch) and the baud rate is consistent. (Make sure your Arduino code reads from Serial3 if you’re using hardwareUartWrite and sendSerial on port 0.)
Your print statements sometimes add numbers directly. For instance:
print("oppositeDistance: " + oppositeDistance + oppositeDistance);
If you meant to print the label and value, you might want to add a separator (or simply print the variable once). For example:
print("oppositeDistance: " + oppositeDistance);
If your intention was to check the value twice, then consider something like:
print("oppositeDistance: " + oppositeDistance + " | " + oppositeDistance);
Your protocol sends:
- 1 header byte (0xAA)
- 4 bytes for pathTotalDistance
- 4 bytes for pathEndpointDistance
- 4 bytes for oppositeDistance
- 1 byte for actualCourse
- 1 byte for desiredCourse
That adds up to 15 bytes. Make sure your Arduino code is checking Serial3.available() for 15 or more bytes-even though some have asked why wait for 14 bytes, based on your protocol it is indeed 15, as DJ_Sures noted.
Below is a revised version of your JavaScript code that incorporates these points:
Ensure that the baud rate (9600 in this example) in your JavaScript code matches the baud rate used in your Arduino Serial3.begin(9600).
Verify that your Arduino is reading all 15 bytes from Serial3 and that the byte order matches (here we are assuming littleendian).
Test each piece separately (for instance, send just one packet) to confirm that both sides (Synthiam ARC and Arduino) are communicating correctly.
Conclusion
Your protocol and overall approach appear sound. Often the issues come down to missing bitwise operators or not consistently reading/sending from the correct UART port. Once you ensure that all data types, byte orders, and UART methods are used correctly on both sides, the Arduino should receive the proper 15byte packet.
Let me know if you have any further questions or need additional assistance. Happy coding!
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, SUCCESS! I followed your recommendations in breaking the problem into smaller bitscool and discovered that the single byte Values were being sent and received but the 4byte Values were not. Breaking those down further revealed that they were not sending at all. I started researching my options for UART commands and suspected that perhaps another type of UART command would send my 4byte arrays. I found by using the following code that I have very reliable transfer of large values from ARC to my Arduino.
I am unsure why and would love to put whatever I stumbled upon in my toolbox for future use. Can you explain why " UART Write" works and "UART Send" does not? Thank you for your continued help. Jack
Below is an explanation of why using hardwareUartWrite works for your multibyte arrays while sendSerial does not:
Direct vs. Formatted Transmission:
UART.hardwareUartWrite is designed to send raw byte data directly to the hardware UART buffer. It doesn’t modify or add any extra formatting to your data; you get exactly what you send. In contrast, UART.sendSerial is typically built for transmitting text data (strings) and may include additional framing or character conversion routines that aren’t ideal when you need to send a raw multibyte array. This extra processing or interpretation can interfere with the proper transmission of your integer values.
Low-Level Control:
Using hardwareUartWrite gives you low-level control over the data being sent. When handling large numbers split into 4 bytes, it’s critical that each byte is sent exactly as calculated. Because hardwareUartWrite bypasses any abstraction layers that might be present in UART.sendSerial, you avoid issues like buffer formatting or newline/termination character insertions that could be silently introduced by sendSerial.
Consistency with the Arduino Side:
Since on your Arduino you’re reading the incoming bytes in the exact order (header, then groups of 4 bytes, then the one-byte values), a direct and unaltered transmission is required. HardwareUartWrite fulfills that need while sendSerial is more geared toward scenarios like sending human-readable commands or text messages.
In summary, for precise and reliable transfer of raw binary data (your 4byte integer arrays), hardwareUartWrite is the recommended method because it directly writes the intended bytes to the UART interface without additional processing. This explains why you observed success with hardwareUartWrite and not with sendSerial.
Let me know if you need further clarification or additional assistance!
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, I need to send a large value (" totalStepsTaken" = 80001) from the Arduino to ARC. I have posted the code for the Arduino to send and ARC to receive via UART. Could you please assist me with help in coding this? Thank you. Jack
ARDUINO
ARC
Below is one way to handle sending a large integer value (like totalStepsTaken = 80001) from your Arduino to ARC over UART.
The overall idea is to break the 32bit long (4 bytes) into individual bytes and send them along with a header so that the ARC side knows when a complete packet arrives. In your Arduino code it’s best to use Serial3.write() (which sends raw bytes) rather than sending a string version.
Below are revised versions (with comments) for both the Arduino and ARC sides.
Arduino Code (Sender)
In your stopMotors() or similar routine, do this:
/* Arduino Sketch Snippet */
void stopMotors() { // (your motor stop code)
if (run == 1) { totalStepsTaken = 80001;
} resetAll(); }
void resetAll() { // Reset positions or variables as needed. LeftFrontWheel.setCurrentPosition(0); RightFrontWheel.setCurrentPosition(0); }
void bufferFlush() { // Flush outdated data from Serial3 buffer. while (Serial3.available()) { Serial3.read(); // Discard received data. delay(10); } }
Key points on the Arduino side:
We use bitwise AND (&) and right shifts (>>) to extract each byte.
The header character (here, T’) is sent first so that ARC knows when to expect the 4 subsequent bytes.
Each byte is written separately with Serial3.write().
ARC Code (Receiver)
On the ARC side, you need to wait until at least 5 bytes are available, then read the header and the four subsequent bytes and reconstruct the original long value.
Below is an updated ARC JavaScript code snippet:
/* ARC (JavaScript) Snippet */
// Ensure at least 5 bytes are available (header + 4 bytes) if (UART.hardwareUartAvailable(0) >= 5) {
// Read one byte as header. var header = UART.hardwareUartReadString(0, 1);
if (header == "T") { // Check if header matches // Read the next 4 bytes. // It is good practice to convert these string-returned bytes to numbers. var b0 = parseInt(UART.hardwareUartReadString(0, 1)); var b1 = parseInt(UART.hardwareUartReadString(0, 1)); var b2 = parseInt(UART.hardwareUartReadString(0, 1)); var b3 = parseInt(UART.hardwareUartReadString(0, 1));
} }
Key points on the ARC side:
We check that at least 5 bytes are available - this covers our header plus 4 bytes of data.
The header is verified to be "T" before processing the next 4 bytes.
Each byte is read (using UART.hardwareUartReadString with a length of 1) then parsed to an integer using parseInt().
Bitwise shift operators (<< and |) combine the bytes back into a long value.
Ensure that your ARC project uses the same UART port (port 0 in this case) and that baud rates match the Arduino side.
Explanation
On the Arduino side, Serial3.write() sends raw binary data exactly as given.
On ARC, UART.hardwareUartReadString(0, 1) returns a 1character string representing the byte which we then convert to a number.
Using hardwareUartWrite for large values is preferable because it doesn’t interfere with the raw binary data; using a textbased function (such as UART.sendSerial) might add formatting characters or not handle binary data properly.
By using these revised code examples and explanations, you should have reliable transfer of your 32bit large value (totalStepsTaken = 80001) from Arduino to ARC via UART.
If you have further questions or need additional modifications, feel free to ask!
Happy coding!
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,
I consistently receive a value for totalStepsTaken = 2048 in ARC. I can send any number from the Arduino as totalStepsTaken. Arduino prints the value correctly, but ARC only prints 2048. Could you please review my code for errors? Thank you. Jack
ARDUINO
ARC
Below is a detailed review of your code with some corrections and explanations to help you get the correct value for totalStepsTaken. In your case, ARC always shows 2048 because of a few small issues in the ARC script (and possibly your header usage).
Below are the main points to check and correct:
On the Arduino side, you send the header byte using:
Serial3.write(T);
Make sure that T is defined or use a literal (for example, 'T' or "T").
In the ARC code you compare the header like this:
if(header == T)
If T is not defined in ARC you will not match properly. It’s best to define it or compare against a literal string as follows:
if(header == "T")
Your code uses:
if(UART.hardwareUartAvailable(0)= 5){
Here, you are using the assignment operator (=) rather than a comparison. Also, you want to check that there are at least 5 bytes available (1 header + 4 data bytes). Replace it with:
if(UART.hardwareUartAvailable(0) >= 5){
This ensures the code only runs when enough bytes are available.
In your ARC code, you reconstruct the long value with an expression that appears as:
totalStepsTaken = ((b3 24)|(b2 16)|(b1 8)| b0);
Here, the bit shifting operators (<<) are missing. The correct operation should be:
totalStepsTaken = ((b3 << 24) | (b2 << 16) | (b1 << 8) | b0);
This takes each byte and shifts it appropriately (assuming the Arduino is sending the LSB first, as your Arduino code does).
Below are the revised versions for both Arduino and ARC.
Arduino Code (Sender):
Make sure your Arduino sends the header (using a literal value) and the bytes:
ARC Code (Receiver - JavaScript)
Ensure you wait for at least 5 bytes, compare against the literal header ("T"), and use proper bit-shift operators:
By comparing the header correctly (using "T"), we ensure that the packet is identified on ARC.
Checking that UART.hardwareUartAvailable(0) is at least 5 avoids trying to read data before it’s available.
The use of << in the bit reconstruction is critical to forming the correct integer value.
With these corrections, ARC should correctly reconstruct the value sent from the Arduino (80001 in your test case) rather than the incorrect 2048 value.
I hope these changes help solve the issue. Let me know if you need any more assistance or further clarifications!
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, Thank you for reexamining my code. I still had the incorrect read in ARC. I found the affected code and included it below: I changed UART.hardwareUartReadString to UART.hardwareUartRead for reading b0-b3. It works perfectly now. Can you please tell me why JavaScript prefers this? Thank you. Jack
ARC: