/*
NMEA Sentence Builder
https://www.sparkfun.com/datasheets/GPS/NMEA%20Reference%20Manual1.pdf
See readme
*/
const char* MSG_IDS[6] = {
"$GPGGA",
"$GPGLL",
"$GPGSA",
"$GPGSV",
"$GPRMC",
"$GPVTG"
};
const char UTC_TIME[] = {"171530.123"}; // hhmmss.sss
char sentence[85];
char coordBuffer[25];
char csBuffer[3];
//double latitude = 4110.3962; // ddmm.mmmm N
//double longitude = 07427.1141; // dddmm.mmmm W
//double longitude = 99999.1141; // dddmm.mmmm W
int degLat = 0;
int minLat = 0;
int secLat = 1234;
int degLong = 0;
int minLong = 0;
int secLong = 1234;
char ns;
char ew;
char* makeCoord() {
snprintf(coordBuffer, 25, "%02d%02d.%04d,%c,%03d%02d.%04d,%c", degLat, minLat, secLat, ns, degLong, minLong, secLong, ew);
//Serial.println(coordBuffer);
return coordBuffer;
}
// Message ID, Lat, N/S, Long, E/W, UTC, Status, Mode
// $GPGLL,Lat,NS,Long,EW,UTC,A,A*CS
char* makeGPGLL() {
char nmeaBuffer[85];
snprintf(nmeaBuffer, 85, "%s,%s,%s,A,A", MSG_IDS[1], makeCoord(), UTC_TIME);
int cs = makeChecksum(nmeaBuffer);
strncat(nmeaBuffer, "*", 1);
strncat(nmeaBuffer, decToHexa(cs), 3);
strncat(nmeaBuffer, "\r\n", 2);
strncat(nmeaBuffer, "\0", 1);
strncpy(sentence, nmeaBuffer, 85);
//Serial.println(sentence);
return sentence;
}
// Message ID, UTC Time, Lat, N/S, Long, E/W, Fix, Sats, HDOP, MSL Altitude, Units, Geoid Separation, Units, Age of Diff. Corr, Diff. Ref. Station ID, Checksum, CR+LF
// $GPGGA,hhmmss.sss,ddmm.mmmm,N,dddmm.mmmm,W,1,07,1.0,100,M,,,,0000*CS<CR+LF>
char* makeGPGGA() {
char nmeaBuffer[85];
char fixedData[] = {"1,07,1.0,100,M,,,,0000"};
snprintf(nmeaBuffer, 85, "%s,%s,%s,%s", MSG_IDS[0], UTC_TIME, makeCoord(), fixedData);
int cs = makeChecksum(nmeaBuffer);
strncat(nmeaBuffer, "*", 1);
strncat(nmeaBuffer, decToHexa(cs), 3);
strncat(nmeaBuffer, "\r\n", 2);
strncat(nmeaBuffer, "\0", 1);
strncpy(sentence, nmeaBuffer, 85);
//Serial.println(sentence);
return sentence;
}
//Message ID, UTC, Status, Lat, N/S, Long, E/W, Speed, Course, Date, Mag, Mode
//$GPRMC,UTC,A,Lat,NS,Long,EW,0.13,309.62,150824,,*CS
char* makeGPRMC() {
char nmeaBuffer[85];
char fixedData[] = {"0.13,309.62,150824,,"};
snprintf(nmeaBuffer, 85, "%s,%s,A,%s,%s", MSG_IDS[4], UTC_TIME, makeCoord(), fixedData);
int cs = makeChecksum(nmeaBuffer);
strncat(nmeaBuffer, "*", 1);
strncat(nmeaBuffer, decToHexa(cs), 3);
strncat(nmeaBuffer, "\r\n", 2);
strncat(nmeaBuffer, "\0", 1);
strncpy(sentence, nmeaBuffer, 85);
//Serial.println(sentence);
return sentence;
}
char* decToHexa(int n) {
csBuffer[0] = intToHex(n / 16);
csBuffer[1] = intToHex(n % 16);
csBuffer[2] = '\0';
//Serial.print("Hex cs: ");
//Serial.println(csBuffer);
return csBuffer;
}
char intToHex(int value) {
char hexChar;
if (value < 10) {
hexChar = value + 48;
} else {
hexChar = value + 55;
}
return hexChar;
}
byte makeChecksum(char *msg) {
byte checksum = 0;
for (int i = 1; i < strlen(msg); i++) {
checksum = checksum ^ (byte)msg[i];
}
//Serial.print("Dec cs: ");
//Serial.println(checksum);
return checksum;
}
void setup() {
Serial.begin(115200);
}
void loop() {
char* message;
degLat = map(analogRead(A3), 0, 1023, -90, 90);
minLat = map(analogRead(A2), 0, 1023, 0, 59);
int secLat = 1234;
degLong = map(analogRead(A1), 0, 1023, -180, 180);
minLong = map(analogRead(A0), 0, 1023, 0, 59);
int secLong = 1234;
if (degLat < 0) {
ns = 'S';
degLat = abs(degLat);
} else {
ns = 'N';
}
if (degLong < 0) {
ew = 'W';
degLong = abs(degLong);
} else {
ew = 'E';
}
/*
Serial.print("Lat deg : ");
Serial.print(degLat);
Serial.print("\tLat min : ");
Serial.println(minLat);
Serial.print("Long deg: ");
Serial.print(degLong);
Serial.print("\tLong min: ");
Serial.println(minLong);
*/
//Message ID, UTC Time, Lat, N/S, Long, E/W, Fix, Sats, HDOP, MSL Altitude, Units, Geoid Separation, Units, Age of Diff. Corr, Diff. Ref. Station ID, Checksum, CR+LF
message = makeGPGGA();
Serial.print(message);
message = makeGPGLL();
Serial.print(message);
//Message ID, Mode 1, mode 2, Sats Used, PDOP, HDOP, VDOP
Serial.println("$GPGSA,A,3,07,02,26,27,09,04,15,,,,,,1.8,1.0,1.5*33");
//Message ID , Number of Messages, Message Number1, Sats in view, Sat ID, Elevation, Azimuth, SNR, ...*CS<CR+LF>
Serial.println("$GPGSV,2,1,07,07,79,048,42,02,51,062,43,26,36,256,42,27,27,138,42*71");
Serial.println("$GPGSV,2,2,07,09,23,313,42,04,19,159,41,15,12,041,42*41");
message = makeGPRMC();
Serial.print(message);
//Message ID, Course, Ref, Course, Ref, Speed, Units, Speed, Units, Mode
Serial.println("$GPVTG,309.62,T, ,M,0.13,N,0.2,K,A*23");
delay(3000);
}