Brauche Hilfe, Tipps oder zumindest Anstoß zur Anzeige der Uhrzeit im GPS-Gerät

Hallo,

neben ein paar kleineren Sachen habe ich auch dieses Projekt hier realisiert. Es ist ein relativ einfaches GPS-Frequenznormal, welches auch sehr gut funktioniert.

Hier zu finden: GPS-Normal

Ich habe zwar andere Normale (DCF77, Rubidium und auch GPS) doch dieses hier kann variable Frequenzen von 1Hz bis 24MHz ausgeben. Zwar nicht durchgängig mit hoher Genauigkeit, doch alles was als ganzzahliger Teilfaktor aus 48MHz abgeleitet werden kann, schon.

Darum geht es hier aber nicht, dass wäre ein unerschöpfliches Thema (in dem ich seit Jahren "fummle")

Der Autor dieses Projektes hat auch den passenden Sketch bereitgetellt, dieser funktioniert auch bestens.

Bedient wird das Ganze über eine 4x4er Tastatur und eine Taste ist noch unbelegt. Auf diese würde ich gerne eine Funktion zur Anzeige von Datum und Uhrzeit legen. In den Weiten des Netzes habe ich einige Beispielsketche gefunden, die funktionieren mit der vorliegenden Hardware auch gut (nach Anpassunge der Ports), doch ich möchte das ja in den vorhandenen Sketch integrieren.

Das ganze auch, um weiter in die Arduinoprogrammiereung einzusteigen.

Hier der Code:

Der ist offenbar für die Forensoftware zu lang, es wird gemeckert, 
dass mein Text über 9000 Zeichen hat.
Also als Anlagen und auch die ublox.h und ublox.cpp

Im Code wird mit der "#"-Taste die Anzhl der empfangenen Satelliten auf das Display ausgegeben, wahrscheinlich in sehr ähnlicher Form wird das mit Datum/Uhrzeit auch gemacht. Doch soweit bin ich in die Tiefen von Arduino noch nicht vorgedrungen.

Bitte keine Diskussion darüber, dass der Kollege vielleicht Dieses und Jenes hätte anders machen können, damit ist ja erstmal keinem geholfen.

Gruß
Old-Papa

GPS_Ref_Version6.ino (7.18 KB)

ublox.cpp (2.18 KB)

ublox.h (450 Bytes)

(deleted)

Peter-CAD-HST:
Moin Old-Papa

und wo ist in deinem Text das "?" ?

Gruss Peter
und gesund bleiben

Hmmmm, ich dachte, mein Problem und damit die Fragestellung sind klar. Soll ich das noch genauer beschreiben?

Also, wie kann ich den Code an der Stelle, in der die #-Taste benutzt wird kopieren und mit der *-Taste für die Anzeige von Datum und Uhrzeit umschreiben?

Der Kollege wertet ja einen bestimmten NMEA-String aus und nutzt die Werte an einer bestimmten Position. Datum und Uhrzeit (oder nur Uhrzeit?) stehen ja im gleichen String.
Die Abfrage habe ich hinbekommen, doch bei der Auswertung, Umwandlung und Darstellung auf dem Display hapert es mit meinem schmalen Arduinowissen noch.
Gerne würde ich ja dazulernen...

Old-Papa

(deleted)

Peter-CAD-HST:
Dort kannst du die Analyse der NMEA Datensätze vornehmen und zur Anzeige bringen.
Bei meiner schnellen Durchsicht habe ich nur den GGA Datensatz gefunden und dieser enthält die UTC Zeit und kein Datum. Beides, Uhrzeit und Datum, sind im ZDA Datensatz enthalten. Vielleicht wird dieser auch empfangen und muss nur noch ausgewertet werden.

Viel Erfolg
Gruss Peter
und gesund bleiben

p.s. Tutorials zum Zerlegen von Strings gibt es im weltweiten Netz

Ja, das habe ich auch so verstanden :wink:

Ich muss alo im "Weltnetz" suchen (ich dachte, ich bin hier schon...)

Gruß
Old-Papa

old-papa:
Ich muss also im "Weltnetz" suchen (ich dachte, ich bin hier schon...)

