Skip to content

Instantly share code, notes, and snippets.

@micolous
Created September 13, 2013 14:44
Show Gist options
  • Save micolous/6551656 to your computer and use it in GitHub Desktop.
Save micolous/6551656 to your computer and use it in GitHub Desktop.
// Test code for Adafruit GPS modules using MTK3329/MTK3339 driver
//
// This code just echos whatever is coming from the GPS unit to the
// serial monitor, handy for debugging!
//
// Tested and works great with the Adafruit Ultimate GPS module
// using MTK33x9 chipset
// ------> http://www.adafruit.com/products/746
// Pick one up today at the Adafruit electronics shop
// and help support open source hardware & software! -ada
#include <Adafruit_GPS.h>
#if ARDUINO >= 100
#include <SoftwareSerial.h>
#else
// Older Arduino IDE requires NewSoftSerial, download from:
// http://arduiniana.org/libraries/newsoftserial/
// #include <NewSoftSerial.h>
// DO NOT install NewSoftSerial if using Arduino 1.0 or later!
#endif
#include <SerialLCD.h>
#include <Time.h>
#include <Timezone.h>
#include <FlippedTM1640.h>
#include <TM16XX.h>
#include <TM16XXFonts.h>
// Connect the GPS Power pin to 5V
// Connect the GPS Ground pin to ground
// If using software serial (sketch example default):
// Connect the GPS TX (transmit) pin to Digital 3
// Connect the GPS RX (receive) pin to Digital 2
// If using hardware serial (e.g. Arduino Mega):
// Connect the GPS TX (transmit) pin to Arduino RX1, RX2 or RX3
// Connect the GPS RX (receive) pin to matching TX1, TX2 or TX3
// If using software serial, keep these lines enabled
// (you can change the pin numbers to match your wiring):
/*
#if ARDUINO >= 100
SoftwareSerial mySerial(6, 5);
#else
NewSoftSerial mySerial(3, 2);
#endif
*/
//Adafruit_GPS GPS(&mySerial);
// If using hardware serial (e.g. Arduino Mega), comment
// out the above six lines and enable this line instead:
Adafruit_GPS GPS(&Serial);
SerialLCD slcd(11, 12);
// Set GPSECHO to 'false' to turn off echoing the GPS data to the Serial console
// Set to 'true' if you want to debug and listen to the raw GPS sentences
#define GPSECHO true
// this keeps track of whether we're using the interrupt
// off by default!
boolean usingInterrupt = false;
void useInterrupt(boolean); // Func prototype keeps Arduino 0023 happy
TimeChangeRule aCDT = {"ACDT", First, Sun, Oct, 2, 630}; //UTC + 10.5 hours
TimeChangeRule aCST = {"ACST", First, Sun, Apr, 3, 570}; //UTC + 9.5 hours
Timezone ausCT(aCDT, aCST);
char* courses = "N NEE SES SWW NW";
// for temperature sensor
int a, b = 3975;
float resistance, temperature;
FlippedTM1640 sevenseg(8, 9);
const int tempPin = 0;
const int laptopRelayPin = 3;
void getTemperature() {
a = analogRead(tempPin);
resistance = (float)(1023 - a) * 10000 / a;
temperature = 1 / (log(resistance / 10000) / b + 1 / 298.15) - 273.15;
//return temperature;
}
void setup()
{
// ensure relay is open
digitalWrite(laptopRelayPin, LOW);
slcd.begin();
slcd.print("GPS...");
slcd.setCursor(0, 0);
// connect at 115200 so we can read the GPS fast enuf and
// also spit it out
//Serial.begin(115200);
// 9600 NMEA is the default baud rate for MTK - some use 4800
GPS.begin(9600);
GPS.sendCommand(PMTK_SET_BAUD_19200);
GPS.end();
GPS.begin(19200);
// uncomment this line to turn on RMC (recommended minimum) and GGA (fix data) including altitude
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
// uncomment this line to turn on only the "minimum recommended" data for high update rates!
//GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY);
// uncomment this line to turn on all the available data - for 9600 baud you'll want 1 Hz rate
//GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_ALLDATA);
// Set the update rate
// 1 Hz update rate
//GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
// 5 Hz update rate- for 9600 baud you'll have to set the output to RMC or RMCGGA only (see above)
//GPS.sendCommand(PMTK_SET_NMEA_UPDATE_5HZ);
// 10 Hz update rate - for 9600 baud you'll have to set the output to RMC only (see above)
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_10HZ);
// Request updates on antenna status, comment out to keep quiet
//GPS.sendCommand(PGCMD_ANTENNA);
// the nice thing about this code is you can have a timer0 interrupt go off
// every 1 millisecond, and read data from the GPS for you. that makes the
// loop code a heck of a lot easier!
//useInterrupt(true);
delay(1000);
slcd.print("PC... ");
slcd.setCursor(0, 0);
// press the button for a second
digitalWrite(laptopRelayPin, HIGH);
delay(1000);
// let go
digitalWrite(laptopRelayPin, LOW);
// setup tm1640:
sevenseg.setupDisplay(true, 7);
}
// Interrupt is called once a millisecond, looks for any new GPS data, and stores it
SIGNAL(TIMER0_COMPA_vect) {
char c = GPS.read();
// if you want to debug, this is a good time to do it!
/*
if (GPSECHO)
if (c) UDR0 = c;
// writing direct to UDR0 is much much faster than Serial.print
// but only one character can be written at a time.
*/
}
void useInterrupt(boolean v) {
if (v) {
// Timer0 is already used for millis() - we'll just interrupt somewhere
// in the middle and call the "Compare A" function above
OCR0A = 0xAF;
TIMSK0 |= _BV(OCIE0A);
usingInterrupt = true;
} else {
// do not call the interrupt function COMPA anymore
TIMSK0 &= ~_BV(OCIE0A);
usingInterrupt = false;
}
}
uint32_t scrTimer = millis();
uint32_t tzTimer = millis();
uint32_t currently = 0;
time_t localTime, utcTime;
int angleIndex = 0;
char* heading;
float speedKmh = 0;
char sevenSegBuffer[17];
tmElements_t currentTime;
void loop() // run over and over again
{
char c = GPS.read();
// printing of NMEA sentences is done by interrupt. now handle data
if (GPS.newNMEAreceived()) {
// try to parse
if (!GPS.parse(GPS.lastNMEA(), false)) {
// failed to parse
return;
} /* else if (GPS.lastPacketType == LAST_GPRMC && GPS.seconds == 0 && GPS.milliseconds < 200) {
setTime(GPS.hour, GPS.minute, GPS.seconds, GPS.day, GPS.month, GPS.year);
Serial.println(now(), DEC);
delay(500);
tzTimer = currently = scrTimer = millis();
}*/
}
currently = millis();
if (tzTimer > currently) tzTimer = currently;
if (scrTimer > currently) scrTimer = currently;
if (currently - tzTimer > 1000) {
tzTimer = currently;
currentTime.Year = GPS.year + 30; // years since 1970
currentTime.Month = GPS.month;
currentTime.Day = GPS.day;
currentTime.Hour = GPS.hour;
currentTime.Minute = GPS.minute;
currentTime.Second = GPS.seconds;
getTemperature();
utcTime = makeTime(currentTime);
//if (1363318376 < utcTime < 4290000000)
localTime = ausCT.toLocal(utcTime);
/*
if (hour(localTime) != 14) {
Serial.print("BAD TIME = ");
Serial.print(utcTime);
Serial.print(" / ");
Serial.println(localTime);
}*/
}
if (currently - scrTimer > 100) {
// every 100ms
scrTimer = currently;
// set the system clock
// discard obviously bad data
//if (GPS.year >= 2013)
//Serial.print("\nSpeed: ");
// knots to km/h
speedKmh = (float)(GPS.speed * 1.852);
heading = courses + ((byte)((
((int)(GPS.angle + 22.5)) // add 22.5 to the angle so that angles line up
/ 45)
% 8) * 2);
// write to TM1640
memset(sevenSegBuffer, 0, sizeof(sevenSegBuffer));
sprintf(sevenSegBuffer, "%02d%02d %02d %03d %2.2s",
hour(localTime),
minute(localTime),
temperature > 99 ? 99 : temperature < 0 ? 0 : (unsigned short)temperature /* temperature */,
speedKmh > 999 ? 999 : speedKmh < 0 ? 0 : (unsigned short)speedKmh,
heading
);
sevenseg.setDisplayToString(sevenSegBuffer, (second(localTime) % 2) << 14, 0);
// write to 16x2 display
/*
slcd.print(speedKmh, DEC);
slcd.print(" km/h ");
slcd.setCursor(14,0);
slcd.print((char)*heading);
slcd.print((char)*(heading+1));
*/
slcd.print(sevenSegBuffer);
slcd.setCursor(0,1);
if (hour(localTime) < 10) slcd.print("0");
slcd.print((long unsigned int)hour(localTime), DEC);
slcd.print(":");
if (minute(localTime) < 10) slcd.print("0");
slcd.print((long unsigned int)minute(localTime), DEC);
slcd.print(":");
if (second(localTime) < 10) slcd.print("0");
slcd.print((long unsigned int)second(localTime), DEC);
slcd.print(".");
slcd.print((currently % 1000) / 100, DEC);
/*
slcd.print(" ");
slcd.print((long unsigned int)year(localTime), DEC);
slcd.print("-");
slcd.print((long unsigned int)month(localTime), DEC);
slcd.print("-");
slcd.print((long unsigned int)day(localTime), DEC);
*/
slcd.setCursor(0,0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment