PDA

View Full Version : GPS working!



kingforger
11-06-2012, 06:38 PM
I got this breakout to work with the Teensy3.0 via hardware serial: http://www.adafruit.com/products/746

I'm not sure what forum to post it under, so it's here. I'm just excited that it works and wanted to share!

First of all, I started out with the "parsing" example code that comes with that GPS. I commented out anything having to do with the interrupt because some things using the interrupt just weren't worknig. If you want to use that, I'm sorry but I have nothing for you. You don't need it though. Next, I removed any references to newsoftwareserial or softwareserial or anything that uses those files from both Adafruit_GPS.h and Adafruit_GPS.cpp and, of course, parsing.ino (the example file). This means that I was only using hardware serial. The Teensy 3.0 has 3 hardware serial ports, so who needs the softwareserial anyway?

I modified a particular line in the parsing example program to get rid of that UDR0 thing that wasn't working. The new line by itself is "if (c) Serial.print(c);". To show you some context, I have some code that surrounds it below:

char c = GPS.read();
// if you want to debug, this is a good time to do it!
if (GPSECHO)
if (c) Serial.print(c);
// writing direct to UDR0 is much much faster than Serial.print
// but only one character can be written at a time.

I also had to define the function itoa() with code that I found at www.jb.man.ac.uk/~slowe/cpp/itoa.html. Specifically, I used the char* version 0.4 code found at the bottom of that page, which is as follows:

/**
* C++ version 0.4 char* style "itoa":
* Written by Lukás Chmela
* Released under GPLv3.
*/
char* itoa(int value, char* result, int base) {
// check that the base if valid
if (base < 2 || base > 36) { *result = '\0'; return result; }

char* ptr = result, *ptr1 = result, tmp_char;
int tmp_value;

do {
tmp_value = value;
value /= base;
*ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcde fghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];
} while ( value );

// Apply negative sign
if (tmp_value < 0) *ptr++ = '-';
*ptr-- = '\0';
while(ptr1 < ptr) {
tmp_char = *ptr;
*ptr--= *ptr1;
*ptr1++ = tmp_char;
}
return result;
}

I just stuck that code right at the top of WString.cpp (which is found in arduino-1.0.1/hardware/teensy/cores/teensy3).

After that, it worked! My location is perfectly accurate, and everything else seems to be too. There was a lot of stuff I played around with and discovered before this stuff that I just told you about, but ultimately none of it is relevant if you just want to get the GPS working. So I think that's everything that I needed to do to make this particular GPS work.

If you have any questions, let me know. I'm just an analog/antenna/power electronics engineer, not really a software guy. So my knowledge of this software is limited. I can really just edit it, but could never write this stuff on my own from scratch.

edit: OH! I also had to edit two calls to isdigit and isalpha. I forget which file they were in. But I got an error saying that isAlpha and isDigit were not called in scope. There was a problem with case. I changed isDigit and isAlpha to isdigit and isalpha, and then there was no problem. I included #include <ctype.h> too in the parsing example main file. I'm not sure if you need this or not.

t3andy
11-06-2012, 07:59 PM
Could you post the Adafruit libraray and PDE fix. :D I have the same GPS on order but Sandy shutdown the power to Adafruit for five days.
I tried to compile the Adafruit library examples for the T3 and ran into the same problems. I showed it to Paul and this was his comments ...

Teensy 3 Adafruit Ultimate GPS Library Port

Adafruit makes the popular Ultimate GPS v3 breakout board.

I don't have the complete status of the progress in the Teensy 3 port development?
Attached is the Adafruit GPS library.

There are many compile errors in this Adafruit GPS library (in all library examples) porting to Teensy 3?


I took a quick look at this library. I'll be out of town for a few days, so I can't work on this more until next week. But here are my initial impressions.


First, there are a few missing functions I need to add, like isDigit and isAlpha. I'll add those next week.


Second, the examples default to SoftwareSerial, which isn't (yet) supported on Teensy 3.0. However, they also support using HardwareSerial, which is supported (and works so much better than software serial ever can). Here's the relevant lines from the "echo" example.

// If using hardware serial (e.g. Arduino Mega), comment
// out the above six lines and enable this line instead:
Adafruit_GPS GPS(&Serial1);


Like many libraries that take pointers to Serial or SoftwareSerial, this could be much simpler if it used the Arduino 1.0 Stream class. Maybe 1.0 is now well enough established for libraries like this to abandon 0023 support?