Ich habe die notwendige Hardware nicht, weshalb ich das längliche Programm nicht ausprobieren kann und sehe daher die Datenströme nicht. Daher wäre es hilfreiuch, das Problem in kleine Teilprobleme zu zerlegen:

  • In der Zeile sats = GPGGAdata.substring(39,41); wird der String GPGGAdata auf die Anzahl der Sateliten untersucht. Sowas benötigst Du auch für die von Dir gesuchten Werte. Wie sieht beispielsweise der Inhalt von GPGGAdata aus? Mit Serial.print(GPGGAdata); wird Dir das angezeigt.
  • Wo findest Du die gesuchten Werte innerhalb des Strings?
  • Wie kann man den String hinsichtlich der gesuchten Werte zerlegen?

Die Punkte 1 und 2 kannst Du selbst lösen, bei 3 kann ich dann gerne helfen.

agmue:
Ich habe die notwendige Hardware nicht, weshalb ich das längliche Programm nicht ausprobieren kann und sehe daher die Datenströme nicht. Daher wäre es hilfreiuch, das Problem in kleine Teilprobleme zu zerlegen:

  • In der Zeile sats = GPGGAdata.substring(39,41); wird der String GPGGAdata auf die Anzahl der Sateliten untersucht. Sowas benötigst Du auch für die von Dir gesuchten Werte. Wie sieht beispielsweise der Inhalt von GPGGAdata aus? Mit Serial.print(GPGGAdata); wird Dir das angezeigt.
  • Wo findest Du die gesuchten Werte innerhalb des Strings?
  • Wie kann man den String hinsichtlich der gesuchten Werte zerlegen?

Hier ein Zitat von der Webseite des Autors: (die hatte ich oben verlinkt)
Leider hatte ich nie Englisch gelernt, daher ist das für mich immer ein Stochern im Nebel.

----- Zitat------

Reading the GPS module data to extract the number of Satellites detected

When the GPS module starts receiving satellite data it provides a constant stream of data sentences which are know as NMEA sentences. Within this data stream the most important NMEA sentences include the GGA which provides the current Fix data, the RMC which provides the minimum GPS sentences information, and the GSA which provides the Satellite status data. In our project we will use the GGA data stream to extract the number of satellites detected and locked on to.

Below is an example of a typical GGA data sentence:

$GPGGA,123519.00,4807.03830,N,01131.00000,E,1,08,0.9,545.4,M,46.9,M,,*47

Where:

GGA Global Positioning System Fix Data
123519.00 Fix taken at 12:35:19 UTC (current time)
4807.03830,N Latitude 48 deg 07.038′ N
01131.00000,E Longitude 11 deg 31.000′ E
1 Fix quality: 0 = invalid, 1 = GPS fix (SPS), 2 = DGPS fix, 3 = PPS fix, 4 = Real Time Kinematic,
5 = Float RTK, 6 = estimated (dead reckoning) (2.3 feature), 7 = Manual input mode,
8 = Simulation mode
08 Number of satellites being tracked
0.9 Horizontal dilution of position
545.4,M Altitude, Meters, above mean sea level
46.9,M Height of geoid (mean sea level) above WGS84 ellipsoid
(empty field) time in seconds since last DGPS update
(empty field) DGPS station ID number
*47 the checksum data, always begins with *

We will be using the data highlighted above to show the number of satellite on our LCD. In order to extract this information we will set up a second Software Serial port.

First we need to identify the NMEA data we need to capture and we do this with the flowing code:

