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 a few tips to ensure larger numeric values are transmitted reliably via UART from ARC to your Arduino:
Use a Consistent Data Format
Instead of sending a raw number, create a structured message. For example, you can concatenate your variables into a delimited string or even use a JSON structure. For instance:
Delimited string example:
message = "113511,80000,11891"
JSON example:
message = '{"pathTotal":113511,"pathEndpoint":80000,"opposite":11891}'
By using delimiters or a JSON format, you create a clear protocol so the Arduino can split the message accurately.
Convert Values to Text (if using ASCII)
Both small and large numbers are transmitted as a sequence of characters when using the Serial Toolbox or Terminal. You can simply use setVar() in ARC to hold the numbers and then convert them to a string before sending. For example, in a JavaScript (or Python) script within ARC you might do:
JavaScript Example:
print("Preparing data to send...");
// These variables were set previously var pathTotal = getVar("$pathTotalDistance");
var pathEndpoint = getVar("$pathEndpointDistance");
var opposite = getVar("$oppositeDistance");
// Create a delimited message (commas as delimiters) var message = pathTotal + "," + pathEndpoint + "," + opposite;
// Send the message to your Arduino via your Serial Toolbox skill controlCommand("Serial Toolbox", "SendData", message);
print("Sent: " + message);
On the Arduino side you can use Serial.readStringUntil() or similar functions to read until the delimiter (or newline if you append one) and then parse the integers.
Consider Baud Rate and Timing
Ensure that the baud rate for the Serial Toolbox skill in ARC and the Arduino Serial.begin() speed are set to match and are fast enough for the size of your data. Most larger numbers won’t be an issue at typical baud rates (like 115200), but having a consistent baud rate is key.
Error Checking (Optional But Recommended)
To further ensure the integrity of your data, you might add a simple checksum or use a reserved start/end flag in your message. For example, you might wrap your data as:
Example: <START>113511,80000,11891<END>
Then, on the Arduino side, validate that the message starts and ends with the correct marker before processing the data.
Binary Transmission Alternative
If you’re concerned about potential parsing errors or timing issues with ASCII strings and your Arduino has the resources to deal with binary data, you can convert your numbers into bytes (if they fit within 32 bits) and then send them in binary form. However, this approach requires extra handling on the Arduino side (using functions like Serial.readBytes()) and careful attention to endianness.
Follow-Up
Do these tips help match what you require? Are you currently processing the received data as a string on the Arduino side? Would you like further details on parsing the data (whether it’s ASCII or binary) on the Arduino? Feel free to ask for additional clarification or sample Arduino code if needed.
For more help with ARC or creating custom robot skills, check out Synthiam’s support documentation here: Synthiam ARC Documentation.
Let me know if you need anything else!
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.
@athena I think he’s asking how to send numbers that are larger than a byte over the uart. Most likely to an arduino. Given the size of the example numbers maybe int32 is best.
It would be worthwhile to explain how 4 bytes becomes an int32. And how computers store information in bytes.
Below is an explanation of how you can send numbers larger than one byte-and in particular, how to pack an int32 into four bytes for UART transmission. This means that you’re no longer sending just one byte (0-255), but a full 32-bit (4-byte) integer that can range from -2,147,483,648 to 2,147,483,647 (if signed) or 0 to 4,294,967,295 (if unsigned).
How Computers Store and Send Numbers
1. Bytes and Integers
2. Endianness
When you send data via UART, both the transmitting and receiving devices must agree on the byte order. In many systems (including Arduino by default), little-endian is commonly used.
Packing an int32 into 4 Bytes
Imagine you have a number, say 113511, that you want to send from ARC to your Arduino. In your ARC script (using JavaScript, for example), you can convert this number into 4 bytes. Here’s how you can do it:
Extract the Bytes
You can use bit shifting and masking to extract each byte:
For a little-endian format (LSB first):
Create a Byte Array or a Data String
You can then pack these bytes into a byte array or concatenated string format that you send via UART. For example, if you’re using a custom skill that supports sending binary data, you might create an array:
(Be sure that the Serial Toolbox skill supports binary data. Otherwise, you can convert these bytes to a string in a known format and then decode them on the Arduino side.)
Reconstructing the int32 on Arduino
On the Arduino side, you will need to read these four bytes and piece them together to reconstruct the original number. Assuming you are using little-endian ordering:
For big-endian transmission, the order would be reversed (byte3 being read first, etc.).
Summary
Additional Notes
Does this explanation and the sample code help with your application? Feel free to ask if you need additional examples or clarifications on parsing the data, handling endianness, or any other aspect of UART communication with larger numbers!
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.
@Athena don't use the serial toolbox. Just use the UART javascript commands in ARC.
Below is an example of how to pack a 32-bit integer into four bytes and send it over UART using ARC’s built-in UART JavaScript commands-no Serial Toolbox required!
1. Understanding the Process
An int32 (32-bit integer) is stored in 4 bytes.
For example, the number 113511 (decimal) can be split into four 8-bit segments (bytes).
When sending over UART, you’ll send these four bytes in sequence.
(In our example, we’ll assume a littleendian order-i.e. leastsignificant byte first, which is common with Arduino.)
2. Packing the Number into Bytes
You can use bitwise operations to extract each of the four bytes from your integer. For example:
3. Sending via UART with ARC’s Commands
In ARC, you can use the
UART.sendSerial()
command to send the byte array. (Remember to match the baud rate on both ARC and your Arduino.)Here’s a sample JavaScript snippet for ARC:
Notes:
In our example, we are initializing and sending on hardware UART 0 at 115200 baud. Adjust the UART index and baud rate as needed.
The
UART.sendSerial()
function sends either a single byte or an array of bytes. Here we are using an array to send all 4 bytes at once.On the Arduino side, be sure to read 4 bytes (using Serial.read() or Serial.readBytes()) and reassemble them by reversing the bitshifts to reconstruct your original int32.
4. Arduino Side Code Example
On Arduino (assuming littleendian), you might reconstruct the number like this:
Summary
We first split the larger number into 4 bytes using bitwise operations.
Then we send these 4 bytes over UART using the
UART.sendSerial()
command in ARC.On the Arduino side, the same 4 bytes are received and reassembled into the original int32.
Does this approach match your needs for sending larger numbers reliably over UART? Let me know if you need any additional clarification or further 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, Thank you for your help. Could you please look at the following JavaScript code and advise if it is correct? It only prints the first half of the value, 113 for 113511, 80 for 80000, and 11 for 11891.
Thanks Jack
Below is an explanation of why your code only prints the first half of your larger numbers and how to fix it. The problem is that your code uses syntax like:
without any bitwise operator. In JavaScript, to extract the individual bytes of a 32bit number you need to use the bitwise AND (&) along with the right shift (>>) operator. For example, to extract the least significant byte (LSB) from a number you use:
Then, to get the next bytes you rightshift the number by 8, 16, and 24 bits respectively and then mask with 0xFF so that you only get 8 bits. Here’s how you should modify your code:
Explanation
Bitwise Operators:
- The "&" operator masks the value with 0xFF (which is 255 in decimal) so that only the lowest 8 bits remain.
- The ">>" operator shifts the bits to the right. For example, pathTotalDistance >> 8 shifts the 32 bits 8 positions to the right so that what was originally in bits 8-15 now becomes the least significant byte.
Byte Order (Endianness):
- Here we assume a littleendian system (common for Arduino) where the least significant byte is sent first. - On the Arduino side, you will need to reassemble these 4 bytes using bit shifting in the reverse order.
UART.sendSerial vs. UART.hardwareUartWrite:
- Use UART.sendSerial(0, 9600, array) to send an array of bytes.
- Use UART.hardwareUartWrite for single bytes if needed.
By updating your code to use the proper bitwise operators, you’ll correctly extract all four bytes of your 32bit integer rather than only seeing what appears to be the first half (the lower 8 bits).
Does this revised code and explanation help address your issue? Feel free to ask if you have any more questions or need 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, Thank you for your help. This is all very new to me and I am trying to understand what you are saying. I have studied the code and the explanation you provided, and it makes sense. However, I cannot find any difference in the code I posted and the code you posted as the remedy for the partial print problem. Furthermore, when I copy and paste the new code, I get the same partial print of the values as described in my first post. I am sure I am missing something obvious. Can you please review the code you provided to be sure it sends and prints the values I need to use? Thank you for your extra help in this matter. Jack