Epijano:
Okay, mit besonders genauen Angaben kann ich also nicht rechnen.
Wenn ich die Funktion gps.f_altitude(); verwende bekomme ich aber immer nur 10000 zurückgegeben.
Wenn Du ernsthaft etwas mit einem GPS-Empfänger machen möchtest, müßtest Du davon weggkommen, die "SoftwareSerial" Library zu verwenden, die mit der Arduino-Software mitgeliefert wird. Das Ding ist so grausam, das produziert in praktisch jedem Sketch, den ich damit ausprobiert habe, immer wieder Fehler beim Datenempfang.
Hast Du vielleicht ein Board zur Verfügung, das mehr als eine hardwaremäßig vorhandene serielle Schnittstelle unterstützt, z.B. einen MEGA?
Wenn nicht, dann installiere Dir mal eine "alternative" Library, um eine SoftwareSerial-Schnittstelle bereitzustellen, z.B. diese hier:
http://www.pjrc.com/teensy/td_libs_AltSoftSerial.html
Dann schreibe Deinen Sketch um, damit statt SoftwareSerial die Library AltSoftSerial verwendet wird.
Nachtrag: Ich habe selbst gerade mal mit AltSoftSerial auf einem UNO getestet, damit läuft es einwandfrei.
Geänderter Test-Sketch für GPS-Module auf 9600 Baud und den seriellen Monitor auf 38400 Baud laufend:
// #include <SoftwareSerial.h>
#include <AltSoftSerial.h>
#include <TinyGPS.h>
/* This sample code demonstrates the normal use of a TinyGPS object.
It requires the use of SoftwareSerial, and assumes that you have a
4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/
TinyGPS gps;
// SoftwareSerial ss(4, 3);
AltSoftSerial ss; // with Uno use RX=8, TX=9 only!
static void smartdelay(unsigned long ms);
static void print_float(float val, float invalid, int len, int prec);
static void print_int(unsigned long val, unsigned long invalid, int len);
static void print_date(TinyGPS &gps);
static void print_str(const char *str, int len);
void setup()
{
Serial.begin(38400);
Serial.print("Testing TinyGPS library v. "); Serial.println(TinyGPS::library_version());
Serial.println("by Mikal Hart");
Serial.println();
Serial.println("Sats HDOP Latitude Longitude Fix Date Time Date Alt Course Speed Card Distance Course Card Chars Sentences Checksum");
Serial.println(" (deg) (deg) Age Age (m) --- from GPS ---- ---- to London ---- RX RX Fail");
Serial.println("-------------------------------------------------------------------------------------------------------------------------------------");
ss.begin(9600);
}
void loop()
{
float flat, flon;
unsigned long age, date, time, chars = 0;
unsigned short sentences = 0, failed = 0;
static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;
print_int(gps.satellites(), TinyGPS::GPS_INVALID_SATELLITES, 5);
print_int(gps.hdop(), TinyGPS::GPS_INVALID_HDOP, 5);
gps.f_get_position(&flat, &flon, &age);
print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 10, 6);
print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 11, 6);
print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
print_date(gps);
print_float(gps.f_altitude(), TinyGPS::GPS_INVALID_F_ALTITUDE, 7, 2);
print_float(gps.f_course(), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
print_float(gps.f_speed_kmph(), TinyGPS::GPS_INVALID_F_SPEED, 6, 2);
print_str(gps.f_course() == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(gps.f_course()), 6);
print_int(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0xFFFFFFFF : (unsigned long)TinyGPS::distance_between(flat, flon, LONDON_LAT, LONDON_LON) / 1000, 0xFFFFFFFF, 9);
print_float(flat == TinyGPS::GPS_INVALID_F_ANGLE ? TinyGPS::GPS_INVALID_F_ANGLE : TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
print_str(flat == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON)), 6);
gps.stats(&chars, &sentences, &failed);
print_int(chars, 0xFFFFFFFF, 6);
print_int(sentences, 0xFFFFFFFF, 10);
print_int(failed, 0xFFFFFFFF, 9);
Serial.println();
smartdelay(1000);
}
static void smartdelay(unsigned long ms)
{
unsigned long start = millis();
do
{
while (ss.available())
gps.encode(ss.read());
} while (millis() - start < ms);
}
static void print_float(float val, float invalid, int len, int prec)
{
if (val == invalid)
{
while (len-- > 1)
Serial.print('*');
Serial.print(' ');
}
else
{
Serial.print(val, prec);
int vi = abs((int)val);
int flen = prec + (val < 0.0 ? 2 : 1); // . and -
flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
for (int i=flen; i<len; ++i)
Serial.print(' ');
}
smartdelay(0);
}
static void print_int(unsigned long val, unsigned long invalid, int len)
{
char sz[32];
if (val == invalid)
strcpy(sz, "*******");
else
sprintf(sz, "%ld", val);
sz[len] = 0;
for (int i=strlen(sz); i<len; ++i)
sz[i] = ' ';
if (len > 0)
sz[len-1] = ' ';
Serial.print(sz);
smartdelay(0);
}
static void print_date(TinyGPS &gps)
{
int year;
byte month, day, hour, minute, second, hundredths;
unsigned long age;
gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
if (age == TinyGPS::GPS_INVALID_AGE)
Serial.print("********** ******** ");
else
{
char sz[32];
sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d ",
month, day, year, hour, minute, second);
Serial.print(sz);
}
print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
smartdelay(0);
}
static void print_str(const char *str, int len)
{
int slen = strlen(str);
for (int i=0; i<len; ++i)
Serial.print(i<slen ? str[i] : ' ');
smartdelay(0);
}
Arduino RX-Pin kann mit AltSoftSerial nicht frei ausgewählt werden, sondern mit AltSoftSerial ist beim UNO RX fest auf Pin-8, also TX vom GPS-Modul mit RX Pin-8 am UNO verbinden.
Aber achte mal im Vergleich zu SoftwareSerial auf die Spalte "Checksum Fail". Mit SoftwareSerial kannst Du zusehen, wie "Checksum Fail" von Sekunde zu Sekunde größer wird, so viele Datenfehler verursacht die SoftwareSerial Library. Mit der AltSoftSerial Library bleibt "Checksum Fail" ganz stabil bei "0" stehen.
Höhenangaben werden übrigens nicht immer mitgeliefert, sondern nur dann, wenn kein "2D fix" vom GPS-Modul geliefert wird, sondern ein "3D fix". Das muß man nicht extra umschalten, sondern das Modul liefert einfach: Bei schlechtem Empfang kommen 2D fix Datensätze ohne Höhenangaben, bei besserem Empfang 3D fix Datensätze mit Höhenangaben. Die TinyGPS-Library kann meines Wissens nach nicht auswerten, ob 2D oder 3D Daten kommen. Als Anhalt kann Dir aber die Anzahl der Satelliten dienen, die TinyGPS anzeigt: Mit 0, 1 oder 2 Satelliten bekommst Du überhaupt keine Positionsangaben, mit 3 Satelliten bekommst Du Längen- und Breitengradangaben, und mit 4 oder mehr Satelliten bekommst Du auch Höhenangaben mitgeliefert. So als grober Anhalt "über den Daumen gepeilt", ohne dass man direkten Zugriff auf alle gelieferten Daten hat, sondern nur die paar minimalen Daten, die die TinyGPS-Library von den gelieferten Daten auswerten kann.