char gpsin[8] = “$GPGGA,”; //define a character string “$GPGGA,”
if (GPSreceiver.find(gpsin)) { //if serial data starts with the characters “$GPGGA,”
GPGGAdata = GPSreceiver.readStringUntil(‘\n’); //read data until carriage return

When the characters “$GPGGA,” are detected it starts reading the remainder of the string data in to the buffer. So the captured data starts from the first digit of the ‘time’ data (and not from the $ character). The captured data then looks as follows:

123519.00,4807.03830,N,01131.00000,E,1,08,0.9,545.4,M,46.9,M,,*47

With in the main loop we will use the substring command to extract the number of satellites from the GGA data sentence. This is a simply and easy way of extracting the data you wish to use. The substring command is defined as follows:
substring(index, to) – this returns a string with the characters starting from index and ending at the character location before the to
So to extract the number of satellites (highlighted in read) from the GGA data sentence below

NMEA_data_stripped

We use the following code:

sats = GPGGAdata.substring(39,41);

The string “sats” now is equal to “08”
If you wanted to extract other data you simply need to change the “index, to” numbers in the substring. For example to extract the current time to a string labeled time then you would use:

time = GPGGAdata.substring(7,13); //the string “time” now is equal to “123519”

------ Zitat ende --------

agmue:
Die Punkte 1 und 2 kannst Du selbst lösen, bei 3 kann ich dann gerne helfen.

Mich irritiert z.B. die letzte Zeile, dort schreibt er ja, dass man durch Ersetzen der Zeile mit "sats" mit dieser Zeile die Zeitinformation bekommt. Bei mir hagelt es dann (für mich) unverständliche Fehlermeldungen.
Das ich die Daten in dieser NMEA-Zeile ab Pos. 0 finde, sehe ich ja, doch dann?
Wie schon geschrieben, ich bin noch ganz am Anfang....

Old-Papa

(deleted)

Hallo,
unten die fehlermeldungen.
Mich irritiert auch, dass plötzlich "mehrere Bibliotheken" für Keypad.h und LiquidCrystal.h gefunden werden. Ohne diese eine ausgetauschte Zeile gibt es auch keine Fehlermeldung zu den Bibliotheken.
(falsche Fehlermeldungen?)
Statt

sats = GPGGAdata.substring(39,41);

steht jetzt wie vom Autor vorgeschlagen

time = GPGGAdata.substring(7,13); //the string “time” now is equal to “123519”

Fehlermeldungen:

D:\Arduino-Testverzeichnis\GPS_Ref_Version6a-Uhr-2x16\GPS_Ref_Version6a-Uhr-2x16.ino: In function 'void loop()':

GPS_Ref_Version6a-Uhr-2x16:164:4: error: 'time' was not declared in this scope

    time = GPGGAdata.substring(7,13); //the string “time” now is equal to “123519”

    ^~~~

D:\Arduino-Testverzeichnis\GPS_Ref_Version6a-Uhr-2x16\GPS_Ref_Version6a-Uhr-2x16.ino:164:4: note: suggested alternative: 'Time'

    time = GPGGAdata.substring(7,13); //the string “time” now is equal to “123519”

    ^~~~

    Time

Mehrere Bibliotheken wurden für "Keypad.h" gefunden
 Benutzt: C:\Program
 Nicht benutzt: C:\Program
Mehrere Bibliotheken wurden für "LiquidCrystal.h" gefunden
 Benutzt: C:\Program
 Nicht benutzt: C:\Program
exit status 1
'time' was not declared in this scope

Du hast die Variable time nicht deklariert.

Das mit den mehreren Libs im Fehlerfall ist ein Bug der IDE.

Gruß Tommy

(deleted)

Tommy56:
Du hast die Variable time nicht deklariert.

Das mit den mehreren Libs im Fehlerfall ist ein Bug der IDE.

Gruß Tommy

Ok, das dachte ich mir schon.
An welcher Stelle im Sketch deklariere ich diese und wie?
testweise hatte ich das so und an gleicher Stelle gemacht, wie auch andere Variablen deklariert wurden
z.B.

String time;
String sats; //number of satellites detected
String GPGGAdata; //satellte data string from GPS module
String FreqStatus; //used to print Frequency locked if applicable

Ich vermute das geht nicht so einfach.
In der IDE wird "time" auch immer in rot dargestellt.

Old-Papa

Doch, das sollte gehen. Evtl. anstelle von time den Namen zeit verwenden.
Die Farben in der IDE darfst Du nicht wirklich ernst nehmen.

Gruß Tommy

Peter-CAD-HST:
Moin

die Variable time kennt der Compiler nicht.

Die muss noch bekanntgegeben werden

String time;        //time in UTC

Gruss Peter
und gesund bleiben

Oha, Tommy war schneller...

Also, genau so hatte ich das ja auch (wobei "time" dann in rot dargestellt wird). Dann habe ich zwar keine Fehlermeldung mehr, doch was dann?
Wie bekomm ich nun die Urzeit aufs Display? :wink:

Wie schon geschrieben, ich hangle mich da an dem Teil im Sketch entlang der genauso für die Anzeige der Satellitenanzahl benutzt wird. Als Anfänger stochert man halt etwas im Nebel.

Old-Papa

So, ich habe überall die Variable in "zeit" geändert, ist zumindest nicht mehr rot :wink:

Hier nochmal der Codeteil zur Anzeige der Satellitenanzahl, wie ihn der Autor extra nochmal auf seiner Seite dargestellt hat.

//new variables added at start of program
String sats; //number of satellites detected
String GPGGAdata;           //satellite data string from GPS module
String FreqStatus;          //used to print Frequency locked if applicable
int satNum;                 //number of satellites detected as an integer

//set up a Software Serial port called GPSreceiver

SoftwareSerial GPSreceiver (14,255); //14(A0) is RX on Arduino connected to GPS TX pin. //255 a nonexistent pin number used to free up a pin

//in void setup() include serial monitor command and set to 57600 baud.

Serial.begin(57600);                 //this is simply used for testing
//The # key used to tell the unit to display the number of satellites on LCD.
// below is the software code used in the main loop to show number of satellites when //“#” key pressed:

case '#'://# pressed Show number of satellites detected and frequency status
lcd.clear(); //clear LCD
lcd.print("Satellites =");        //print the word 'Satellites =' on the top line of LCD
do {                             //now loop
GPSreceiver.flush();   //clear any data which may be in the Serial Buffer
if (GPSreceiver.available())          //if any GPS data is available
{
GPSreceiver.read();         //read GPS serial data streams if available
}
char gpsin[8] = "$GPGGA,";       //define a character string “$GPGGA,”
if (GPSreceiver.find(gpsin)) {     //if serial data starts with the characters “$GPGGA,”
GPGGAdata = GPSreceiver.readStringUntil('\n'); //read data until a carriage return
sats = GPGGAdata.substring(39,41); //extract number of satellites from data string
}
satNum = sats.toInt(); //convert sats string to an integer so as to remove leading zero
if (satNum >0){
FreqStatus = "Frequency Locked";  //if satellites detected the status string
//= “Frequency Locked”
}else{
FreqStatus = " ";                 //16 spaces to clear line if no lock
}
Serial.print(GPGGAdata);   //These serial print lines are for testing using

//Serial Monitor
Serial.println(); //full GPGGA data sentence printed and then carriage return
Serial.print("Satellite = ");
Serial.print(satNum);
Serial.println();
Serial.print(FreqStatus);
Serial.println();

lcd.setCursor(13,0); //set cursor position to column 13 of row 0 (first line on LCD)
lcd.print(" ");  //clears number if no satellites detected (3 spaces used)
lcd.setCursor(13,0); //set cursor position to column 13 of row 0 (first line on LCD)
lcd.print(satNum);         //print number of satellites to LCD
lcd.setCursor(0,1); //set cursor position to column 0 of row 1 (second line on LCD)
lcd.print(FreqStatus);     //print Frequency Locked status
}
while (customKeypad.getKey()!= '#'); //if # key pressed again break out of loop
displayCurrentFrequency();   //and display current frequency subroutine
break;                       //break and return to main program loop

Old-papa

Wie versprochen Punkt 3:

String GPGGAdata = "123519.00,4807.03830,N,01131.00000,E,1,08,0.9,545.4,M,46.9,M,,*47";   //satellte data string from GPS module

void setup()
{
  Serial.begin(115200);
  Serial.println("\nStart");
  Serial.println(GPGGAdata);
  String zeit = GPGGAdata.substring(0, 6);
  Serial.println(zeit);
  byte h = GPGGAdata.substring(0, 2).toInt();
  byte m = GPGGAdata.substring(2, 4).toInt();
  byte s = GPGGAdata.substring(4, 6).toInt();
  Serial.print(h); Serial.print(':'); Serial.print(m); Serial.print(':'); Serial.println(s);
  char z[] = {"00:00:00"};
  snprintf(z, sizeof(z), "%2d:%2d:%2d", h, m, s);
  Serial.println(z);
}

void loop() {}

Wenn Du was auf das Display schreiben möchtest, dann lcd.print().

Besser:

snprintf(z, sizeof(z), "%02d:%02d:%02d", h, m, s);

Da wird automatisch die führende 0 hinzu gefügt.

Gruß Tommy

Tommy56:
Da wird automatisch die führende 0 hinzu gefügt.

Stimmt, danke!

Nun, ich werde das Ganze wohl bleiben lassen.

Keine Ahnung wo ich dass nun hinschreibe (unter "case '*' wahrscheinlich)

Wie gesagt, ich brauche schon fast ein "an die Hand nehmen..."

Old-Papa

So, ich noch mal... :wink:

Ich bin ein ganzes Stück weiter, zumindest auf dem seriellen Monitor wird die Uhrzeit richtig angezeigt.
Auf dem Display fehlen leider die führenden Nullen (im Moment bei den Minuten und Sekunden). Ja, die von Tommy geänderte Zeile habe ich ausgetauscht.

Bis hier her erstmal herzlichen Dank!
Und Ja, wieder was gelernt.

Old-Papa

Achso... Wie komme ich nun von UTC auf MESZ? Immer 2 Stunden addieren?