pdcira2
Posts: 13
Joined: 12/29/2003
Status: offline
|
the following is code for a simple eVC++ application that reads your location from your GPS device and writes it to file on your WinCE device. it accompanies the following post for Simple GPS helper App... 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
#include <windows.h>
// 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(hGPSPort);
hGPSPort = INVALID_HANDLE_VALUE;
return;
}
else
{
CloseHandle(hGPSPort);
}
}
// 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 );
}
|