Este código tiene una función que lee los datos enviados por un GPS Bluetooth en una PDA con Windows Mobile 2003 SE, está desarrollado en C++ con VS 2005.
En este caso particular el GPS no está integrado en la PDA envía los datos en formato NMEA a través de una conexión Bluetooth. Al puerto Bluetooth lo podemos leer como un puerto COM más, solo tenemos que saber de antemano cual es el número de los puertos COM de entrada y de salidada del Bluetooth. Esto podemos hacerlo leyendo el registro de la PDA, en mi caso particular es el "COM5:". Una vez que conocemos el puerto que tiene la función de Bluetoot in, leemos los datos con la función ReadFile como con cualquier puerto COM en la PDA o en Windows. La función lee los datos almacenados en el puerto, estableciendo previamente algunos parámetros como velocidad, timeouts y buffers, luego falta procesar los datos obtenidos (en este caso los datos vienen en formato NMEA, hay que procesarlos para obtener los valores de Latitud, Longitud, cantidad de satélites, etc). De la misma manera podemos utilizar esta función o alguna similar para obtener los datos de cualquier dispositivo que envíe a un puerto COM, ya sea en el dispositivo móvil o en nuestra aplicación Windows.
Este es solo un ejemplo, estableciendo algunos valores solo para mostrar como se hace, y guardando los resultados obtenidos en un array local, sin procesarlos luego, es probable que haya que hacerle algunos retoques a la hora de ponerlo en práctica en un programa real.
/*en la parte de definiciones*/
bool PuertoCom(wchar_t *Port);
/*Para llamar la función, por ejemplo al hacer clic en algún botón*/
bool result;
result = PuertoCom(L"COM5:");
if (result == true){
MessageBox(hWnd, L"Se leyeron los datos del puerto", L"OK:", MB_ICONINFORMATION | MB_OK);
}else{
MessageBox(hWnd, L"No se puede abrir, leer el puerto", L"ERROR:", MB_ICONERROR | MB_OK);
}
/*Implementación de la función*/
bool PuertoCom(wchar_t *Port){
HANDLE PCom;
OVERLAPPED ov;
DCB dcb;
COMMTIMEOUTS to;
DWORD x;
COMSTAT cs;
char tmp[1024];
wchar_t buf[1024];
//abrir el puerto
PCom = CreateFile(Port, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if(PCom ==INVALID_HANDLE_VALUE) return false;
//Obtener los timeouts actuales del puerto
if (GetCommTimeouts(PCom, &to) == 0) return false;
//Setear timeouts en el puerto
to.ReadIntervalTimeout = MAXDWORD;
to.ReadTotalTimeoutMultiplier = 0;
to.ReadTotalTimeoutConstant = 0;
to.WriteTotalTimeoutMultiplier = 0;
to.WriteTotalTimeoutConstant = 0;
if (SetCommTimeouts(PCom, &to) == 0) return false;
//setear buffers del puerto
if (SetupComm(PCom, 1024, 1024) == 0) return false;
//Obtener estado del puerto
if (GetCommState(PCom, &dcb) == 0) return false;
//Setear estado del puerto
dcb.BaudRate = (DWORD)38400; //Velocidad;
dcb.ByteSize = (BYTE)8; //NBits;
dcb.Parity = (BYTE)0; //Paridad;
dcb.StopBits = (BYTE)1; //StopBits;
if (SetCommState(PCom, &dcb) == 0) return false;
//Leer datos del puerto
if (ReadFile(PCom, tmp, 1024, &x, &ov) != 0){ //almacenamos en tmp los datos leídos del puerto
int a = strlen(tmp);
BSTR unicodestr = SysAllocStringLen(NULL, a);
::MultiByteToWideChar(CP_ACP, 0, tmp, a, unicodestr, a);
wcscpy(buf ,unicodestr); //convertir la cadena char devuelta por ReadFile en wschar_t
::SysFreeString(unicodestr);
}
//Cerrar puerto com
SetCommMask(PCom, 0);
CloseHandle(PCom);
return true;
}
En este caso particular el GPS no está integrado en la PDA envía los datos en formato NMEA a través de una conexión Bluetooth. Al puerto Bluetooth lo podemos leer como un puerto COM más, solo tenemos que saber de antemano cual es el número de los puertos COM de entrada y de salidada del Bluetooth. Esto podemos hacerlo leyendo el registro de la PDA, en mi caso particular es el "COM5:". Una vez que conocemos el puerto que tiene la función de Bluetoot in, leemos los datos con la función ReadFile como con cualquier puerto COM en la PDA o en Windows. La función lee los datos almacenados en el puerto, estableciendo previamente algunos parámetros como velocidad, timeouts y buffers, luego falta procesar los datos obtenidos (en este caso los datos vienen en formato NMEA, hay que procesarlos para obtener los valores de Latitud, Longitud, cantidad de satélites, etc). De la misma manera podemos utilizar esta función o alguna similar para obtener los datos de cualquier dispositivo que envíe a un puerto COM, ya sea en el dispositivo móvil o en nuestra aplicación Windows.
Este es solo un ejemplo, estableciendo algunos valores solo para mostrar como se hace, y guardando los resultados obtenidos en un array local, sin procesarlos luego, es probable que haya que hacerle algunos retoques a la hora de ponerlo en práctica en un programa real.
/*en la parte de definiciones*/
bool PuertoCom(wchar_t *Port);
/*Para llamar la función, por ejemplo al hacer clic en algún botón*/
bool result;
result = PuertoCom(L"COM5:");
if (result == true){
MessageBox(hWnd, L"Se leyeron los datos del puerto", L"OK:", MB_ICONINFORMATION | MB_OK);
}else{
MessageBox(hWnd, L"No se puede abrir, leer el puerto", L"ERROR:", MB_ICONERROR | MB_OK);
}
/*Implementación de la función*/
bool PuertoCom(wchar_t *Port){
HANDLE PCom;
OVERLAPPED ov;
DCB dcb;
COMMTIMEOUTS to;
DWORD x;
COMSTAT cs;
char tmp[1024];
wchar_t buf[1024];
//abrir el puerto
PCom = CreateFile(Port, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if(PCom ==INVALID_HANDLE_VALUE) return false;
//Obtener los timeouts actuales del puerto
if (GetCommTimeouts(PCom, &to) == 0) return false;
//Setear timeouts en el puerto
to.ReadIntervalTimeout = MAXDWORD;
to.ReadTotalTimeoutMultiplier = 0;
to.ReadTotalTimeoutConstant = 0;
to.WriteTotalTimeoutMultiplier = 0;
to.WriteTotalTimeoutConstant = 0;
if (SetCommTimeouts(PCom, &to) == 0) return false;
//setear buffers del puerto
if (SetupComm(PCom, 1024, 1024) == 0) return false;
//Obtener estado del puerto
if (GetCommState(PCom, &dcb) == 0) return false;
//Setear estado del puerto
dcb.BaudRate = (DWORD)38400; //Velocidad;
dcb.ByteSize = (BYTE)8; //NBits;
dcb.Parity = (BYTE)0; //Paridad;
dcb.StopBits = (BYTE)1; //StopBits;
if (SetCommState(PCom, &dcb) == 0) return false;
//Leer datos del puerto
if (ReadFile(PCom, tmp, 1024, &x, &ov) != 0){ //almacenamos en tmp los datos leídos del puerto
int a = strlen(tmp);
BSTR unicodestr = SysAllocStringLen(NULL, a);
::MultiByteToWideChar(CP_ACP, 0, tmp, a, unicodestr, a);
wcscpy(buf ,unicodestr); //convertir la cadena char devuelta por ReadFile en wschar_t
::SysFreeString(unicodestr);
}
//Cerrar puerto com
SetCommMask(PCom, 0);
CloseHandle(PCom);
return true;
}
Comentarios