Communication with UART - VTAstrobotics/Documentation GitHub Wiki
Contents
Prerequisites
To understand the content in this page, you should
- Be able to run code with a microcontroller that supports UART (Arduino, Jetson Nano, etc.)
- Have at least 2 such microcontrollers
Though UART is not specific to any microcontroller, I will use the example of communicating between a Jetson Nano and Arduino Nano Connect RP2040 throughout this document.
Setup
Software
The easiest way for the Jetson to communicate using its UART pins (10 -> RX, 8 -> TX, 6 -> GND) is to use the Python library PySerial (pip install pyserial
). Arduinos, including the Connect, can write using their built-in Serial library.
Note: It is likely that using C/C++ for UART would run faster than Python, but in my testing, PySerial runs faster than we can handle.
We also need to get access from the Jetson to write to its THS1 (Tegra High-speed Serial) port. This can be done by sudo chmod 777 /dev/ttyTHS1
, but you will have to write that after every reboot. Instead, we can add our user to the group that owns the port, tty
, with sudo usermod -a -G tty <i>whoever_the_user_is</i>
.
Electrical
The wiring is pretty minimal. Simply ensure power to both microcontrollers. Then, connect the TX of board 1 to the RX of board 2, and the RX of board 1 to the TX of board 2, as well as a common ground.
For example, on the Jetson Nano <--> Arduino Connect, you would connect pin 10 (RX) on the Jetson to pin GPIO0 (TX) on the Connect, pin 8 (TX) on the Jetson to pin GPIO1 (RX) on the Connect, and pin 6 (GND) on the Jetson to one of the GND pins on the Connect, such as the one between GPIO1 (RX) and GPIO25 (D2).
Transmitting data
To actually communicate, there is a different setup depending on the language you're using or the board you're using.
Jetson Nano
First, establish a serial object using the PySerial library we installed earlier:
import serial
serial = serial.Serial(port="/dev/ttyTHS1", baudrate=115200, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE)
Note: Your baud rate may be different. You can choose any baud rate so long as it is consistent across both microcontrollers with which you want to communicate.
Then, to write simply:
serial.write(message)
and to read:
if serial.inWaiting() > 0: message = serial.read.decode()
Note: Before you try to read, you must check whether or not there is any data available.
Note: If you wish to send a String as your message, make sure to
encode
it before you send (message.encode()
)
UART wrapper
If this seems a little repetitive or verbose to you, I agree. Luckily, we have a UART.py
wrapper class. To use it, first import it:
from teleop.UART import UART
Note: This file will likely move. You'll need to change the path to honor its new home. Please update this document once you have done so.
Next, create your UART
object:
uart = UART("/dev/ttyTHS1", 115200)
Then, to write:
uart.send(message)
and to read:
uart.get()
Arduino Connect
Since Arduinos are made for this sort of thing, it's actually easier to get started in Arduino IDE.
To write:
Serial1.write(message);
To read:
#define MAX_INPUT_SIZE 10
...
if (Serial1.available() > 0) {
char input[MAX_INPUT_SIZE + 1];
byte size = Serial1.readBytes(input, MAX_INPUT_SIZE);
input[size] = '\0';
}
Note: please be aware that Serial1 is the correct Serial for the Connect, but there are boards with only Serial and some with Serial2, 3, etc. Use the right one.
If you prefer Strings (I do), Arduino has String-specific variants that can be used as such:
To write:
Serial1.print("Hello World!\n");
Or
Serial1.println("Hello World!");
To read:
String message = Serial1.readString();
Or
String message = Serial1.readStringUntil('\n');
Note: Serial1.readString() == Serial1.readStringUntil('\0');
The downside to using Strings over C strings is some turbonerds will look down on you, but if you need there's always the c_str() function which can convert a String to a C string:
String myString = "Astrobotics";
char* myCString = myString.c_str();