You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

pl2303_tinygps.ino 6.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /* USB Host to PL2303-based USB GPS unit interface */
  2. /* Navibee GM720 receiver - Sirf Star III */
  3. /* Mikal Hart's TinyGPS library */
  4. /* test_with_gps_device library example modified for PL2302 access */
  5. /* USB support */
  6. #include <usbhub.h>
  7. /* CDC support */
  8. #include <cdcacm.h>
  9. #include <cdcprolific.h>
  10. #include <TinyGPS.h>
  11. // Satisfy the IDE, which needs to see the include statment in the ino too.
  12. #ifdef dobogusinclude
  13. #include <spi4teensy3.h>
  14. #include <SPI.h>
  15. #endif
  16. /* This sample code demonstrates the normal use of a TinyGPS object.
  17. Modified to be used with USB Host Shield Library r2.0
  18. and USB Host Shield 2.0
  19. */
  20. class PLAsyncOper : public CDCAsyncOper
  21. {
  22. public:
  23. uint8_t OnInit(ACM *pacm);
  24. };
  25. uint8_t PLAsyncOper::OnInit(ACM *pacm)
  26. {
  27. uint8_t rcode;
  28. // Set DTR = 1
  29. rcode = pacm->SetControlLineState(1);
  30. if (rcode) {
  31. ErrorMessage<uint8_t>(PSTR("SetControlLineState"), rcode);
  32. return rcode;
  33. }
  34. LINE_CODING lc;
  35. lc.dwDTERate = 4800; //default serial speed of GPS unit
  36. lc.bCharFormat = 0;
  37. lc.bParityType = 0;
  38. lc.bDataBits = 8;
  39. rcode = pacm->SetLineCoding(&lc);
  40. if (rcode) {
  41. ErrorMessage<uint8_t>(PSTR("SetLineCoding"), rcode);
  42. }
  43. return rcode;
  44. }
  45. USB Usb;
  46. //USBHub Hub(&Usb);
  47. PLAsyncOper AsyncOper;
  48. PL2303 Pl(&Usb, &AsyncOper);
  49. TinyGPS gps;
  50. void gpsdump(TinyGPS &gps);
  51. bool feedgps();
  52. void printFloat(double f, int digits = 2);
  53. void setup()
  54. {
  55. Serial.begin(115200);
  56. #if !defined(__MIPSEL__)
  57. while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
  58. #endif
  59. Serial.print("Testing TinyGPS library v. "); Serial.println(TinyGPS::library_version());
  60. Serial.println("by Mikal Hart");
  61. Serial.println();
  62. Serial.print("Sizeof(gpsobject) = "); Serial.println(sizeof(TinyGPS));
  63. Serial.println();
  64. /* USB Initialization */
  65. if (Usb.Init() == -1) {
  66. Serial.println("OSCOKIRQ failed to assert");
  67. }
  68. delay( 200 );
  69. }
  70. void loop()
  71. {
  72. Usb.Task();
  73. if( Pl.isReady()) {
  74. bool newdata = false;
  75. unsigned long start = millis();
  76. // Every 5 seconds we print an update
  77. while (millis() - start < 5000) {
  78. if( feedgps()) {
  79. newdata = true;
  80. }
  81. }//while (millis()...
  82. if (newdata) {
  83. Serial.println("Acquired Data");
  84. Serial.println("-------------");
  85. gpsdump(gps);
  86. Serial.println("-------------");
  87. Serial.println();
  88. }//if( newdata...
  89. }//if( Usb.getUsbTaskState() == USB_STATE_RUNNING...
  90. }
  91. void printFloat(double number, int digits)
  92. {
  93. // Handle negative numbers
  94. if (number < 0.0)
  95. {
  96. Serial.print('-');
  97. number = -number;
  98. }
  99. // Round correctly so that print(1.999, 2) prints as "2.00"
  100. double rounding = 0.5;
  101. for (uint8_t i=0; i<digits; ++i)
  102. rounding /= 10.0;
  103. number += rounding;
  104. // Extract the integer part of the number and print it
  105. unsigned long int_part = (unsigned long)number;
  106. double remainder = number - (double)int_part;
  107. Serial.print(int_part);
  108. // Print the decimal point, but only if there are digits beyond
  109. if (digits > 0)
  110. Serial.print(".");
  111. // Extract digits from the remainder one at a time
  112. while (digits-- > 0)
  113. {
  114. remainder *= 10.0;
  115. int toPrint = int(remainder);
  116. Serial.print(toPrint);
  117. remainder -= toPrint;
  118. }
  119. }
  120. void gpsdump(TinyGPS &gps)
  121. {
  122. long lat, lon;
  123. float flat, flon;
  124. unsigned long age, date, time, chars;
  125. int year;
  126. byte month, day, hour, minute, second, hundredths;
  127. unsigned short sentences, failed;
  128. gps.get_position(&lat, &lon, &age);
  129. Serial.print("Lat/Long(10^-5 deg): "); Serial.print(lat); Serial.print(", "); Serial.print(lon);
  130. Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms.");
  131. feedgps(); // If we don't feed the gps during this long routine, we may drop characters and get checksum errors
  132. gps.f_get_position(&flat, &flon, &age);
  133. Serial.print("Lat/Long(float): "); printFloat(flat, 5); Serial.print(", "); printFloat(flon, 5);
  134. Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms.");
  135. feedgps();
  136. gps.get_datetime(&date, &time, &age);
  137. Serial.print("Date(ddmmyy): "); Serial.print(date); Serial.print(" Time(hhmmsscc): "); Serial.print(time);
  138. Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms.");
  139. feedgps();
  140. gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  141. Serial.print("Date: "); Serial.print(static_cast<int>(month)); Serial.print("/"); Serial.print(static_cast<int>(day)); Serial.print("/"); Serial.print(year);
  142. 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));
  143. Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms.");
  144. feedgps();
  145. 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());
  146. Serial.print("Alt(float): "); printFloat(gps.f_altitude()); Serial.print(" Course(float): "); printFloat(gps.f_course()); Serial.println();
  147. Serial.print("Speed(knots): "); printFloat(gps.f_speed_knots()); Serial.print(" (mph): "); printFloat(gps.f_speed_mph());
  148. Serial.print(" (mps): "); printFloat(gps.f_speed_mps()); Serial.print(" (kmph): "); printFloat(gps.f_speed_kmph()); Serial.println();
  149. feedgps();
  150. gps.stats(&chars, &sentences, &failed);
  151. Serial.print("Stats: characters: "); Serial.print(chars); Serial.print(" sentences: "); Serial.print(sentences); Serial.print(" failed checksum: "); Serial.println(failed);
  152. }
  153. bool feedgps()
  154. {
  155. uint8_t rcode;
  156. uint8_t buf[64]; //serial buffer equals Max.packet size of bulk-IN endpoint
  157. uint16_t rcvd = 64;
  158. {
  159. /* reading the GPS */
  160. rcode = Pl.RcvData(&rcvd, buf);
  161. if (rcode && rcode != hrNAK)
  162. ErrorMessage<uint8_t>(PSTR("Ret"), rcode);
  163. rcode = false;
  164. if( rcvd ) { //more than zero bytes received
  165. for( uint16_t i=0; i < rcvd; i++ ) {
  166. if( gps.encode((char)buf[i])) { //feed a character to gps object
  167. rcode = true;
  168. }//if( gps.encode(buf[i]...
  169. }//for( uint16_t i=0; i < rcvd; i++...
  170. }//if( rcvd...
  171. }
  172. return( rcode );
  173. }