如何通过带有 c 的串行端口从带有 NMEA 协议的 GPS 模块获取数据 [英] How can I get data from a GPS module coming with NMEA protocol through a Serial port with c

查看:48
本文介绍了如何通过带有 c 的串行端口从带有 NMEA 协议的 GPS 模块获取数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要通过串行端口从采用 NMEA 协议的 GPS 模块获取数据,输入如下所示:

I need to get data from a GPS module which is coming in NMEA protocol through a Serial port, and the input looks something like this:

$GPRMC,190335.389,V,3754.931,N,08002.496,W,33.6,0.59,110619,,E*47$GPGGA,190336.389,3754.931,N,08002.496,W,0,00,,,M,,M,,*52$GPGLL,3754.931,N,08002.496,W,190337.389,V*33$GPVTG,0.59,T,,M,33.6,N,62.2,K*5C$GPRMC,190339.389,V,3754.932,N,08002.494,W,11.9,0.62,110619,,E*4D$GPGGA,190340.389,3754.932,N,08002.494,W,0,00,,,M,,M,,*52$GPGLL,3754.932,N,08002.494,W,190341.389,V*33

$GPRMC,190335.389,V,3754.931,N,08002.496,W,33.6,0.59,110619,,E*47 $GPGGA,190336.389,3754.931,N,08002.496,W,0,00,,,M,,M,,*52 $GPGLL,3754.931,N,08002.496,W,190337.389,V*33 $GPVTG,0.59,T,,M,33.6,N,62.2,K*5C $GPRMC,190339.389,V,3754.932,N,08002.494,W,11.9,0.62,110619,,E*4D $GPGGA,190340.389,3754.932,N,08002.494,W,0,00,,,M,,M,,*52 $GPGLL,3754.932,N,08002.494,W,190341.389,V*33

问题是,我只需要以 GPRMC 开头的行.问题是数据是异步的,例如,首先是一行的前半部分,然后是另一半和另一行的一些,依此类推.现在我怎样才能逐行获取输入并且只获取以 GPRMC 开头的输入.输入不断,我需要实时获得正确的线路.我怎么能用C做到这一点?

The thing is, I only need the lines starting with GPRMC. And the problem is the data is coming asynchronous, first comes the first half of a line, for example, then the other half and some of the other line and so on. Now how can I get the input line-by-line and only get the ones starting with GPRMC. The input is coming incessant and I need to get the correct line real-time. How could I do this with C?

我真的不知道如何从串行端口读取,我尝试了一些方法,但由于输入是异步的,我无法获得正确的行.哦,还有一件事,一行的最大长度是 83.

I don't really know how to read from a Serial port, I tried something but because the input's coming asynchronous, I couldn't get the correct lines. Oh, and one more thing, the maximum length of a line is 83.

这是我试过的一些代码,我知道它很糟糕

Here's some code I tried, I know it's bad

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;

}

推荐答案

GPS NMEA 0183是一种基于文本的协议,可以使用独立于平台的 C 语言标准库进行处理.
已经开发了许多库和解析器,您无需重新开发即可使用它们.

GPS NMEA 0183 is a text-based protocol and can be processed with a platform-independent C language standard library.
Many libraries and parsers have already been developed, and you can use them without redevelopment.

例如,您可以在 StackOverflow 站点上找到这篇文章:
NMEA 库 - nmeaINFO 为空/NMEA 库
linux串口的C GPS nmea解析器没有解析读缓冲区的最后一行
GPS NMEA 字符串的解析代码

For example, you can find this article on the StackOverflow site:
NMEA library - nmeaINFO empty / NMEA Library
C Gps nmea parser from linux serial port does not parse the last line of the read buffer
Parsing code for GPS NMEA string

其他网站:
使用 BOOST 的多平台串行接口:GPS 传感器和 OPENDDS - 第 I 部分/第二部分

这些是解析器,解析读取数据的库.
jacketizer/libnmea
kosma/minmea
MaJerle/GPS_NMEA_parser

These are parsers, libraries that parse the read data.
jacketizer/libnmea
kosma/minmea
MaJerle/GPS_NMEA_parser

在上述库中分析后,您应该只使用您想要的数据.

After analyzing in the above library, you should use only the data you want.

这篇关于如何通过带有 c 的串行端口从带有 NMEA 协议的 GPS 模块获取数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