Forum: Mikrocontroller und Digitale Elektronik Arduino: NMEA String bauen.


von Frank (Gast)


Lesenswert?

Moin!

Ich empfange mit einem Arduino (Zero) NMEA Daten über die Serielle 
Schnittstelle. Diese Daten werden dann mit TinyGPS verarbeitet. Nun 
möchte ich diese Daten (und noch ein paar andere) über UDP versenden. 
Die UDP Verbindung funktioniert schon, jedoch scheitere ich am (was 
Anfang so schien) simpelsten... dem Zusammenfügen des NMEA Strings, bzw. 
Char arrays.

Arduino untersützt kein float im sprintf, daher bin ich auf dtostrf 
gestoßen. Das ganze wird jedoch ziemlich unübserichtlich und wirkt ein 
bisschen aufgeblasen für ein simples zusammenfügen eines Char Arrays.

Ich bin noch recht neu in der Programmierecke und komme eher aus dem 
klassischem Maschinenbau, habt daher bitte etwas Nachsicht :)

Ich habe auch schon überlegt, neben TinyGPS auch einfach den Seriellen 
Stream zu Puffern und diesen einfach so auszugeben. Jedoch muss ich 
später auch "Custom NMEA" Nachrichten senden, daher komme ich um den Bau 
meines Char Arrays nicht herum.

So sollte der String aussehen:
1
eg2. $GPRMC,225446,A,4916.45,N,12311.12,W,000.5,054.7,191194,020.3,E*68
2
3
4
           225446       Time of fix 22:54:46 UTC
5
           A            Navigation receiver warning A = OK, V = warning
6
           4916.45,N    Latitude 49 deg. 16.45 min North
7
           12311.12,W   Longitude 123 deg. 11.12 min West
8
           000.5        Speed over ground, Knots
9
           054.7        Course Made Good, True
10
           191194       Date of fix  19 November 1994
11
           020.3,E      Magnetic variation 20.3 deg East
12
           *68          mandatory checksum

Und so bastel ich mir meinen zusammen.
1
void UDPSendData(void) {
2
  char buffer[200];
3
  sprintf(buffer, "$GPRMC,%u,%d,", gps.time.value(), gps.location.isValid());
4
  dtostrf(gps.location.lat(), 4, 5, &buffer[strlen(buffer)]);
5
  strcat(buffer, ",");
6
  dtostrf(gps.location.lng(), 4, 5, &buffer[strlen(buffer)]);
7
  strcat(buffer, ",");
8
  dtostrf(gps.speed.knots(), 3, 0, &buffer[strlen(buffer)]);
9
  strcat(buffer, ",");
10
//der rest fehlt noch.
11
  IPAddress broadcastIp = ~WiFi.subnetMask() | WiFi.gatewayIP();  //Build the Broadcast IP Adress
12
  UDP.beginPacket(broadcastIp, UDPremotePort);
13
  UDP.write(buffer);
14
  UDP.endPacket();
15
16
}

Grüße

Frank

von Vincent H. (vinci)


Lesenswert?

Das Erstellen von Strings ist eines der Paradebeispiele eines 
erzeugenden Design Patterns namens "Builder". Die Beischreibung auf 
Wikipedia ist ganz ok:

https://en.wikipedia.org/wiki/Builder_pattern

Dort findet sich auch ein Beispiel, wie so etwas in C++ (sprich Arduino) 
meist aussieht.
1
// simple usage
2
Product p1 = Product::Builder().setI(2).setF(0.5f).setC('x').build();
3
p1.print(); // test p1


Bei einem "String Builder" wird sowas dann meist zu irgendwas in 
Richtung
1
// Pseudo
2
NmeaStr str = Builder().append(Time, 16, 10)     // Time und Co ev. eigene Typen
3
                       .append(Latitude, 49, 16)
4
                       .append(Speed, 100);


Wenn du dir mit dem Konzept eines Builders ein wenig schwer tust, dann 
lässt sich das ganze natürlich auch "C" ähnlich realisieren.
1
char[512] str; // initialize me ;)
2
uint32_t size;
3
appendTime(&str[size], &size, 16, 10);
4
appendLatitude(&str[size], &size, 49, 16);
5
appendSpeed(&str[size], &size, 100);

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.