Third, while not a problem with the library itself, the examples have some very AVR-specific code that calls GPS.read().

// 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.
}

Even if you replace the direct write to UDR0 with Serial.write(c), using timer0 this way just isn't possible on Teensy 3.0. It also won't work on Arduino Due.

Sadly, the Arduino API doesn't provide anything like a timer event in a way that's portable. Maybe it should? I'm not sure if there is a good solution at this time. I'll copy Limor.

Long-term, I'm hoping to extend the Arduino API with a portable, cooperatively scheduled timer event API. In the short term, maybe there's some other hack that can get these examples working. For echo, that stuff in the interrupt could probably just move into loop() and be called every 1 ms. But the other examples have stuff in loop which presumably runs slower than GPS.read() needs to be called?


That's the best I can do right now... in the hours right before I need to leave. I'll be back next week, and this will be on my to-do list.

kingforger
11-06-2012, 08:44 PM
What does PDE stand for? I'm not sure what a PDE fix is.

I've uploaded the code of my modified parsing program example here, where it will be available for 2 weeks: http://jumpshare.com/b/877d8t
That code I just uploaded also turns the onboard LED on/off every time the GPS data is updated in the serial monitor.

Also, here are the modified Adafruit_GPS.h and Adafruit_GPS.cpp files: http://jumpshare.com/b/R7aaPZ

Again, available for two weeks.

I think that you only really need those 3 files. I made a few other edits in other files earlier, though I'm not sure that you need any of the edits that I made. Except of course for the edit that I gave you the details of in my first post.

t3andy
11-06-2012, 09:20 PM
What does PDE stand for? I'm not sure what a PDE fix is.

Its slang for an Arduino sketch file extension.

