how can I have my GPS report my heading ("angle") as, for instance: 038.43 (instead of "38.43" as it currently is showing it?). I realize that I need to work with the "GPS.angle" variable from the code provided by Adafruit.
The goal would be to have the newly created "038.43" value saved as a variable.
Does anyone have any thoughts and/or examples on how I can do this?
Thanks!!
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(3, 2);
Adafruit_GPS GPS(&mySerial);
#define GPSECHO true
boolean usingInterrupt = false;
void useInterrupt(boolean); // Func prototype keeps Arduino 0023 happy
void setup()
{
Serial.begin(115200);
Serial.println("Adafruit GPS library basic test!");
GPS.begin(9600);
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // 1 Hz update rate
GPS.sendCommand(PGCMD_ANTENNA);
useInterrupt(true);
delay(1000);
mySerial.println(PMTK_Q_RELEASE);
}
SIGNAL(TIMER0_COMPA_vect) {
char c = GPS.read();
#ifdef UDR0
if (GPSECHO)
if (c) UDR0 = c;
#endif
}
void useInterrupt(boolean v) {
if (v) {
OCR0A = 0xAF;
TIMSK0 |= _BV(OCIE0A);
usingInterrupt = true;
} else {
TIMSK0 &= ~_BV(OCIE0A);
usingInterrupt = false;
}
}
uint32_t timer = millis();
void loop() // run over and over again
{
if (! usingInterrupt) {
char c = GPS.read();
if (GPSECHO)
if (c) Serial.print(c);
}
if (GPS.newNMEAreceived()) {
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 (timer > millis()) timer = millis();
if (millis() - timer > 2000) {
timer = millis(); // reset the timer
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("Angle: "); Serial.println(GPS.angle);
}
}
}
Serial.println(GPS.angle);
Here GPS.angle( is variable )itself stores the value of angle.You can write it in EEPROM. Since it vary with position of sensor.
It doesn't make any sense 038.43 or 38.43
coding1227:
how can I have my GPS report my heading ("angle") as, for instance: 038.43 (instead of "38.43" as it currently is showing it?). I realize that I need to work with the "GPS.angle" variable from the code provided by Adafruit.
[quote
The goal would be to have the newly created "038.43" value saved as a variable.
[/quote]
The value cannot be stored in a float (which GPS.angle is) with a leading zero. In other words, the float variable only holds the value. In order to save it with the leading zero, you would need to convert it to a string with a leading zero, or better still, just use the above routine to display the value with a leading zero.
Thanks guys for the feedback. You where right in that I had to do some conversions. Per the code hereby included, I transformed the float value from GPS.angle into a character, and then from there I built a string that included the "0" in front of it.
However, if possible... could someone please double-check that I've used the correct array size for "anglebuff", as well as in dtostrf? The thing is that I "sort of" understand how these work, but I'm not totally sure... thanks so much!
Here's my code:
// Reformat the angle to add a ZERO infront...
// this is to turn, for instance: 34.53 into 034.53; or also turn 3.85 into 003.85:
char anglebuff[4];
dtostrf(GPS.angle, 4, 2, anglebuff); // dtostrf(floatvar, num of digits, num of decimals, buffname)
String myangle = "";
if (GPS.angle < 100) {
myangle += "0" + String(anglebuff);
} else if (GPS.angle < 10) {
myangle += "0" + String(anglebuff);
} else {
String myangle = anglebuff;
}
Serial.print(myangle);
Serial.print(" ");
The anglebuff array needs to be large enough to hold the target string plus the terminating NULL character so a dimension of 4 will not be large enough. It may work as it is but you will be writing to memory locations beyond the array as declared which could cause all sorts of problems.
Two other observations.
You are using a mix of Strings and strings which is generally considered a bad thing. Strings (capital S) have proponents here and they seem generally easier to use than strings (lower case s) at first sight. However, C style strings (NULL terminated char arrays) are generally felt to be a better way to do things in the limited memory environment of a micro-controller.
If the angle is less that 100 you add one leading zero but if it is less than 10 you still only add one leading zero.
I understand what you mean on all your comments, which were very helpful! So, considering that my angle values should be XXX.XX, what should the buffer size be? And similarly, are the parameters used in "dtostrf" correct?
Regarding the mixing of the String & string declarations, I didn't know that there was such a difference. What other way would you suggest I code this so as to make it more efficient?
The maximum angle of XXX.XX is 6 characters long so, allowing for the final NULL on the string the buffer needs to be 7 characters long (or more). The parameters look OK to me.
Using strings instead of Strings would not necessarily make the program more efficient but the memory fragmentation that Strings can cause could be important in larger programs.
The code you provided works just perfectly! My apologies... I somehow had missed earlier that you had posted this code example.
It turns out to work perfectly, and thanks to your great explanation I was able to learn something new today:
super nifty tools such as "strcpy" and "strcat"
One last question... could you provide me with some recommendations of sites I could look at that have a good review of these & other useful arduino tools? It is just that I had no idea these little commands existed... until now
Those functions are not Arduino specific, they are general purpose C++ functions. Any site with a tutorial on C++ (or C for that matter) will explain what these and other functions do and how. For instance http://www.cplusplus.com/reference/