Как я могу получить данные от модуля GPS, идущего с протоколом NMEA через последовательный порт с - PullRequest
0 голосов
/ 11 июня 2019

Мне нужно получить данные от модуля GPS, который идет по протоколу NMEA через последовательный порт, и вход выглядит примерно так:

$ GPRMC, 190335,389, V, 3754,931, N, 08002,496, Вт, 33.6,0.59,110619, Е * 47 $ GPGGA, 190336.389,3754.931, N, 08002,496, W, 0,00 ,,, М ,, М ,, * 52 $ GPGLL, 3754.931, N, 08002.496, Вт, 190337.389, В * 33 $ GPVTG, 0,59, Т ,, М, 33,6, Н, 62,2, К * 5C $ GPRMC, 190339.389, V, 3754.932, N, 08002.494, Вт, 11.9,0.62,110619,, * 4D Е $ GPGGA, 190340.389,3754.932, N, 08002,494, W, 0,00 ,,, М ,, М ,, * 52 $ GPGLL, 3754.932, N, 08002.494, Вт, 190341.389, V * 33

Дело в том, что мне нужны только строки, начинающиеся с GPRMC. И проблема в том, что данные поступают асинхронно, сначала идет, например, первая половина строки, затем вторая половина и часть другой строки и так далее. Теперь, как я могу получить вход за строкой и получить только те, которые начинаются с GPRMC. Вход поступает непрерывно, и мне нужно получить правильную линию в режиме реального времени. Как я мог сделать это с C?

Я действительно не знаю, как читать с последовательного порта, я что-то пробовал, но из-за асинхронного ввода я не смог получить правильные строки. Да, и еще одна вещь, максимальная длина строки 83.

Вот код, который я пробовал, я знаю, что это плохо

int a = 0;
int test = 0;
int gprmc_find(char* gps)
{
    while(a < strlen(gps))
    {
        if(gps[a] =='$' && gps[a+1] == 'G' && gps[a+2] == 'P' && gps[a+3] == 'R' )
        {
            test = 1;
            break;
        }
        else
        {
            test = 0;
        }
        a++;
        return test;
    }
}
int main()
{

DWORD  accessdirection =GENERIC_READ | GENERIC_WRITE;
HANDLE hSerial = CreateFile("COM4",
                            accessdirection,
                            0,
                            0,
                            OPEN_EXISTING,
                            0,
                            0);
if (hSerial == INVALID_HANDLE_VALUE) {
    printf("Invalid\n");
}

DCB dcbSerialParams = {0};
dcbSerialParams.DCBlength=sizeof(dcbSerialParams);
if (!GetCommState(hSerial, &dcbSerialParams)) {
     printf("could not get the state of the comport\n");
}
dcbSerialParams.BaudRate=9600;
dcbSerialParams.ByteSize=8;
dcbSerialParams.StopBits=ONESTOPBIT;
dcbSerialParams.Parity=NOPARITY;
if(!SetCommState(hSerial, &dcbSerialParams)){
     printf("Error\n");
}
COMMTIMEOUTS timeouts={0};
timeouts.ReadIntervalTimeout=50;
timeouts.ReadTotalTimeoutConstant=50;
timeouts.ReadTotalTimeoutMultiplier=10;
timeouts.WriteTotalTimeoutConstant=50;
timeouts.WriteTotalTimeoutMultiplier=10;
if(!SetCommTimeouts(hSerial, &timeouts)){
    printf("handle error1");
}
    char buf[83] = {0};
    while(1)
    {


        DWORD dwBytesRead = 0;

       //CloseHandle(hSerial);

        if(!ReadFile(hSerial, buf, 82, &dwBytesRead, NULL)){
            printf("handle error");
        }
        printf(" %d \n", test);
        if(gprmc_find(buf) == 1)
        {
            printf(buf);  
        }
        memset(buf, 0, 83);
        delay(1);
    }
    return 0;

}

1 Ответ

0 голосов
/ 12 июня 2019

GPS NMEA 0183 - это текстовый протокол, который можно обрабатывать с помощью независимой от платформы стандартной библиотеки языка C.
Многие библиотеки и парсеры уже разработаны, и вы можете использовать их без перепланировки.

Например, вы можете найти эту статью на сайте StackOverflow:
Библиотека NMEA - nmeaINFO пусто / Библиотека NMEA
C Парсер Gme nmea из последовательного порта linux не анализирует последнюю строку буфера чтения
Код разбора для строки GPS NMEA

Другой сайт:
МУЛЬТИПлатформенный последовательный интерфейс с использованием BOOST: GPS-ДАТЧИК И ОТКРЫТИЯ - ЧАСТЬ I / ЧАСТЬ II

Это парсеры, библиотеки, которые анализируют прочитанные данные.
jacketizer / libnmea
Косма / minmea
MaJerle / GPS_NMEA_parser

После анализа в вышеуказанной библиотеке вы должны использовать только те данные, которые вам нужны.

...