The examples in the Adafruit library, for instance, the "echo.pde" contains interrupts which are not done yet on the T3. And it contains other specific AVR Arduino specific timer interrupts references..
How did you make this example file compile and work with the "background" interrupts? Please inspect what Paul said (above)
Just state which library "examples" were you able to make work? (there are 7 example PDE's)

BTW ... Great work on the GPS library !

kingforger
11-06-2012, 09:35 PM
Oh, right.

"I commented out anything having to do with the interrupt". So I couldn't get it to compile with the interrupts. I just wanted it to work at all for now, and it does. I do not use interrupts.

The only example I've used was "parsing". I didn't care about the rest.

What Paul said seems to be right except for one thing... "First, there are a few missing functions I need to add, like isDigit and isAlpha. I'll add those next week.". isdigit and isalpha are indeed there, they're just lower case and in the file ctype.h. Hence, I changed the case to match and I no longer got that error. So I swapped isDigit and isAlpha with isdigit and isalpha.

t3andy
11-06-2012, 09:53 PM
echo.pde example demostrates Adafruit "background" streaming of NEMA data, so a user could do other important things while this streaming interrupt routine takes place. My second option was to discard this professional written library with parser and use the tinyGPS library which serially polls the NEMA data just like what you are doing with your modifications to the Adafruit library (parser.pde). Any how, you got the library to work partially - great!

el_supremo
01-22-2013, 01:53 AM
I've just got an Adafruit GPS (and the active antenna) and have it working with a Nano and now I want to get it going with the Teensy3.
How did you guys power the GPS when used with a T3?

Pete

t3andy
01-23-2013, 03:33 AM
I've just got an Adafruit GPS (and the active antenna) and have it working with a Nano and now I want to get it going with the Teensy3.
How did you guys power the GPS when used with a T3?


Adafruit made it so you can power it from +5VDC or 3.3 VDC - they use a LDO regulator for dual voltage use. Myself, I used 3.3 VDC and ground BUT be careful I believe the current draw is somewhat high and since you are using the sensitive, active, power hungry external antenna - the power draw is even greater. The T3 can only provide 100 ma. Also, I put a series current limit resistor of 1k in the Rx line for safety.

el_supremo
01-23-2013, 03:59 AM
Thanks t3andy. I've powered the GPS from 3xAA batteries and directly from the T3's 3V3 and it's still firing out NMEA without a hiccup. But good point about the extra juice for the active antenna. Adafruit says it draws 10ma so it shouldn't be a problem.

Pete

t3andy
01-23-2013, 04:13 AM
•MTK3339 Operating current: 25mA tracking, 20 mA current draw during navigation
This GPS antenna draws about 10mA.
35 total ma. + 27 T3 at idle = 62 ma.

Better have some extra batteries on hand.

ZTiK.nl
02-09-2013, 04:56 PM
I just received this GPS module in the mail today, but have not been able to get the code to compile properly.

I tried to follow your instructions, initially overlooking the final tip about isalpha and isdigit.
After this I still kept getting errors about SoftwareSerial.h not able to be included, so I uncommented both the includes in Adafruit_GPS.h.
Now it appears that I might have gone a step too far somewhere:

In file included from parsing.pde:14:0:
D:\arduino-1.0.3-1.12\libraries\Adafruit_GPS/Adafruit_GPS.h:81:14: error: 'uint16_t' has not been declared
D:\arduino-1.0.3-1.12\libraries\Adafruit_GPS/Adafruit_GPS.h:84:31: error: expected ')' before '*' token
D:\arduino-1.0.3-1.12\libraries\Adafruit_GPS/Adafruit_GPS.h:88:31: error: expected ')' before '*' token
D:\arduino-1.0.3-1.12\libraries\Adafruit_GPS/Adafruit_GPS.h:91:3: error: 'boolean' does not name a type
D:\arduino-1.0.3-1.12\libraries\Adafruit_GPS/Adafruit_GPS.h:94:14: error: 'boolean' has not been declared
D:\arduino-1.0.3-1.12\libraries\Adafruit_GPS/Adafruit_GPS.h:96:3: error: 'boolean' does not name a type
D:\arduino-1.0.3-1.12\libraries\Adafruit_GPS/Adafruit_GPS.h:97:3: error: 'uint8_t' does not name a type
D:\arduino-1.0.3-1.12\libraries\Adafruit_GPS/Adafruit_GPS.h:100:3: error: 'boolean' does not name a type
D:\arduino-1.0.3-1.12\libraries\Adafruit_GPS/Adafruit_GPS.h:101:23: error: 'boolean' has not been declared
D:\arduino-1.0.3-1.12\libraries\Adafruit_GPS/Adafruit_GPS.h:103:3: error: 'boolean' does not name a type
D:\arduino-1.0.3-1.12\libraries\Adafruit_GPS/Adafruit_GPS.h:104:2: error: 'boolean' does not name a type
D:\arduino-1.0.3-1.12\libraries\Adafruit_GPS/Adafruit_GPS.h:106:3: error: 'uint8_t' does not name a type
D:\arduino-1.0.3-1.12\libraries\Adafruit_GPS/Adafruit_GPS.h:107:3: error: 'uint16_t' does not name a type
D:\arduino-1.0.3-1.12\libraries\Adafruit_GPS/Adafruit_GPS.h:111:3: error: 'boolean' does not name a type
D:\arduino-1.0.3-1.12\libraries\Adafruit_GPS/Adafruit_GPS.h:112:3: error: 'uint8_t' does not name a type
D:\arduino-1.0.3-1.12\libraries\Adafruit_GPS/Adafruit_GPS.h:114:3: error: 'boolean' does not name a type
D:\arduino-1.0.3-1.12\libraries\Adafruit_GPS/Adafruit_GPS.h:115:3: error: 'boolean' does not name a type
D:\arduino-1.0.3-1.12\libraries\Adafruit_GPS/Adafruit_GPS.h:116:3: error: 'boolean' does not name a type
D:\arduino-1.0.3-1.12\libraries\Adafruit_GPS/Adafruit_GPS.h:118:3: error: 'uint16_t' does not name a type
D:\arduino-1.0.3-1.12\libraries\Adafruit_GPS/Adafruit_GPS.h:119:3: error: 'uint8_t' does not name a type
D:\arduino-1.0.3-1.12\libraries\Adafruit_GPS/Adafruit_GPS.h:121:3: error: 'boolean' does not name a type
D:\arduino-1.0.3-1.12\libraries\Adafruit_GPS/Adafruit_GPS.h:123:3: error: 'uint8_t' does not name a type
D:\arduino-1.0.3-1.12\libraries\Adafruit_GPS/Adafruit_GPS.h:125:3: error: 'SoftwareSerial' does not name a type
D:\arduino-1.0.3-1.12\libraries\Adafruit_GPS/Adafruit_GPS.h:129:3: error: 'HardwareSerial' does not name a type
parsing.pde:43:26: error: no matching function for call to 'Adafruit_GPS::Adafruit_GPS(HardwareSerial*)'
parsing.pde:43:26: note: candidates are:
In file included from parsing.pde:14:0:
D:\arduino-1.0.3-1.12\libraries\Adafruit_GPS/Adafruit_GPS.h:79:7: note: Adafruit_GPS::Adafruit_GPS()
D:\arduino-1.0.3-1.12\libraries\Adafruit_GPS/Adafruit_GPS.h:79:7: note: candidate expects 0 arguments, 1 provided
D:\arduino-1.0.3-1.12\libraries\Adafruit_GPS/Adafruit_GPS.h:79:7: note: constexpr Adafruit_GPS::Adafruit_GPS(const Adafruit_GPS&)
D:\arduino-1.0.3-1.12\libraries\Adafruit_GPS/Adafruit_GPS.h:79:7: note: no known conversion for argument 1 from 'HardwareSerial*' to 'const Adafruit_GPS&'
D:\arduino-1.0.3-1.12\libraries\Adafruit_GPS/Adafruit_GPS.h:79:7: note: constexpr Adafruit_GPS::Adafruit_GPS(Adafruit_GPS&&)
D:\arduino-1.0.3-1.12\libraries\Adafruit_GPS/Adafruit_GPS.h:79:7: note: no known conversion for argument 1 from 'HardwareSerial*' to 'Adafruit_GPS&&'
parsing.pde: In function 'void loop()':
parsing.pde:98:11: error: 'class Adafruit_GPS' has no member named 'newNMEAreceived'
parsing.pde:104:14: error: 'class Adafruit_GPS' has no member named 'parse'
parsing.pde:116:22: error: 'class Adafruit_GPS' has no member named 'hour'
parsing.pde:117:22: error: 'class Adafruit_GPS' has no member named 'minute'
parsing.pde:118:22: error: 'class Adafruit_GPS' has no member named 'seconds'
parsing.pde:119:24: error: 'class Adafruit_GPS' has no member named 'milliseconds'
parsing.pde:121:22: error: 'class Adafruit_GPS' has no member named 'day'
parsing.pde:122:22: error: 'class Adafruit_GPS' has no member named 'month'
parsing.pde:123:24: error: 'class Adafruit_GPS' has no member named 'year'
parsing.pde:124:50: error: 'class Adafruit_GPS' has no member named 'fix'
parsing.pde:125:57: error: 'class Adafruit_GPS' has no member named 'fixquality'
parsing.pde:126:13: error: 'class Adafruit_GPS' has no member named 'fix'
parsing.pde:135:61: error: 'class Adafruit_GPS' has no member named 'satellites'

Did I miss something along the way?
Is it possible to upload your library somewhere again?

Ow, I have included/excluded '#include <ctype.h>' in my parsing.ino but I have noticed no difference, seems it is not required.
Then again, my code doesn't work yet, so I'll get back on that when it does ;)

