The Sparkfun Redboard and other toys can be a lot of fun indeed. What I like about the Arduinos, is that the board support packages are very good and it is very easy to intersperse regular C with the simple Sketch code.
Here is a minimalist on the fly parser for NMEA GPS data positioning that I've been playing with. It receives and analyzes one byte at a time, so there is no delay. You have the data the very moment it is available:
// Minimal GPS Parser
// Herman Oosthuysen, 2016
#include <string.h>
#include <SoftwareSerial.h>
// GPS serial: 9600N81
// Example GPS data capture
//$GPGSA,A,3,11,31,27,14,,,,,,,,,2.09,1.85,0.96*08
//$GPRMC,155741.000,A,2413.4311,N,05541.2983,E,1.19,45.34,240816,,,A*5D
//$GPVTG,45.34,T,,M,1.19,N,2.21,K,A*03
//$GPGGA,155742.000,2413.4313,N,05541.2985,E,1,4,1.85,263.9,M,-29.9,M,,*77
//Time, Lat, North, Long, East, Fix:
//$GPGGA,155743.000,2413.4317,N,05541.2986,E,1,
//Heading true, heading magnetic, speed knots, speed kph
//$GPVTG,45.34,T,,M,1.19,N,2.21,K
const int rxpin=8;
//const int txpin=9;
const int txpin=255; // Rx only, frees up a pin
SoftwareSerial serial_gps(rxpin, txpin);
char ch = 0;
int cnt = 0;
int csv = 0;
int fix = 0;
int res = 1;
char dat[16];
char tim[16];
char lat[16];
char lng[16];
void setup()
{
Serial.begin(9600);
serial_gps.begin(9600);
}
void loop()
{
if(serial_gps.available())
{
ch=serial_gps.read();
//Serial.print(ch);
// simple parser, start with $
if(ch == '$')
{
cnt = 0;
csv = 0;
fix = 0;
}
else
{
dat[cnt++] = ch;
if(ch == ',')
{
dat[--cnt] = 0;
cnt = 0;
csv++;
if(csv == 1)
{
res = strcmp(dat,"GPGGA");
if(res == 0)
fix = 1;
}
// Assume N, E
if(fix == 1)
{
if(csv == 2)
strcpy(tim, dat);
else if(csv == 3)
strcpy(lat, dat);
else if(csv == 5)
strcpy(lng, dat);
else if(csv == 6)
{
Serial.print("Tim: ");
Serial.println(tim);
Serial.print("Lat: ");
Serial.println(lat);
Serial.print("Lon: ");
Serial.println(lng);
fix = 0;
}
}
}
}
}
}
The result is:
Tim: 154417.000
Lat: 2413.4364
Lon: 05541.2907
Cool, now you all know exactly where I live.
In days gone by, there were phone directories, now, there is GPS.
There are Arduino GPS libraries available, but they are too complex for my liking. For a toy, one can make some assumptions to simplify things, which saves processing cycles and memory. I don't see the need to verify the checksum, or check whether the position is north and east - I'm not going to drive my toy car to the other side of the globe.
The Arduino software and Redboard works pretty good on my Mac, but if I unplug it from the USB port, then I have to reboot the Mac to get the USB serial port to work again when I plug it back in. There should be a way to force the Mac to reload the driver, but I haven't gotten round to diving into the OSX weeds to figure it out yet.
Have fun!
Herman
Here is a minimalist on the fly parser for NMEA GPS data positioning that I've been playing with. It receives and analyzes one byte at a time, so there is no delay. You have the data the very moment it is available:
// Minimal GPS Parser
// Herman Oosthuysen, 2016
#include <string.h>
#include <SoftwareSerial.h>
// GPS serial: 9600N81
// Example GPS data capture
//$GPGSA,A,3,11,31,27,14,,,,,,,,,2.09,1.85,0.96*08
//$GPRMC,155741.000,A,2413.4311,N,05541.2983,E,1.19,45.34,240816,,,A*5D
//$GPVTG,45.34,T,,M,1.19,N,2.21,K,A*03
//$GPGGA,155742.000,2413.4313,N,05541.2985,E,1,4,1.85,263.9,M,-29.9,M,,*77
//Time, Lat, North, Long, East, Fix:
//$GPGGA,155743.000,2413.4317,N,05541.2986,E,1,
//Heading true, heading magnetic, speed knots, speed kph
//$GPVTG,45.34,T,,M,1.19,N,2.21,K
const int rxpin=8;
//const int txpin=9;
const int txpin=255; // Rx only, frees up a pin
SoftwareSerial serial_gps(rxpin, txpin);
char ch = 0;
int cnt = 0;
int csv = 0;
int fix = 0;
int res = 1;
char dat[16];
char tim[16];
char lat[16];
char lng[16];
void setup()
{
Serial.begin(9600);
serial_gps.begin(9600);
}
void loop()
{
if(serial_gps.available())
{
ch=serial_gps.read();
//Serial.print(ch);
// simple parser, start with $
if(ch == '$')
{
cnt = 0;
csv = 0;
fix = 0;
}
else
{
dat[cnt++] = ch;
if(ch == ',')
{
dat[--cnt] = 0;
cnt = 0;
csv++;
if(csv == 1)
{
res = strcmp(dat,"GPGGA");
if(res == 0)
fix = 1;
}
// Assume N, E
if(fix == 1)
{
if(csv == 2)
strcpy(tim, dat);
else if(csv == 3)
strcpy(lat, dat);
else if(csv == 5)
strcpy(lng, dat);
else if(csv == 6)
{
Serial.print("Tim: ");
Serial.println(tim);
Serial.print("Lat: ");
Serial.println(lat);
Serial.print("Lon: ");
Serial.println(lng);
fix = 0;
}
}
}
}
}
}
The result is:
Tim: 154417.000
Lat: 2413.4364
Lon: 05541.2907
Cool, now you all know exactly where I live.
In days gone by, there were phone directories, now, there is GPS.
There are Arduino GPS libraries available, but they are too complex for my liking. For a toy, one can make some assumptions to simplify things, which saves processing cycles and memory. I don't see the need to verify the checksum, or check whether the position is north and east - I'm not going to drive my toy car to the other side of the globe.
The Arduino software and Redboard works pretty good on my Mac, but if I unplug it from the USB port, then I have to reboot the Mac to get the USB serial port to work again when I plug it back in. There should be a way to force the Mac to reload the driver, but I haven't gotten round to diving into the OSX weeds to figure it out yet.
Have fun!
Herman
Comments
Post a Comment
On topic comments are welcome. Junk will be deleted.