Hello.
I have a project where I use a TX2 board with a high speed camera and a GPS module. I need to get the NMEA data from the GPS to the module, and for that I’m using UART. In between the GPS and the Jetson I use an arduino, the reason for this is because we were afraid the GPS could damage the Jetson board as its J21 pins can only handle 1.8V (or so what it would see).
My problem is that the Jetson doesnt recive all data (or is unable to handle it) correctly. But what it receives is at least correct. The issue is not with the arduino, as the serial monitor shows correct (and processed) NMEA.
I have tried both with minicom and GtkTerm, and written code in C. (I think raspberry pi example).
Thanks in advance.
Insight:
System drawing: https://i.imgur.com/OLvckdr.png
GtkTerm settings: https://i.imgur.com/jC5KvLE.png
NMEA on jetson (missing bytes) : https://i.imgur.com/srEyFEH.png
NMEA on PC serial monitor: https://i.imgur.com/k7Rrh4c.png
ARDUINO CODE: (A lot of it is commented out, only the bare necessity remains)
/*
6-8-10
Aaron Weiss
SparkFun Electronics
Example GPS Parser based off of arduiniana.org TinyGPS examples.
Parses NMEA sentences from an EM406 running at 4800bps into readable
values for latitude, longitude, elevation, date, time, course, and
speed.
For the SparkFun GPS Shield. Make sure the switch is set to DLINE.
Once you get your longitude and latitude you can paste your
coordinates from the terminal window into Google Maps. Here is the
link for SparkFun's location.
http://maps.google.com/maps?q=40.06477,+-105.20997
Uses the NewSoftSerial library for serial communication with your GPS,
so connect your GPS TX and RX pin to any digital pin on the Arduino,
just be sure to define which pins you are using on the Arduino to
communicate with the GPS module.
*/
// In order for this sketch to work, you will need to download
// NewSoftSerial and TinyGPS libraries from arduiniana.org and put them
// into the hardware->libraries folder in your ardiuno directory.
// Here are the lines of code that point to those libraries.
#include <SoftwareSerial.h>
#include <TinyGPS.h>
// Define which pins you will use on the Arduino to communicate with your
// GPS. In this case, the GPS module's TX pin will connect to the
// Arduino's RXPIN which is pin 3.
#define RXPIN 10
#define TXPIN 9
//Set this value equal to the baud rate of your GPS
#define GPSBAUD 9600
// Create an instance of the TinyGPS object
TinyGPS gps;
// Initialize the NewSoftSerial library to the pins you defined above
SoftwareSerial uart_gps(10, 11);
// This is where you declare prototypes for the functions that will be
// using the TinyGPS library.
void getgps(TinyGPS &gps);
// In the setup function, you need to initialize two serial ports; the
// standard hardware serial port (Serial()) to communicate with your
// terminal program an another serial port (NewSoftSerial()) for your
// GPS.
void setup()
{
// This is the serial rate for your terminal program. It must be this
// fast because we need to print everything before a new sentence
// comes in. If you slow it down, the messages might not be valid and
// you will likely get checksum errors.
Serial.begin(115200);
//Sets baud rate of your GPS
uart_gps.begin(9600);
Serial.println("");
Serial.println("GPS Shield QuickStart Example Sketch v12");
Serial.println(" ...waiting for lock... ");
Serial.println("");
}
// This is the main loop of the code. All it does is check for data on
// the RX pin of the ardiuno, makes sure the data is valid NMEA sentences,
// then jumps to the getgps() function.
void loop()
{
while (uart_gps.available()) // While there is data on the RX pin...
{
int c = uart_gps.read(); // load the data into a variable...
Serial.write((char)c);
if (gps.encode(c)) // if there is a new valid sentence...
{
//Serial.println(" gps.encode(c)");
//Serial.println("");
//getgps(gps); // then grab the data.
}
}
}
// The getgps function will get and print the values we want.
void getgps(TinyGPS &gps)
{
int year;
byte month, day, hour, minute, second, hundredths;
gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths);
// Print data and time
Serial.print("D");
if (month < 10) {
Serial.print(0, DEC);
}
Serial.print(month, DEC); Serial.print("/");
if (day < 10) {
Serial.print(0, DEC);
}
Serial.print(day, DEC); Serial.print("/"); Serial.print(year);
Serial.print("T");
if (hour < 10) {
Serial.print(0, DEC);
}
Serial.print(hour, DEC); Serial.print(":");
if (minute < 10) {
Serial.print(0, DEC);
}
Serial.print(minute, DEC); Serial.print(":");
if (second < 10) {
Serial.print(0, DEC);
}
Serial.print(second, DEC); Serial.print(".");
if (hundredths < 10) {
Serial.print(0, DEC);
}
Serial.println(hundredths, DEC);
}
C code on jetson.
#include <stdio.h>
#include <unistd.h> //Used for UART
#include <fcntl.h> //Used for UART
#include <termios.h> //Used for UART
int main()
{
//-------------------------
//----- SETUP USART 0 -----
//-------------------------
//At bootup, pins 8 and 10 are already set to UART0_TXD, UART0_RXD (ie the alt0 function) respectively
int uart0_filestream = -1;
//OPEN THE UART
//The flags (defined in fcntl.h):
// Access modes (use 1 of these):
// O_RDONLY - Open for reading only.
// O_RDWR - Open for reading and writing.
// O_WRONLY - Open for writing only.
//
// O_NDELAY / O_NONBLOCK (same function) - Enables nonblocking mode. When set read requests on the file can return immediately with a failure status
// if there is no input immediately available (instead of blocking). Likewise, write requests can also return
// immediately with a failure status if the output can't be written immediately.
//
// O_NOCTTY - When set and path identifies a terminal device, open() shall not cause the terminal device to become the controlling terminal for the process.
uart0_filestream = open("/dev/ttyS0", O_RDONLY | O_NOCTTY | O_NDELAY); //Open in non blocking read/write mode
if (uart0_filestream == -1)
{
//ERROR - CAN'T OPEN SERIAL PORT
printf("Error - Unable to open UART. Ensure it is not in use by another application\n");
}
//CONFIGURE THE UART
//The flags (defined in /usr/include/termios.h - see http://pubs.opengroup.org/onlinepubs/007908799/xsh/termios.h.html):
// Baud rate:- B1200, B2400, B4800, B9600, B19200, B38400, B57600, B115200, B230400, B460800, B500000, B576000, B921600, B1000000, B1152000, B1500000, B2000000, B2500000, B3000000, B3500000, B4000000
// CSIZE:- CS5, CS6, CS7, CS8
// CLOCAL - Ignore modem status lines
// CREAD - Enable receiver
// IGNPAR = Ignore characters with parity errors
// ICRNL - Map CR to NL on input (Use for ASCII comms where you want to auto correct end of line characters - don't use for bianry comms!)
// PARENB - Parity enable
// PARODD - Odd parity (else even)
struct termios options;
tcgetattr(uart0_filestream, &options);
cfsetispeed(&options, B115200);
cfsetospeed(&options, B115200);
options.c_cflag = B115200 | CS8 | CLOCAL | CREAD; //<Set baud rate
options.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);
options.c_oflag = 0;
options.c_lflag = 0;
tcflush(uart0_filestream, TCIFLUSH);
tcsetattr(uart0_filestream, TCSANOW, &options);
//----- CHECK FOR ANY RX BYTES -----
while (uart0_filestream != -1)
{
// Read up to 255 characters from the port if they are there
unsigned char rx_buffer[256];
int rx_length = read(uart0_filestream, (void*)rx_buffer, 255); //Filestream, buffer to store in, number of bytes to read (max)
if (rx_length < 0)
{
//perror("read");
//An error occured (will occur if there are no bytes)
}
else if (rx_length == 0)
{
perror("nodata \n");
//No data waiting
}
else
{
//Bytes received
rx_buffer[rx_length] = '
#include <stdio.h>
#include <unistd.h> //Used for UART
#include <fcntl.h> //Used for UART
#include <termios.h> //Used for UART
int main()
{
//-------------------------
//----- SETUP USART 0 -----
//-------------------------
//At bootup, pins 8 and 10 are already set to UART0_TXD, UART0_RXD (ie the alt0 function) respectively
int uart0_filestream = -1;
//OPEN THE UART
//The flags (defined in fcntl.h):
// Access modes (use 1 of these):
// O_RDONLY - Open for reading only.
// O_RDWR - Open for reading and writing.
// O_WRONLY - Open for writing only.
//
// O_NDELAY / O_NONBLOCK (same function) - Enables nonblocking mode. When set read requests on the file can return immediately with a failure status
// if there is no input immediately available (instead of blocking). Likewise, write requests can also return
// immediately with a failure status if the output can't be written immediately.
//
// O_NOCTTY - When set and path identifies a terminal device, open() shall not cause the terminal device to become the controlling terminal for the process.
uart0_filestream = open("/dev/ttyS0", O_RDONLY | O_NOCTTY | O_NDELAY); //Open in non blocking read/write mode
if (uart0_filestream == -1)
{
//ERROR - CAN'T OPEN SERIAL PORT
printf("Error - Unable to open UART. Ensure it is not in use by another application\n");
}
//CONFIGURE THE UART
//The flags (defined in /usr/include/termios.h - see http://pubs.opengroup.org/onlinepubs/007908799/xsh/termios.h.html):
// Baud rate:- B1200, B2400, B4800, B9600, B19200, B38400, B57600, B115200, B230400, B460800, B500000, B576000, B921600, B1000000, B1152000, B1500000, B2000000, B2500000, B3000000, B3500000, B4000000
// CSIZE:- CS5, CS6, CS7, CS8
// CLOCAL - Ignore modem status lines
// CREAD - Enable receiver
// IGNPAR = Ignore characters with parity errors
// ICRNL - Map CR to NL on input (Use for ASCII comms where you want to auto correct end of line characters - don't use for bianry comms!)
// PARENB - Parity enable
// PARODD - Odd parity (else even)
struct termios options;
tcgetattr(uart0_filestream, &options);
cfsetispeed(&options, B115200);
cfsetospeed(&options, B115200);
options.c_cflag = B115200 | CS8 | CLOCAL | CREAD; //<Set baud rate
options.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);
options.c_oflag = 0;
options.c_lflag = 0;
tcflush(uart0_filestream, TCIFLUSH);
tcsetattr(uart0_filestream, TCSANOW, &options);
//----- CHECK FOR ANY RX BYTES -----
while (uart0_filestream != -1)
{
// Read up to 255 characters from the port if they are there
unsigned char rx_buffer[256];
int rx_length = read(uart0_filestream, (void*)rx_buffer, 255); //Filestream, buffer to store in, number of bytes to read (max)
if (rx_length < 0)
{
//perror("read");
//An error occured (will occur if there are no bytes)
}
else if (rx_length == 0)
{
perror("nodata \n");
//No data waiting
}
else
{
//Bytes received
rx_buffer[rx_length] = '\0';
printf("%i bytes read : %s\n", rx_length, rx_buffer);
}
}
//----- CLOSE THE UART -----
close(uart0_filestream);
return 0;
}
';
printf("%i bytes read : %s\n", rx_length, rx_buffer);
}
}
//----- CLOSE THE UART -----
close(uart0_filestream);
return 0;
}