diff --git a/Adafruit_GPS.cpp b/Adafruit_GPS.cpp index 65b8b1e..5a68d26 100644 --- a/Adafruit_GPS.cpp +++ b/Adafruit_GPS.cpp @@ -164,10 +164,13 @@ char Adafruit_GPS::read(void) { if (paused) return c; +#ifdef __AVR__ if(gpsSwSerial) { if(!gpsSwSerial->available()) return c; c = gpsSwSerial->read(); - } else { + } else +#endif + { if(!gpsHwSerial->available()) return c; c = gpsHwSerial->read(); } @@ -203,6 +206,7 @@ char Adafruit_GPS::read(void) { return c; } +#ifdef __AVR__ // Constructor when using SoftwareSerial or NewSoftSerial #if ARDUINO >= 100 Adafruit_GPS::Adafruit_GPS(SoftwareSerial *ser) @@ -213,6 +217,7 @@ Adafruit_GPS::Adafruit_GPS(NewSoftSerial *ser) common_init(); // Set everything to common state, then... gpsSwSerial = ser; // ...override gpsSwSerial with value passed. } +#endif // Constructor when using HardwareSerial Adafruit_GPS::Adafruit_GPS(HardwareSerial *ser) { @@ -222,7 +227,9 @@ Adafruit_GPS::Adafruit_GPS(HardwareSerial *ser) { // Initialization code used by all constructor types void Adafruit_GPS::common_init(void) { +#ifdef __AVR__ gpsSwSerial = NULL; // Set both to NULL, then override correct +#endif gpsHwSerial = NULL; // port pointer in corresponding constructor recvdflag = false; paused = false; @@ -241,15 +248,23 @@ void Adafruit_GPS::common_init(void) { void Adafruit_GPS::begin(uint16_t baud) { - if(gpsSwSerial) gpsSwSerial->begin(baud); - else gpsHwSerial->begin(baud); +#ifdef __AVR__ + if(gpsSwSerial) + gpsSwSerial->begin(baud); + else + gpsHwSerial->begin(baud); +#endif delay(10); } void Adafruit_GPS::sendCommand(char *str) { - if(gpsSwSerial) gpsSwSerial->println(str); - else gpsHwSerial->println(str); +#ifdef __AVR__ + if(gpsSwSerial) + gpsSwSerial->println(str); + else +#endif + gpsHwSerial->println(str); } boolean Adafruit_GPS::newNMEAreceived(void) { diff --git a/Adafruit_GPS.h b/Adafruit_GPS.h index a2c968b..231f009 100644 --- a/Adafruit_GPS.h +++ b/Adafruit_GPS.h @@ -20,10 +20,12 @@ All text above must be included in any redistribution #ifndef _ADAFRUIT_GPS_H #define _ADAFRUIT_GPS_H -#if ARDUINO >= 100 - #include -#else - #include +#ifdef __AVR__ + #if ARDUINO >= 100 + #include + #else + #include + #endif #endif // different commands to set the update rate from once a second (1 Hz) to 10 times a second (10Hz) @@ -71,7 +73,7 @@ All text above must be included in any redistribution #if ARDUINO >= 100 #include "Arduino.h" -#if !defined(__AVR_ATmega32U4__) +#if defined (__AVR__) && !defined(__AVR_ATmega32U4__) #include "SoftwareSerial.h" #endif #else @@ -84,10 +86,12 @@ class Adafruit_GPS { public: void begin(uint16_t baud); -#if ARDUINO >= 100 - Adafruit_GPS(SoftwareSerial *ser); // Constructor when using SoftwareSerial -#else - Adafruit_GPS(NewSoftSerial *ser); // Constructor when using NewSoftSerial +#ifdef __AVR__ + #if ARDUINO >= 100 + Adafruit_GPS(SoftwareSerial *ser); // Constructor when using SoftwareSerial + #else + Adafruit_GPS(NewSoftSerial *ser); // Constructor when using NewSoftSerial + #endif #endif Adafruit_GPS(HardwareSerial *ser); // Constructor when using HardwareSerial @@ -105,7 +109,7 @@ class Adafruit_GPS { void interruptReads(boolean r); boolean wakeup(void); - boolean standby(void); + boolean standby(void); uint8_t hour, minute, seconds, year, month, day; uint16_t milliseconds; @@ -125,10 +129,12 @@ class Adafruit_GPS { boolean paused; uint8_t parseResponse(char *response); -#if ARDUINO >= 100 - SoftwareSerial *gpsSwSerial; -#else - NewSoftSerial *gpsSwSerial; +#ifdef __AVR__ + #if ARDUINO >= 100 + SoftwareSerial *gpsSwSerial; + #else + NewSoftSerial *gpsSwSerial; + #endif #endif HardwareSerial *gpsHwSerial; }; diff --git a/examples/due_parsing/due_parsing.ino b/examples/due_parsing/due_parsing.ino new file mode 100644 index 0000000..a1e9ea5 --- /dev/null +++ b/examples/due_parsing/due_parsing.ino @@ -0,0 +1,178 @@ +// Test code for Adafruit GPS modules using MTK3329/MTK3339 driver +// +// This code shows how to listen to the GPS module in an interrupt +// which allows the program to have more 'freedom' - just parse +// when a new NMEA sentence is available! Then access data when +// desired. +// +// 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 + +#ifdef __AVR__ + #include +#endif + +// If you're using a GPS module: +// 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 you're using the Adafruit GPS shield, change +// SoftwareSerial mySerial(3, 2); -> SoftwareSerial mySerial(8, 7); +// and make sure the switch is set to SoftSerial + +// If using software serial, keep this line enabled +// (you can change the pin numbers to match your wiring): +//SoftwareSerial mySerial(3, 2); + +// If using hardware serial (e.g. Arduino Mega, Leonardo, Due), comment +// out the above line and enable this line instead: +#define mySerial Serial1 + +Adafruit_GPS GPS(&mySerial); + + +// 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 + +void setup() +{ + + // connect at 115200 so we can read the GPS fast enough and echo without dropping chars + // also spit it out + Serial.begin(115200); + Serial.println("Adafruit GPS library basic test!"); + + // 9600 NMEA is the default baud rate for Adafruit MTK GPS's- some use 4800 + GPS.begin(9600); + mySerial.begin(9600); + + // 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 + //GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY); + // For parsing data, we don't suggest using anything but either RMC only or RMC+GGA since + // the parser doesn't care about other sentences at this time + + // Set the update rate + GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // 1 Hz update rate + // For the parsing code to work nicely and have time to sort thru the data, and + // print it out we don't suggest using anything higher than 1 Hz + + // 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! + +#ifdef __arm__ + usingInterrupt = false; //NOTE - we don't want to use interrupts on the Due +#else + useInterrupt(true); +#endif + + delay(1000); + // Ask for firmware version + mySerial.println(PMTK_Q_RELEASE); +} + +#ifdef __AVR__ +// 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! +#ifdef UDR0 + 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. +#endif +} + +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; + } +} +#endif //#ifdef__AVR__ + +uint32_t timer = millis(); +void loop() // run over and over again +{ + // in case you are not using the interrupt above, you'll + // need to 'hand query' the GPS, not suggested :( + if (! usingInterrupt) { + // read data from the GPS in the 'main loop' + char c = GPS.read(); + // if you want to debug, this is a good time to do it! + if (GPSECHO) + if (c) Serial.print(c); + } + + // if a sentence is received, we can check the checksum, parse it... + if (GPS.newNMEAreceived()) { + // a tricky thing here is if we print the NMEA sentence, or data + // we end up not listening and catching other sentences! + // so be very wary if using OUTPUT_ALLDATA and trytng to print out data + //Serial.println(GPS.lastNMEA()); // this also sets the newNMEAreceived() flag to false + + if (!GPS.parse(GPS.lastNMEA())) // this also sets the newNMEAreceived() flag to false + return; // we can fail to parse a sentence in which case we should just wait for another + } + + // if millis() or timer wraps around, we'll just reset it + if (timer > millis()) timer = millis(); + + // approximately every 2 seconds or so, print out the current stats + if (millis() - timer > 2000) { + timer = millis(); // reset the timer + + Serial.print("\nTime: "); + Serial.print(GPS.hour, DEC); Serial.print(':'); + Serial.print(GPS.minute, DEC); Serial.print(':'); + Serial.print(GPS.seconds, DEC); Serial.print('.'); + Serial.println(GPS.milliseconds); + Serial.print("Date: "); + Serial.print(GPS.day, DEC); Serial.print('/'); + Serial.print(GPS.month, DEC); Serial.print("/20"); + Serial.println(GPS.year, DEC); + Serial.print("Fix: "); Serial.print((int)GPS.fix); + Serial.print(" quality: "); Serial.println((int)GPS.fixquality); + if (GPS.fix) { + Serial.print("Location: "); + Serial.print(GPS.latitude, 4); Serial.print(GPS.lat); + Serial.print(", "); + Serial.print(GPS.longitude, 4); Serial.println(GPS.lon); + + Serial.print("Speed (knots): "); Serial.println(GPS.speed); + Serial.print("Angle: "); Serial.println(GPS.angle); + Serial.print("Altitude: "); Serial.println(GPS.altitude); + Serial.print("Satellites: "); Serial.println((int)GPS.satellites); + } + } +}