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
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?
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;
}