Forum: Mikrocontroller und Digitale Elektronik GPS NMEA Libary für Atmega32


von Hans W (Gast)


Lesenswert?

Hallo,

ich bin auf der Suche nach einer einfachen Libary um die NMEA Daten von 
diesem kleinen Modul auf einem Atmega32 auszuwerten:
http://www.amazon.de/niceeshop-Aircraft-Flight-Controller-Schwarz/dp/B00S4RLICU/ref=sr_1_1?ie=UTF8&qid=1459384658&sr=8-1&keywords=GY-GPS6MV2

Ich würde zwar gerne selbst einen Parser dafür programmieren aber leider 
habe ich wenig zeit um die ganze Sache zum Laufen zu bekommen.

In folge dessen Suche ich eine einfache Libary mit der ich den NMEA 
String den ich per UART bekomme in die einzelnen Werte (Position, 
Geschwindigkeit,...) decodiere und direkt in meinem hauptprogramm 
verwursten kann.

Die Suche im Internet hat mich dahingehend zugegebenermaßen ein wenig 
überfordert, da es da zig verschiedene Varianten gibt die ich auf die 
schnelle nicht in ein laufendes Projekt umgesetzt bekomme.

Daher die Frage: Kennt jemand eine Quelle oder hat jemand eine einfache 
und funktionierende Libary die ich benutzen kann?

von Fritz G. (fritzg)


Lesenswert?

Damit solltest du zurecht kommen, meine Besonderheiten musst halt 
rausnehmen.
1
/**
2
 *  @brief   Gibt den String nach dem n-ten Komma zurück
3
 *  @param   sentence Enthält NMEA Satz
4
 *  @param   n Nummer des Teilstrings
5
 *  @return  String
6
 */
7
8
char *readFieldByNumber (char *sentence, uint8_t n)
9
{
10
    static char result[100];
11
    char *p = sentence;
12
    
13
    while (n-- > 0)
14
        while (*p++ != ',') ;
15
    //    if (strlen(sentence)>=99) {
16
    //        printf_P(PSTR("sentence zu lang: %d\n%s\n"),strlen(sentence),sentence);
17
    //    }
18
    strncpy (result, p,100);
19
    result[99]=0;
20
    p = result;
21
    while (*p && *p != ',' && *p != '*' && *p != '\r')
22
        p++;
23
    
24
    *p = '\0';
25
    return result;
26
}
27
28
/**
29
 *  @brief   Parst den GGA Satz
30
 *  @param   data Enthält NMEA Satz GGA
31
 *
32
 * $GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47
33
 *  @return  none Daten sind in der Struktur gpspos
34
 */
