Die GPS Position, Kurs und Geschwindigkeit werden vom HDS gesendet, aus dem NMEA2000 Netzwerk in den Arduino Mega eingelesen und per USB dann formatiert in der Konsole ausgegeben.
Es kommt ein schneller Kurs/Speed Datensatz 4x pro Sekunde aus dem NMEA2000 Netz
PGN 129026 COG & SOG, Rapid Update
und ein GPS Datensatz 1x pro Sekunde
PGN 129029 GNSS Position Data
Diese beiden Datensätze werden eingelesen, zerlegt und die interessanten Werte werden auf der Konsole ausgegeben.
Hier das Programm:
/ Die Positionsdaten, SOG und COG werden aus dem // NMEA2000 Netz in den Arduino eingelesen und dann // formatiert ausgegeben. // // Matthias Busse 2.12.2016 Version 1.0 #define N2k_CAN_INT_PIN 21 #define MCP_CAN_RX_BUFFER_SIZE #include <SPI.h> #include <Arduino.h> #include <NMEA2000_CAN.h> #include <N2kMessages.h> #include <N2kMessagesEnumToStr.h> typedef struct { unsigned long PGN; void (*Handler)(const tN2kMsg &N2kMsg); } tNMEA2000Handler; void COGSOG(const tN2kMsg &N2kMsg); void GNSS(const tN2kMsg &N2kMsg); tNMEA2000Handler NMEA2000Handlers[]={ {129026L,&COGSOG}, {129029L,&GNSS}, {0,0} }; template<typename T> void PrintLabelValWithConversionCheckUnDef(const char* label, T val, double (*ConvFunc)(double val)=0, bool AddLf=false ) { Serial.print(label); if (!N2kIsNA(val)) { if (ConvFunc) { Serial.print(ConvFunc(val)); } else { Serial.print(val); } } else Serial.print("not available"); if (AddLf) Serial.println(); } void setup() { Serial.begin(115200); NMEA2000.EnableForward(false); NMEA2000.SetMsgHandler(HandleNMEA2000Msg); NMEA2000.Open(); } void loop() { NMEA2000.ParseMessages(); } void COGSOG(const tN2kMsg &N2kMsg) { // PGN 129026 COG & SOG, Rapid Update. // kommt typisch 4x pro Sekunde unsigned char SID; tN2kHeadingReference HeadingReference; double COG, COG2; double SOG; if (ParseN2kCOGSOGRapid(N2kMsg,SID,HeadingReference,COG,SOG) ) { Serial.print("COG: "); COG2=COG*57296/1000; // NMEA2000 ist radians > in Grad umrechnen if(COG2<0.0) COG2=360+COG2; // 0..180 und 0..-179 in 0..360 Grad umrechnen Serial.print(COG2,0); // in Grad Serial.print(" Grad, "); Serial.print("SOG: "); Serial.print(SOG*1.9438,2); // in kn (NMEA2000 ist m/s) (m/s * 1.9438 = kn) Serial.println(" kn "); } else { Serial.print("Fehler PGN: "); Serial.println(N2kMsg.PGN); } } void GNSS(const tN2kMsg &N2kMsg) { // PGN 129029 GNSS Position Data // kommt typisch 1x pro Sekunde unsigned char SID; uint16_t DaysSince1970; double SecondsSinceMidnight; double Latitude; double Longitude; double Altitude; tN2kGNSStype GNSStype; tN2kGNSSmethod GNSSmethod; unsigned char nSatellites; double HDOP; double PDOP; double GeoidalSeparation; unsigned char nReferenceStations; tN2kGNSStype ReferenceStationType; uint16_t ReferenceSationID; double AgeOfCorrection; if (ParseN2kGNSS(N2kMsg,SID,DaysSince1970,SecondsSinceMidnight, Latitude,Longitude,Altitude,GNSStype,GNSSmethod, nSatellites,HDOP,PDOP,GeoidalSeparation, nReferenceStations,ReferenceStationType,ReferenceSationID, AgeOfCorrection) ) { Serial.print("Breite: "); Serial.print(Latitude,5); // 5 Kommastellen, in Grad ("-"=Süd, “+”=Nord) Serial.print(" Grad, "); Serial.print("Laenge: "); Serial.print(Longitude,5); // 5 Kommastellen, in Grad ("-"=West, “+”=Ost) Serial.print(" Grad, "); Serial.print("Hoehe: "); Serial.print(Altitude,1); Serial.print("m, "); Serial.print("Sats: "); Serial.print(nSatellites); Serial.println(" "); } else { Serial.print("Fehler PGN: "); Serial.println(N2kMsg.PGN); } } void HandleNMEA2000Msg(const tN2kMsg &N2kMsg) { int iHandler; for (iHandler=0; NMEA2000Handlers[iHandler].PGN!=0 && !(N2kMsg.PGN==NMEA2000Handlers[iHandler].PGN); iHandler++); if (NMEA2000Handlers[iHandler].PGN!=0) { NMEA2000Handlers[iHandler].Handler(N2kMsg); } }
Die Konsolenausgabe sieht dann so aus:
Breite: 54.26037 Grad, Laenge: 10.08289 Grad, Hoehe: 42.4m, Sats: 7
COG: 247 Grad, SOG: 0.14 kn
COG: 320 Grad, SOG: 0.23 kn
COG: 320 Grad, SOG: 0.23 kn
COG: 320 Grad, SOG: 0.23 kn
Breite: 54.26037 Grad, Laenge: 10.08289 Grad, Hoehe: 42.9m, Sats: 7
COG: 320 Grad, SOG: 0.23 kn
COG: 242 Grad, SOG: 0.25 kn
COG: 242 Grad, SOG: 0.25 kn
COG: 242 Grad, SOG: 0.25 kn
Der Plotter mit eingebautem GPS, steht bei mir vor dem Fenster und hat so einen brauchbaren Empfang mit 5-8 Satelliten. Kurs und Geschwindigkeit springen aber etwas um die eigentlich feste Position herum. Das ist einfach der Positionsfehler und gut in den Daten zu sehen.
Hier der Aufbau:
Verwendet wurden:
Arduino Software 1.6.5
Die Library von Timo Lappalainen
Arduino Mega 2560
MCP2515 & TJA1050 Platine
Ein NMEA2000 Netzwerk mit Stromversorgung und Abschlußwiderständen
Lowrance HDS 5m Plotter mit NMEA2000 Ausgang
Verbindungen wie hier beschrieben
von Matthias Busse
Hallo Mathias,
die beiden defins:
#define N2k_CAN_INT_PIN 21
#define MCP_CAN_RX_BUFFER_SIZE 100
müssen vor den
#include
stehen, sonst hat das keine wirkung.
Danke für den Hinweis, das ist geändert.
Hallo Mathias,
gibt es eine Möglichkeit die Anzahl der Nachkommastellen beim Längen- und Breitengrad zu erhöhen, damit Positionsbestimmungen im Zentimeterbereich möglich werden?
Vielen Dank.
hello when i compile it gives only the compilation error message with no error what should i do?