ZTiK.nl
02-09-2013, 04:59 PM
By the way, thanks for sharing your info, this would have taken me weeks probably!

ZTiK.nl
02-09-2013, 05:56 PM
Wow, never mind... seems I indeed commented out a bit too much, didnt notice it wasn't related to softserial..

code compiles perfectly now:

Time: 17:54:23.0
Date: 9/2/2013
Fix: 0 quality: 0
$PGTOP,11,2*6E
$GPGGA,175424.000,,,,,0,3,,,M,,M,,*4A
$GPRMC,175424.000,V,,,,,3.27,74.87,090213,,,N*7F
$PGTOP,11,2*6E
$GPGGA,175425.000,,,,,0,3,,,M,,M,,*4B
$GPRMC,175425.000,V,,,,,3.44,75.45,090213,,,N*74

Thanks a million!

ZTiK.nl
02-09-2013, 06:01 PM
And one with accurate positioning:

Time: 17:59:9.0
Date: 9/2/2013
Fix: 1 quality: 1
Location: 5230.4160N, 458.8786E
Speed (knots): 0.65
Angle: 136.93
Altitude: -48.30
Satellites: 4
$PGTOP,11,2*6E
$GPGGA,175910.000,,,,,0,4,,,M,,M,,*47
$GPRMC,175910.000,V,,,,,0.66,135.76,090213,,,N*49
$PGTOP,11,2*6E
$GPGGA,175911.000,,,,,0,4,,,M,,M,,*46
$GPRMC,175911.000,V,,,,,0.67,135.13,090213,,,N*4A

... This is +/- 7 meters from where I am sitting now according to google maps :P

ians
07-12-2013, 05:32 AM
Hi all,
i got the Ultimate GPS working on the T3 as well. After removing the softwareserial code, it wasn't working for me initially. Later, i realized that if i ran Serial2.begin(9600) before the GPS.begin it would work.

