Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
11 years, 8 months ago.
Can't detect speed and Course from this code.
In the following code I have written a GPRMC detection code, which is similar to the GPGGA detection that was provided in the GPS.cpp library. But the Speed and course comes as 0.000. The lat and long from GPGGA and GPRMC comes correctly. Can anyone tell me if there is an error in the code?
GPS.cpp: /* mbed EM-406 GPS Module Library * Copyright (c) 2008-2010, sford * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include "GPS.h" GPS::GPS(PinName tx, PinName rx) : _gps(tx, rx) { _gps.baud(4800); longitude = 0.0; latitude = 0.0; } int GPS::sample() { float time; char ns, ew, ns2, ew2, warning; int lock, timefix; while(1) { getline(); // Check if it is a GPGGA msg (matches both locked and non-locked msg) if(sscanf(msg, "GPGGA,%f,%f,%c,%f,%c,%d", &time, &latitude, &ns, &longitude, &ew, &lock) >= 1) { if(!lock) { longitude = 0.0; latitude = 0.0; return 0; } else { if(ns == 'S') { latitude *= -1.0; } if(ew == 'W') { longitude *= -1.0; } float degrees = trunc(latitude / 100.0f); float minutes = latitude - (degrees * 100.0f); latitude = degrees + minutes / 60.0f; degrees = trunc(longitude / 100.0f ); // Edit:original GPS.h had, degrees = trunc(longitude/100.f*0.01f); minutes = longitude - (degrees * 100.0f); longitude = degrees + minutes / 60.0f; return 1; } } else { if (sscanf(msg, "GPRMC,%d,%c,%f,%c,%f,%c,%f,%f", &timefix,&warning,&lat,&ns2,&lon, &ew2,&speedgnd,&course) >=1) { if(ns == 'S') {lat *= -1.0;} if(ew == 'W') { lon *= -1.0;} float deg = trunc( lat/100.0f); float min= lat - (deg*100.0f); lat = deg + min/60.0f; deg = trunc(lon/100.0f); // This line too maybe should have had (lon/100.0f*0.0f); min= lon - (deg*100.0f); lon = deg + min/60.0f; return 1; } } } } float GPS::trunc(float v) { if(v < 0.0) { // floor(x) returns the largest integer value not greater than x. v*= -1.0; v = floor(v); v*=-1.0; } else { v = floor(v); } return v; } void GPS::getline() { while(_gps.getc() != '$'); // wait for the start of a line for(int i=0; i<256; i++) { msg[i] = _gps.getc(); if(msg[i] == '\r') { msg[i] = 0; return; } } error("Overflowed message limit"); }
Main.cpp: #include "mbed.h" #include "GPS.h" Serial pc(USBTX, USBRX); GPS gps(p9, p10); int main() { while(1) { if(gps.sample()) { pc.printf(" GPGGA says: I'm at %f, %f\r\n", gps.longitude, gps.latitude); pc.printf("GPRMC says: I am at %f, %f\r\n", gps.lon, gps.lat); pc.printf("Speed over ground: %f, Course over ground: %f \r\n\r", gps.speedgnd, gps.course); pc.printf("\r\n"); } else { pc.printf("Oh Dear! No lock :(\n"); } } }
2 Answers
11 years, 8 months ago.
How do I check whether my input itself contains speed and course as 0.000 and 0.000. I generally take the GPS connected with mbed and the laptop and walk around the campus. I hope walking speed is measurable by GPS.
yes I have mentioned the variables: speedgnd, course as floats in gps.h file.
Didn't get your last sentence. Do you mean by keeping 'timefix' a decimal input sscanf stops there itself and doesnt care about the rest of the sentence?
Thanks, Abhilash
He means (if I am correct) that you should try just sending the entire 'msg' string to your PC. Then manually check what this message contains, is it what you expect it to be with a course and speed?
posted by 04 Apr 2013Yes that's what I mean. And yes sscanf stops scanning when it encounters a decimal point in an integer
posted by 04 Apr 2013Yes you are right, Ad Van Weiden. The timefix variable in the GPRMC is a floating point variable. I changed the timefix variable in the above program into float as you said. That change fixed the program. I am getting the course and speed. Thanks a lot.
Thanks to Erik Olieman too.
posted by 05 Apr 201311 years, 8 months ago.
check the return value of sscanf. it will tell you how many fields were converted. I assume you already checked the input?
What do you mean by already checking the input?
My serial output is: GPGGA says: I'm at 72.918327, 19.131733 GPRMC says: I am at 0.000000, 0.000000 Speed over ground: 0.000000, Course over ground: 0.000000
posted by 04 Apr 2013What I mean is, if your input is: $GPRMC,081836,A,3751.65,S,14507.36,E,000.0,000.0,130998,011.3,E*62 it would not be surprising that speed and course are zero. are the speed and course members in the gps class floats? I have seen an example of this sentence where the time was a float, this may stop sscanf.
posted by 04 Apr 2013