/* USB Host to PL2303-based USB GPS unit interface */ /* Navibee GM720 receiver - Sirf Star III */ /* Mikal Hart's TinyGPS library */ /* test_with_gps_device library example modified for PL2302 access */ /* USB support */ #include <usbhub.h> /* CDC support */ #include <cdcacm.h> #include <cdcprolific.h> #include <TinyGPS.h> // Satisfy the IDE, which needs to see the include statment in the ino too. #ifdef dobogusinclude #include <spi4teensy3.h> #include <SPI.h> #endif /* This sample code demonstrates the normal use of a TinyGPS object. Modified to be used with USB Host Shield Library r2.0 and USB Host Shield 2.0 */ class PLAsyncOper : public CDCAsyncOper { public: uint8_t OnInit(ACM *pacm); }; uint8_t PLAsyncOper::OnInit(ACM *pacm) { uint8_t rcode; // Set DTR = 1 rcode = pacm->SetControlLineState(1); if (rcode) { ErrorMessage<uint8_t>(PSTR("SetControlLineState"), rcode); return rcode; } LINE_CODING lc; lc.dwDTERate = 4800; //default serial speed of GPS unit lc.bCharFormat = 0; lc.bParityType = 0; lc.bDataBits = 8; rcode = pacm->SetLineCoding(&lc); if (rcode) { ErrorMessage<uint8_t>(PSTR("SetLineCoding"), rcode); } return rcode; } USB Usb; //USBHub Hub(&Usb); PLAsyncOper AsyncOper; PL2303 Pl(&Usb, &AsyncOper); TinyGPS gps; void gpsdump(TinyGPS &gps); bool feedgps(); void printFloat(double f, int digits = 2); void setup() { Serial.begin(115200); #if !defined(__MIPSEL__) while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection #endif Serial.print("Testing TinyGPS library v. "); Serial.println(TinyGPS::library_version()); Serial.println("by Mikal Hart"); Serial.println(); Serial.print("Sizeof(gpsobject) = "); Serial.println(sizeof(TinyGPS)); Serial.println(); /* USB Initialization */ if (Usb.Init() == -1) { Serial.println("OSCOKIRQ failed to assert"); } delay( 200 ); } void loop() { Usb.Task(); if( Pl.isReady()) { bool newdata = false; unsigned long start = millis(); // Every 5 seconds we print an update while (millis() - start < 5000) { if( feedgps()) { newdata = true; } }//while (millis()... if (newdata) { Serial.println("Acquired Data"); Serial.println("-------------"); gpsdump(gps); Serial.println("-------------"); Serial.println(); }//if( newdata... }//if( Usb.getUsbTaskState() == USB_STATE_RUNNING... } void printFloat(double number, int digits) { // Handle negative numbers if (number < 0.0) { Serial.print('-'); number = -number; } // Round correctly so that print(1.999, 2) prints as "2.00" double rounding = 0.5; for (uint8_t i=0; i<digits; ++i) rounding /= 10.0; number += rounding; // Extract the integer part of the number and print it unsigned long int_part = (unsigned long)number; double remainder = number - (double)int_part; Serial.print(int_part); // Print the decimal point, but only if there are digits beyond if (digits > 0) Serial.print("."); // Extract digits from the remainder one at a time while (digits-- > 0) { remainder *= 10.0; int toPrint = int(remainder); Serial.print(toPrint); remainder -= toPrint; } } void gpsdump(TinyGPS &gps) { long lat, lon; float flat, flon; unsigned long age, date, time, chars; int year; byte month, day, hour, minute, second, hundredths; unsigned short sentences, failed; gps.get_position(&lat, &lon, &age); Serial.print("Lat/Long(10^-5 deg): "); Serial.print(lat); Serial.print(", "); Serial.print(lon); Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms."); feedgps(); // If we don't feed the gps during this long routine, we may drop characters and get checksum errors gps.f_get_position(&flat, &flon, &age); Serial.print("Lat/Long(float): "); printFloat(flat, 5); Serial.print(", "); printFloat(flon, 5); Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms."); feedgps(); gps.get_datetime(&date, &time, &age); Serial.print("Date(ddmmyy): "); Serial.print(date); Serial.print(" Time(hhmmsscc): "); Serial.print(time); Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms."); feedgps(); gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age); Serial.print("Date: "); Serial.print(static_cast<int>(month)); Serial.print("/"); Serial.print(static_cast<int>(day)); Serial.print("/"); Serial.print(year); Serial.print(" Time: "); Serial.print(static_cast<int>(hour)); Serial.print(":"); Serial.print(static_cast<int>(minute)); Serial.print(":"); Serial.print(static_cast<int>(second)); Serial.print("."); Serial.print(static_cast<int>(hundredths)); Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms."); feedgps(); Serial.print("Alt(cm): "); Serial.print(gps.altitude()); Serial.print(" Course(10^-2 deg): "); Serial.print(gps.course()); Serial.print(" Speed(10^-2 knots): "); Serial.println(gps.speed()); Serial.print("Alt(float): "); printFloat(gps.f_altitude()); Serial.print(" Course(float): "); printFloat(gps.f_course()); Serial.println(); Serial.print("Speed(knots): "); printFloat(gps.f_speed_knots()); Serial.print(" (mph): "); printFloat(gps.f_speed_mph()); Serial.print(" (mps): "); printFloat(gps.f_speed_mps()); Serial.print(" (kmph): "); printFloat(gps.f_speed_kmph()); Serial.println(); feedgps(); gps.stats(&chars, &sentences, &failed); Serial.print("Stats: characters: "); Serial.print(chars); Serial.print(" sentences: "); Serial.print(sentences); Serial.print(" failed checksum: "); Serial.println(failed); } bool feedgps() { uint8_t rcode; uint8_t buf[64]; //serial buffer equals Max.packet size of bulk-IN endpoint uint16_t rcvd = 64; { /* reading the GPS */ rcode = Pl.RcvData(&rcvd, buf); if (rcode && rcode != hrNAK) ErrorMessage<uint8_t>(PSTR("Ret"), rcode); rcode = false; if( rcvd ) { //more than zero bytes received for( uint16_t i=0; i < rcvd; i++ ) { if( gps.encode((char)buf[i])) { //feed a character to gps object rcode = true; }//if( gps.encode(buf[i]... }//for( uint16_t i=0; i < rcvd; i++... }//if( rcvd... } return( rcode ); }