As a bonus, declare PMTK... to get GGA output only:


#define PMTK_SET_NMEA_OUTPUT_GGAONLY "$PMTK314,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_GGAONLY);

stevech
07-12-2013, 10:58 PM
The default GPS receiver serial data rate is 4800baud - per the NMEA standard.
The standard lacks a way to change the baud rate config.. you have to use a vendor specific method.

ians
07-12-2013, 11:59 PM
The default GPS receiver serial data rate is 4800baud - per the NMEA standard.
The standard lacks a way to change the baud rate config.. you have to use a vendor specific method.

hm thats strange... The ultimate gps demo sketches use 9600baud. At any rate, its been running at 9600 on my mini pro for months.

stevech
07-13-2013, 12:07 AM
yeah, that 4800baud standard in NMEA dates back to the late 80's I think.
Today vendors may not stick to it as the default.

keeb
12-19-2013, 06:43 PM
I've been trying to get my adafruit ultimate V3 gps working with my teensy3 for hours now, and I've reached the end of my limited skills. I've tried to follow the instructions above to edit the adafruit parsing sketch, and can get the sketch to compile and load on the teensy, but I get nothing printed to the serial monitor. I know my gps works because I have a working sketch on my UNO R3. I'm an ME just starting out with this whole micro controller business, and software stuff is not my strong point...(yet!). If somebody could post some working sketches and accompanying libraries, or point me in the right direction with my sketch below, I'd be grateful. My motorcycle will be grateful to, since this will become a more accurate speedometer once it is all working.

At one point I had the serial monitor spitting out the info from these lines...

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);

...but i was just getting zeros instead of useful information. I changed something else (can't remember what), and now nothing at all in my serial monitor.


#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
#include <ctype.h>

// 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 these lines enabled
// (you can change the pin numbers to match your wiring):
//SoftwareSerial mySerial(3, 2);

//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(&Serial1);


// 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
Serial1.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);

// 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!
//useInterrupt(true);

delay(1000);
// Ask for firmware version
Serial.println(PMTK_Q_RELEASE);
}


// 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) Serial.print(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;
}
}
*/
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 > 1000) {
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 (MPH): ");
Serial.println(GPS.speed);
Serial.print("Angle: ");
Serial.println(GPS.angle);
Serial.print("Altitude (Ft): ");
Serial.println(GPS.altitude);
Serial.print("Satellites: ");
Serial.println((int)GPS.satellites);

}
}
}


Oh yeah, I've tried to get the tinyGPS sketch working from the tutorial in the teensyduino libraries, but have had no luck. --> http://www.pjrc.com/teensy/td_libs_TinyGPS.html

el_supremo
12-19-2013, 07:13 PM
This doesn't look right:

Serial1.begin(115200);
Serial.println("Adafruit GPS library basic test!");

I think the Serial1 should be Serial.

Pete

PaulStoffregen
12-19-2013, 07:21 PM
First, please make sure you're running the latest Teensyduino, either 1.17 or 1.18-rc1 (needed for Teensy 3.1). It's ok to download the installer and just install into the same Arduino 1.0.5 you're using now.

This is important, because a bug was fixed where certain hardware serial functions weren't "virtual" to allow their use in libraries like this. So before you send even one more frustrating minute, please install the latest version. It might make things "just work".

keeb
12-19-2013, 08:00 PM
This doesn't look right:

Serial1.begin(115200);
Serial.println("Adafruit GPS library basic test!");

I think the Serial1 should be Serial.

Pete

Fixed


irst, please make sure you're running the latest Teensyduino, either 1.17 or 1.18-rc1 (needed for Teensy 3.1).
I installed Teensyduino 1.17 just before starting this project. It is running on Mac OS 10.8.5

Thanks for the input. I feel like I'm close to getting this to work, but I just don't know enough about the software side of things to be confident in my rampant commenting out of stuff in the .ino and the .h and the .cpp.

PaulStoffregen
12-19-2013, 08:26 PM
This code really looks like it should work.

Can you check which pins you've connected? A photo might help us see any possible wiring issue, if you can post one?

el_supremo
12-19-2013, 09:50 PM
//SIGNAL(TIMER0_COMPA_vect) {
char c = GPS.read();

This will declare a global "c" which might cause confusion with the local "c" in the loop function. If you aren't going to use SIGNAL it would be best to use a /*...*/ comment around the whole thing as was done with useInterrupt.

Pete

