A porting of a GPS decoding and presenting program within the mbos RTOS. It is not a definitive application but a study program to test NMEA full decoding library and a first approach to an RTOS. Many thanks to Andrew Levido for his support and his patience on teaching me the RTOS principles from the other side of the Earth. It uses NMEA library by Tim (xtimor@gmail.com) ported by Ken Todotani (http://mbed.org/users/todotani/) on public mbed library (http://mbed.org/users/todotani/programs/GPS_nmeaLib/5yo4h) also available, as original universal C library, on http://nmea.sourceforge.net
Dependencies: mbos Watchdog TextLCD mbed ConfigFile
Task1Gps.cpp
- Committer:
- guiott
- Date:
- 2012-02-03
- Revision:
- 3:a2f9eb3b8a16
- Parent:
- 2:8917036cbf69
File content as of revision 3:a2f9eb3b8a16:
#include "Task1Gps.h" void GpsSerialTask(void) {/** *\brief TASK 1, wait for the event then get the input char */ while(1) { os.WaitEvent(GPS_SERIAL_IN_EVT); GpsStringParse(); Dest.lat= 4151.32496; // ***************debug Dest.lon= 1229.34; // *************debug GpsDist(); } } void GpsSerialIsr(void) {/** *\brief Interrupt handler for serial Rx set the event for the serial task */ char c = gps.getc(); msgBuff[bufferSelect & 1][writePointer] = c; if (writePointer++ == BUFF_SIZE) { writePointer = 0; } if (writePointer > 200) {// GPS input buffer full, start computing coordinates os.SetEvent(GPS_SERIAL_IN_EVT, GPS_SERIAL_TASK); } } void trace_h(const char *str, int str_size) {/** *\brief output on console what's received on GPS serial Callback function for NMEA parser buffer trace */ if( PcMonitor==5 || PcMonitor>5) { for (int i = 0; i < str_size; i++) { pc.putc(*str++); } } } void error_h(const char *str, int str_size) {/** *\brief Callback function for NMEA parser error */ for (int i = 0; i < str_size; i++) { pc.putc(*str++); } } double trunc(double v) {/** *\brief Return nearest integer vaule less than input * *\parameters double variable to get nearest ingeger * *\return double */ if(v < 0.0) { v*= -1.0; v = floor(v); v*=-1.0; } else { v = floor(v); } return v; } void GpsStringParse(void) {/** *\brief parse the GPS string to extract info */ gps.attach(NULL); // Suspend serial interrupt while buffer change size = writePointer; writePointer = 0; bufferSelect++; // Change buffer gps.attach( &GpsSerialIsr ); // Resume serial interrupt nmea_parse(&parser, msgBuff[(bufferSelect-1)&1], size, &info); Coordinates(); // transform nmea coordinates in decimal degrees } void GpsDist(void) {/** *\brief compute the distance and direction (forward and reverse) from point A to point B on the ellipsoid */ nmea_info2pos(&info, &Pos[0]); // current position nmea_info2pos(&Dest, &Pos[1]); // destination Path.Dist = nmea_distance_ellipsoid(&Pos[0], &Pos[1], &Path.Azimuth[1], &Path.Azimuth[0]); if(Path.Azimuth[0] > NMEA_PI) {// reverse direction Path.Azimuth[0] = Path.Azimuth[0] - NMEA_PI; } else { Path.Azimuth[1] = Path.Azimuth[1] + NMEA_PI; } for(int i=0; i < 2; i++) { Path.Azimuth[i]=(nmea_radian2degree(Path.Azimuth[i])); if(Path.Azimuth[i] > 360) { Path.Azimuth[i] = Path.Azimuth[i] - 360; } if(Path.Azimuth[i] < 0) { Path.Azimuth[i] = Path.Azimuth[i] + 360; } } } void Coordinates(void) {/** *\brief transform nmea coordinates in decimal degrees */ degrees = trunc(info.lat / 100.0); minutes = info.lat - (degrees * 100.0); latitude = degrees + minutes / 60.0; degrees = trunc(info.lon / 100.0); minutes = info.lon - (degrees * 100.0); longitude = degrees + minutes / 60.0; } void Deg2DegMinSec(double DecDeg, DegMinSec *DecSec) {/** *\brief convert decimalDeg to Deg Min decimalSec */ DecSec->Deg = trunc(DecDeg); double MinDec = (DecDeg - DecSec->Deg); DecSec->Min = trunc(MinDec * 60); DecSec->Sec = (MinDec * 3600) - (DecSec->Min * 60); }