35
36
void parseGGA(char *data) {
37
    char chksum[3];
38
    char value=0,csnum=0;
39
    char *csPointer;
40
    char tmp[5];
41
    float m;
42
    int16_t d;
43
    static uint32_t oldAge=0;
44
    float oldLat,oldLon;
45
    
46
    csPointer=(data+1);
47
    while(*csPointer != '*' ){
48
        value ^= *(csPointer++);
49
    }
50
    chksum[0]=*(++csPointer);
51
    chksum[1]=*(++csPointer);
52
    chksum[2]=0;
53
    csnum=strtol(chksum, NULL, 16);
54
    if (csnum!=value) {
55
        printf_P(PSTR("NMEA CS ! %s  %02x\n"),chksum,value);
56
        return;
57
    }
58
    
59
    oldLat = gpspos.lat;
60
    oldLon = gpspos.lon;
61
    
62
    gpspos.lat=atof(readFieldByNumber(data, 2));
63
    d=gpspos.lat/100;
64
    m=(gpspos.lat-100*d);
65
    gpspos.lat = d + m / 60.0;
66
    
67
    strncpy(tmp, readFieldByNumber(data, 3), 2);
68
    if (tmp[0]=='S') {
69
        gpspos.lat=-gpspos.lat;
70
    }
71
    gpspos.lon=atof(readFieldByNumber(data, 4));
72
    d=gpspos.lon/100;
73
    m=(gpspos.lon-100*d);
74
    gpspos.lon = d + m / 60.0;
75
    
76
    gpspos.alt=atof(readFieldByNumber(data, 9));
77
    
78
    strncpy(tmp, readFieldByNumber(data, 5), 2);
79
    if (tmp[0]=='W') {
80
        gpspos.lon=-gpspos.lon;
81
    }
82
    gpspos.fix=strtol(readFieldByNumber(data, 6), NULL, 10);
83
    gpspos.sats=strtol(readFieldByNumber(data, 7), NULL, 10);
84
    //  Horizontal dilution
85
    gpspos.hdop=atof(readFieldByNumber(data, 8));
86
87
    //    printf_P(PSTR("lat: %f lon: %f fix:%d sats: %d Zeit: %s %d\n"),
88
    //             gpspos.lat,gpspos.lon,gpspos.fix,gpspos.sats,gpspos.utc,strlen(data));
89
    if (gpspos.fix>0) {
90
        oldAge = uptimeCounter;
91
    } else {
92
        // Nicht 0.0 anzeigen, weil letzte Position angezeigt werden soll bei Fixverlust
93
        gpspos.lon = oldLon;
94
        gpspos.lat = oldLat;
95
    }
96
    gpspos.age = uptimeCounter - oldAge; // Zeit in Sekunden seit letzter Position
97
    return;
98
}
99
100
101
/**
102
 *  @brief   Parst den GZA Satz
103
 *  @param   data Enthält NMEA Satz GZA (Datum und Zeit)
104
 *
105
 *  $GPZDA,194916.00,09,06,2015,00,00*6D
106
 *  @return  none Daten sind in der Struktur gpspos
107
 */
108
109
void parseZDA(char *data) {
110
    char chksum[3];
111
    char value=0,csnum=0;
112
    char *csPointer;
113
    char *p;
114
    static uint8_t needDateCounter=0;
115
    
116
    csPointer=(data+1);
117
    while(*csPointer != '*' ){
118
        value ^= *(csPointer++);
119
    }
120
    chksum[0]=*(++csPointer);
121
    chksum[1]=*(++csPointer);
122
    chksum[2]=0;
123
    csnum=strtol(chksum, NULL, 16);
124
    if (csnum!=value) {
125
        printf_P(PSTR("NMEA CS ! %s  %02x\n"),chksum,value);
126
        return;
127
    }
128
    
129
    strncpy(gpspos.date, readFieldByNumber(data, 4),4); // Jahr
130
    strncpy((gpspos.date+4), readFieldByNumber(data, 3),2); // Monat
131
    strncpy((gpspos.date+6), readFieldByNumber(data, 2),2); // Tag
132
    gpspos.date[8]=0;
133
    
134
    p=strncpy(gpspos.utc, readFieldByNumber(data, 1),sizeof(gpspos.utc));
135
    if (debugOut) {
136
        printf_P(PSTR("ZDA Zeit: %s(%d bytes)"),gpspos.utc,strlen(p));
137
    }
138
    if (strlen(p)==0) {
139
        strncpy(gpspos.utc,"---------",sizeof(gpspos.utc));
140
        if (gpsBattGood!=0) {
141
            gpsBattGood--;
142
        }
143
    } else {
144
        if (need_setDate!=0) {
145
            needDateCounter++;
146
            if (needDateCounter>30) {
147
                setGPSDate();
148
                needDateCounter = 30;
149
            }
150
        }
151
    }
152
    
153
    // GPS in Powersave schicken
154
    if (uBattAvg>POWERSAVELIMIT) {
155
        if (gpsIsPowerSave) {
156
            switchGpsPowersave(0);
157
        }
158
    } else {
159
        if (!gpsIsPowerSave) {
160
            switchGpsPowersave(1);
161
        }
162
    }
163
    
164
    return;
165
}

von Hans W (Gast)


Lesenswert?

Oh super damit komme ich auf den ersten Blick zurecht vielen Dank :-)

von Christian O. (hightec)


Lesenswert?

Oh Sorry, ich hatte tatsächlich vergessen mich anzumelden

Ich bins ;-)

Gruß

Christian

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.