keeb
12-19-2013, 09:56 PM
Can post a photo later, but here's how it is wired:

GPS RX = teensy pin 0
GPS TX = teensy pin 1
GPS gnd = teensy gnd (The one by pin 0)
GPS vin = teensy 3.3V (pin directly across from pin 1)

I've double checked the RX and TX connections about a dozen times, so I'm confident they aren't Mixed up.

keeb
12-20-2013, 04:15 AM
How it's wired up...
1235

I commented out the "char c = gps.read()" line as suggested by Pete. (I now recall that earlier I had the whole thing commented out because now I'm back to what's shown below. I'm getting everything before the "if gps.fix" line, but nothing printed to the serial monitor after that. I was worried that I'd mucked up my library files by poking around them, so I replaced them with fresh copies. The only thing I changed was the case for the "isDigit" and "isAlpha" lines, so that the sketch would compile. Now I just get this. It is like the teensy just never gets the NMEA data from the gps, but I'm at a loss why not. Is there a very simple way to just print the raw data from the module, to see if I can get that far? The adafruit library contains a "blank" sketch for this purpose that just bypasses everything let the serial monitor print whatever comes its way. What would be the teensy version of this?


$PMTK605*31

Time: 0:0:0.0
Date: 0/0/200
Fix: 0 quality: 0

Time: 0:0:0.0
Date: 0/0/200
Fix: 0 quality: 0

Time: 0:0:0.0
Date: 0/0/200
Fix: 0 quality: 0

Time: 0:0:0.0
Date: 0/0/200
Fix: 0 quality: 0


adafruit "Blank" sketch for viewing raw gps data over serial (can I do something similar on Teensy to test?):

// this sketch will allow you to bypass the Atmega chip
// and connect the GPS sensor directly to the USB/Serial
// chip converter.

// Connect VIN to +5V
// Connect GND to Ground
// Connect GPS RX (data into GPS) to Digital 0
// Connect GPS TX (data out from GPS) to Digital 1

void setup() {}
void loop() {}

PaulStoffregen
12-20-2013, 07:54 AM
That photos really helps! I believe you need to swap the 2 signal wires. You've got RX from Adafruit's GPS connected to RX on the Teensy3, and likewise TX connected to TX.

What you really need is TX from one connected to RX on the other, and vice verse, so each side transmits to the pin where the other side is trying to receive.

PaulStoffregen
12-20-2013, 08:21 AM
Also, it looks like you've got VIN on Adafruit's GPS connected to 3.3V on Teensy3. That might work fine, and it's probably the safest way to use this. Adafruit claims this thing works down to 3.0 volts.

It looks like they put a 3.3 volt regulator on the board, meant to create 3.3V from 5.0V. You might check the 3.3V pin to see what voltage the GPS is actually getting from its own regulator. If it's lower than 3.0V, you might need to connect VIN to Teensy3's VIN or VUSB pin.

But swap those signal wires first. That will probably solve all your troubles.

keeb
12-20-2013, 10:26 PM
Thanks so much for the help. It works just fine now after switching the serial receive and transmit wires as Paul suggested. I'm gonna chalk this one up to being a complete noob. Just in case anybody else stumbles across this thread in need of help, here's what finally worked for me.

Edited the Adafruit_gps.cpp files as follows:

char c = response[0];
if (isdigit(c)) //changed from isDigit
parsed[i] += c - '0';
else
parsed[i] = c;
response++;

LOCUS_serial = parsed[0];
LOCUS_type = parsed[1];
if (isalpha(parsed[2])) { //changed from isAlpha
parsed[2] = parsed[2] - 'a' + 10;

(I also changed altitude from meters to feet, and speed from knots to mph by multiplying the respective variables by the appropriate conversion factors.)

The modified adafruit parsing sketch:

// 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 <Adafruit_GPS.h>
#include <SoftwareSerial.h>


// 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 these lines enabled
// (you can change the pin numbers to match your wiring):
//SoftwareSerial mySerial(3, 2);

//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(&Serial1);


// 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);

// 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!
//useInterrupt(true);

delay(1000);
// Ask for firmware version
//Serial.println(PMTK_Q_RELEASE);
}


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 > 1000) {
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 (MPH): ");
Serial.println(GPS.speed);
Serial.print("Angle: ");
Serial.println(GPS.angle);
Serial.print("Altitude (Ft): ");
Serial.println(GPS.altitude);
Serial.print("Satellites: ");
Serial.println((int)GPS.satellites);

}
}
}