http://forums.devbuzz.com/tm.asp?m=37186&p=1&tmode=1
// code should compile for any WinCE 3.x or higher based device // some of the code was taken from Nick Gratton and Marshall Brian's book... // Windows CE 3.0 Application Programming // defines and includes #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #includeCredit to pdcira2// function headers void openComPort(); DWORD WINAPI GPSReadThread(LPVOID); void ParseRMC(LPTSTR szSentence); // class level variables HANDLE hGPSPort = INVALID_HANDLE_VALUE; int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { // open the port openComPort(); // read some data and write it to file GPSReadThread(NULL); // close the port if(hGPSPort != INVALID_HANDLE_VALUE) { CloseHandle(hGPSPort); hGPSPort = INVALID_HANDLE_VALUE; } return 0; } void openComPort() { // hardcoded hear to COM port 1 hGPSPort = CreateFile (_T("COM1:"), // Port Name (Unicode compatible) GENERIC_READ | GENERIC_WRITE, // Open for Read-Write 0, // COM port cannot be shared NULL, // Always NULL for Windows CE OPEN_EXISTING, // For communication resource 0, // Non-overlapped operation only NULL); // Always NULL for Windows CE if(hGPSPort == INVALID_HANDLE_VALUE) { MessageBox(0, _T("Error Opening Comms Port."), _T(""), 0); return; } // set the timeouts to specify the behavior of reads and writes. COMMTIMEOUTS ct; ct.ReadIntervalTimeout = 1000; ct.ReadTotalTimeoutMultiplier = 0; ct.ReadTotalTimeoutConstant = 0; ct.WriteTotalTimeoutMultiplier = 10; ct.WriteTotalTimeoutConstant = 1000; if(!SetCommTimeouts(hGPSPort, &ct)) { MessageBox(0, _T("Error Setting Comm Timeouts."), _T(""), 0); CloseHandle(hGPSPort); hGPSPort = INVALID_HANDLE_VALUE; return; } // get the current communications parameters, and configure baud rate DCB dcb; dcb.DCBlength = sizeof(DCB); if(!GetCommState(hGPSPort, &dcb)) { MessageBox(0, _T("Error Getting Comms State."), _T(""), 0); CloseHandle(hGPSPort); hGPSPort = INVALID_HANDLE_VALUE; return; } dcb.BaudRate = CBR_4800; dcb.fOutxCtsFlow = FALSE; dcb.fRtsControl = RTS_CONTROL_DISABLE; dcb.fDtrControl = DTR_CONTROL_DISABLE; dcb.fOutxDsrFlow = FALSE; dcb.fOutX = TRUE; // XON/XOFF control dcb.fInX = TRUE; dcb.ByteSize = 8; dcb.Parity = NOPARITY; dcb.StopBits = ONESTOPBIT; if(!SetCommState(hGPSPort, &dcb)) { MessageBox(0, _T("Error Setting Comms State."), _T(""), 0); CloseHandle(hGPSPort); hGPSPort = INVALID_HANDLE_VALUE; return; } // give time for data to arrive into comm port Sleep(3000); // now need to create the thread that will be reading the comms port HANDLE hCommReadThread = CreateThread(NULL, 0, GPSReadThread, NULL, 0, NULL); if(hCommReadThread == NULL) { MessageBox(0, _T("Error Creating Thread."), _T(""), 0); CloseHandle(hCommReadThread ); hCommReadThread = INVALID_HANDLE_VALUE; return; } else { CloseHandle(hCommReadThread ); } } // Thread function reads NMEA output from GPS device DWORD WINAPI GPSReadThread(LPVOID) { DWORD dwBytesRead; char szSentence[1000], c; TCHAR szwcsSentence[1000]; int nc = 0; int counter = 0; SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL); while(hGPSPort != INVALID_HANDLE_VALUE) { if(!ReadFile(hGPSPort, &c, 1, &dwBytesRead, NULL)) { MessageBox(0, _T("Error Reading comms port."), _T(""), 0); return 0; // terminate thread on first error } if(dwBytesRead == 1) { if(c == '\n') // LF marks end of sentance { szSentence[nc - 1] = '\0';// remove trailing CR nc = 0; // ready to read next sentence if(strlen(szSentence) < 6) ; else if(szSentence[0] != '$') ; else { // have a sentence. convert to Unicode mbstowcs(szwcsSentence, szSentence, 1000); // find sentence ID if(wcsncmp(&szwcsSentence[3], _T("RMC"), 3) == 0) { ParseRMC(szwcsSentence); return 1; } } } else szSentence[nc++] = c; } } return 0; } // returns the next token from the sentence. LPTSTR GetNextToken(LPTSTR lpSentence, LPTSTR lpToken) { lpToken[0] = '\0'; if(lpSentence == NULL) // empty sentence return NULL; if(lpSentence[0] == '\0') // end of sentence return NULL; if(lpSentence[0] == ',') // empty token return lpSentence + 1; while(*lpSentence != ',' && *lpSentence != '\0' && *lpSentence != '*') { *lpToken = *lpSentence; lpToken++; lpSentence++; } lpSentence++; // skip over comma *lpToken = '\0'; return lpSentence; } // Parses a RMC sentence which has the format: // RMC,225446,A,4916.45,N,12311.12,W,000.5,054.7,191194,020.3,E*68 void ParseRMC(LPTSTR szSentence) { TCHAR szToken[20]; DWORD dwCheckSum = 0; FILE* stream; TCHAR* s = _T("|"); LPCWSTR seps = (const unsigned short *) s; for(UINT i = 1; i < wcslen(szSentence) && szSentence[i] != '*'; i++) dwCheckSum ^= szSentence[i]; // lpNextTok points at ID $GPRMS, ignore this szSentence = GetNextToken(szSentence, szToken); // Time of Fix, convert to Unicode szSentence = GetNextToken(szSentence, szToken); // Navigation receiver (GPS) warning szSentence = GetNextToken(szSentence, szToken); // Latitude szSentence = GetNextToken(szSentence, szToken); // write lat. to file stream = fopen( "\\location.txt", "w" ); fputws( szToken, stream ); fputws( seps, stream ); fclose( stream ); // Latitude N or S szSentence = GetNextToken(szSentence, szToken); // write N/S. to file stream = fopen( "\\location.txt", "a" ); fputws( szToken, stream ); fputws( seps, stream ); // Longitude szSentence = GetNextToken(szSentence, szToken); // write lon. to file fputws( szToken, stream ); fputws( seps, stream ); // Longitude W or E szSentence = GetNextToken(szSentence, szToken); // write W/E. to file fputws( szToken, stream ); fputws( seps, stream ); fclose( stream ); }
No comments:
Post a Comment