//************************************************************************
//* GPS Almanac display
//* by Mark Sproul
//* March 7, 2010
//************************************************************************
#include
#include
#include
#include
#include "WConstants.h"
#include "wiring.h"
#ifdef __MWERKS__
int atoi(...);
int sprintf(...);
#endif
#define _T6963_GRAPHICS_
//#define _MEGA_
#ifdef _T6963_GRAPHICS_
#include
// T6963 LCD(160,128,6,32);
T6963 LCD(160,128,8,64);
#define kScreen_Width 160
#define kScreen_Height 128
#endif
#include "HardwareSerial.h"
//#include
#include
#ifdef _T6963_GRAPHICS_
#define kTX_Pin 10
#define kRX_Pin 11
#define kPOWER_Pin 12
#define kLED1_PIN 13
// #define kLED2_PIN 13
#elif defined(_MEGA_)
#define kTX_Pin 10
#define kRX_Pin 11
#define kPOWER_Pin 12
#define kLED1_PIN 13
// #define kLED2_PIN 13
#else
#define kTX_Pin 4
#define kRX_Pin 5
#define kPOWER_Pin 6
#define kLED1_PIN 7
#define kLED2_PIN 8
#endif
#define kGPSRATE 4800
typedef struct
{
unsigned int elevation;
unsigned int snr; //* signal to noise ration
unsigned int asimuth;
} SAT_DATA;
//AFSoftSerial gpsSerial = AFSoftSerial(kTX_Pin, kRX_Pin);
SoftwareSerial gpsSerial = SoftwareSerial(kTX_Pin, kRX_Pin);
#define kNMEAbuffSize 80 // plenty big
char gNMEAbuffer[kNMEAbuffSize];
char gNMEAbuffidx;
int gNMEAhour;
int gNMEAminute;
int gNMEAsecond;
int gNMEAsatCount;
#define kSatMaxCount 32
SAT_DATA gNMEAsatData[kSatMaxCount];
//#define _OUTPUT_TO_CONSOLE_
//************************************************************************
void setup()
{
int ii;
Serial.begin(115200);
Serial.println();
Serial.println("GPS Clock");
pinMode(kLED1_PIN, OUTPUT);
pinMode(kLED1_PIN, OUTPUT);
//* turn on the GPS
pinMode(kPOWER_Pin, OUTPUT);
digitalWrite(kPOWER_Pin, LOW); // pull low to turn on!
gpsSerial.begin(kGPSRATE); //* open GPS port
// Serial.println("GPS Power turned on");
gNMEAbuffidx = 0;
gNMEAsatCount = 0;
for (ii=0; ii 0) || (gNMEAsatData[ii].asimuth > 0))
{
azm = ReturnCompAngFromMapAng(gNMEAsatData[ii].asimuth);
relv = (1.0 * gNMEAsatData[ii].elevation) / kDeg2Rad;
razm = (1.0 * azm) / kDeg2Rad;
dhy = cos(relv) * (circleRadius - 3);
daj = cos(razm) * dhy;
dop = sin(razm) * dhy;
satCenterX = xCenter + daj;
satCenterY = yCenter - dop;
LCD.createLine(satCenterX - 2, satCenterY, satCenterX + 2, satCenterY);
LCD.createLine(satCenterX, satCenterY - 2, satCenterX, satCenterY + 2);
// LCD.createCircle(satCenterX, satCenterY, 2);
}
}
#elif defined(foobar)
char myString[32];
int ii;
int yy;
sprintf(myString, "Sat cnt=%d", gNMEAsatCount);
LCD.TextGoTo(0, 1);
LCD.WriteString(myString);
yy = 2;
for (ii=0; ii 0) || (gNMEAsatData[ii].asimuth > 0))
{
sprintf(myString, "%2d %2d %3d %2d", ii,
gNMEAsatData[ii].elevation,
gNMEAsatData[ii].asimuth,
gNMEAsatData[ii].snr);
LCD.TextGoTo(0, yy);
LCD.WriteString(myString);
// Serial.println(myString);
yy++;
}
}
#endif
}
//************************************************************************
//* GPS Clock
//* $PSRFTXT,Version:GSW3.2.4_3.1.00.12-SDK003P1.00a
//* $PSRFTXT,Version2:F-GPS-03-0701301
//* $PSRFTXT,WAAS Enable
//* $PSRFTXT,TOW: 0
//* $PSRFTXT,WK: 1399
//* $PSRFTXT,POS: 6378137 0 0
//* $PSRFTXT,CLK: 96250
//* $PSRFTXT,CHNL: 12
//* $PSRFTXT,Baud rate: 4800
//* $GPGGA,235947.031,,,,,0,00,,,M,0.0,M,,0000*5A
//* $GPGSA,A,1,,,,,,,,,,,,,,,*1E
//* $GPRMC,235947.031,V,,,,,,,281006,,*2E
//* $GPGGA,235948.039,,,,,0,00,,,M,0.0,M,,0000*5D
//* $GPGSA,A,1,,,,,,,,,,,,,,,*1E
//* $GPRMC,235948.039,V,,,,,,,281006,,*29
//* $GPGGA,235949.030,,,,,0,00,,,M,0.0,M,,0000*55
//* $GPGSA,A,1,,,,,,,,,,,,,,,*1E
//* $GPRMC,235949.030,V,,,,,,,281006,,*21
//* $GPGGA,235950.030,,,,,0,00,,,M,0.0,M,,0000*5D
//* $GPGSA,A,1,,,,,,,,,,,,,,,*1E
//* $GPRMC,235950.030,V,,,,,,,281006,,*29
//* $GPGGA,235951.038,,,,,0,00,,,M,0.0,M,,0000*54
//*
//* $GPGGA,003509.000,4027.4299,N,07430.2057,W,1,04,2.0,40.9,M,-34.1,M,,0000*56
//* $GPGSA,A,3,32,14,31,30,,,,,,,,,4.0,2.0,3.5*37
//* $GPRMC,003509.000,A,4027.4299,N,07430.2057,W,0.48,346.15,070310,,*15
//* $GPGGA,003510.000,4027.4297,N,07430.2055,W,1,04,2.0,40.9,M,-34.1,M,,0000*52
//* $GPGSA,A,3,32,14,31,30,,,,,,,,,4.0,2.0,3.5*37
//* $GPGSV,3,1,12,25,70,326,,31,70,008,28,32,51,276,35,01,48,314,26*77
//* $GPGSV,3,2,12,05,42,054,,14,40,112,22,16,37,195,23,20,28,304,28*70
//* $GPGSV,3,3,12,30,23,045,28,06,18,074,,07,16,062,,22,09,168,*7D
//* $GPRMC,003510.000,A,4027.4297,N,07430.2055,W,0.35,144.00,070310,,*1F
//* $GPGGA,003511.000,4027.4291,N,07430.2051,W,1,04,2.0,40.8,M,-34.1,M,,0000*50
//* $GPGSA,A,3,32,14,31,30,,,,,,,,,4.0,2.0,3.5*37
//* $GPRMC,003511.000,A,4027.4291,N,07430.2051,W,1.38,153
//************************************************************************
void ProcessNMEA(char *nmeaBuffer)
{
long nmeaSentanceType;
char hourString[4];
char minString[4];
char secString[4];
char myString[32];
int ii;
int cc;
int comaCount;
int parsedNum;
int satEntryIndex;
int satData[16];
int gsvEntryCount;
int gsvEntryNumber;
boolean keepGoing;
if ((nmeaBuffer[0] == '$') && (nmeaBuffer[1] == 'G'))
{
nmeaSentanceType = 0;
for (ii = 0; ii < 4; ii++)
{
nmeaSentanceType = nmeaSentanceType << 8;
nmeaSentanceType += nmeaBuffer[2 + ii];
}
switch(nmeaSentanceType)
{
//* Global Positioning System Fix Data
//* $GPGGA,003509.000,4027.4299,N,07430.2057,W,1,04,2.0,40.9,M,-34.1,M,,0000*56
// case 'PGGA':
case 0x50474741:
// Serial.println(nmeaBuffer);
ii = 7;
hourString[0] = nmeaBuffer[ii++];
hourString[1] = nmeaBuffer[ii++];
hourString[2] = 0;
minString[0] = nmeaBuffer[ii++];
minString[1] = nmeaBuffer[ii++];
minString[2] = 0;
secString[0] = nmeaBuffer[ii++];
secString[1] = nmeaBuffer[ii++];
secString[2] = 0;
// Serial.print("\x0c");
strcpy(myString, hourString);
strcat(myString, ":");
strcat(myString, minString);
strcat(myString, ":");
strcat(myString, secString);
strcat(myString, " Z");
#ifdef _T6963_GRAPHICS_
LCD.TextGoTo(0,0);
LCD.WriteString(myString);
#else
// Serial.println(myString);
#endif
gNMEAhour = atoi(hourString);
gNMEAminute = atoi(minString);
gNMEAsecond = atoi(secString);
if (gNMEAsecond == 0)
{
// Serial.print("\x07"); //* send a bell
}
gNMEAhour += 19; //* adjust to local time
digitalWrite(kLED1_PIN, HIGH); //* turn on LED
break;
//* GPS Satellites in view
//* $GPGSV,3,1,12,25,70,326,,31,70,008,28,32,51,276,35,01,48,314,26*77
//* $GPGSV,3,2,12,05,42,054,,14,40,112,22,16,37,195,23,20,28,304,28*70
//* $GPGSV,3,3,12,30,23,045,28,06,18,074,,07,16,062,,22,09,168,*7D
// case 'PGSV':
case 0x50475356:
// Serial.println(nmeaBuffer);
for (ii=0; ii<16; ii++)
{
satData[ii] = 0;;
}
digitalWrite(kLED1_PIN, LOW); //* turn on LED
gsvEntryCount = 0;
gsvEntryNumber = 0;
ii = 0;
cc = 0;
comaCount = 0;
keepGoing = true;
while ((nmeaBuffer[ii] != 0) && keepGoing)
{
if (nmeaBuffer[ii] == '*')
{
keepGoing = false;
}
if ((nmeaBuffer[ii] == ',') || (nmeaBuffer[ii] == '*'))
{
//* time to do something with the string
myString[cc++] = 0;
parsedNum = atoi(myString);
if (comaCount == 1)
{
gsvEntryCount = parsedNum;
}
if (comaCount == 2)
{
gsvEntryNumber = parsedNum;
}
if (comaCount == 3)
{
gNMEAsatCount = parsedNum;
}
else if ((comaCount >= 4) && (comaCount <= 19))
{
satData[comaCount - 4] = parsedNum;
}
comaCount++;
cc = 0;
}
else
{
myString[cc++] = nmeaBuffer[ii];
}
ii++;
}
//* go through the 4 entries
for (ii=0; ii<4; ii++)
{
satEntryIndex = satData[(ii * 4)];
if ((satEntryIndex > 0) && (satEntryIndex < 32))
{
gNMEAsatData[satEntryIndex].elevation = satData[(ii * 4) + 1];
gNMEAsatData[satEntryIndex].asimuth = satData[(ii * 4) + 2];
gNMEAsatData[satEntryIndex].snr = satData[(ii * 4) + 3];
}
}
if ((gsvEntryCount > 0) && (gsvEntryNumber == gsvEntryCount))
{
DisplayGPSalmanac();
}
break;
}
}
}
//************************************************************************
void loop()
{
char gpsChar;
gpsChar = gpsSerial.read();
#ifdef _OUTPUT_TO_CONSOLE_
Serial.write(gpsChar);
#endif
if (gpsChar == 0x0d)
{
//* if its a CR, process the line
gNMEAbuffer[gNMEAbuffidx++] = 0;
ProcessNMEA(gNMEAbuffer);
gNMEAbuffidx = 0;
}
else if ((gpsChar >= 0x20) && (gNMEAbuffidx < kNMEAbuffSize))
{
//* valid char store it
gNMEAbuffer[gNMEAbuffidx++] = gpsChar;
//* first char MUST be '$'
if (gNMEAbuffer[0] != '$')
{
gNMEAbuffidx = 0;
}
}
}
|