sPositionX+=strGPS.GetAt(i); break;
default:
break;
}/*End switch*/
}/*End if*/
}/*End for*/
}/*End if*/
If (sGpsStatus == "A") {…… //如果GPS信号状态有效,做相应的处理}
}
以上的GPS数据读取方法,在利用SD卡式样的GPS接收机或CF卡式样的GPS接收机情况下,在大部分PDA上均能调试通过,程序能可靠的运行。部分利用 蓝牙 GPS接收机作为GPS模块的PDA中,一般只要找到对应的虚拟串口,程序中数据的读取与普通的串口读取方法类似,用户可以通过Holux的GPSViewer查找到对应的串口。
4. 模拟串口解决方法所遇到的问题
大显CU928机型是一款性价比较高的机型:处理器采用Intel PXA 263的400MHz CPU和高通MSM5500芯片组;内存容量为64MB;具有SD/MMC扩展能力;操作系统为MICroSOFt Wireless Mobile 2003 Pocket Phone Edition ;支持WAP浏览器,支持红外接口,内置 蓝牙 接口。
以上介绍的方法虽然对大部分的PDA切实可行,但笔者在使用大显CU928机型时发现,PDA开发蓝牙 GPS 数据采集 程序时,用GPS Viewer时可发现虚拟串口,并且用该程序接收数据也正常。但在用上述的程序实现方法访问对应的串口时,打开串口正常,但接受不到GPS数据。通常的解决方法是在应用软件和蓝牙设备之间再添加一个应用软件,如GPS GATE,笔者没有做这样的尝试,因为添加应用软件会降低系统的可靠性,同时也提高软件的最终成本。
5. 一种新的改进思路
所有的I/O操作都是通过读写文件描述符而产生的,文件描 述符是一个和打开的文件相关联的整数,这个文件并不只包括真正存储在磁盘上的文件,还包括一个网络连接、一个命名管道、一个终端等,而套接口就是系统进程和文件描述符通信的一种方法。目前最常用的套接口是字:字节流套接口(基于TCP)和数据报套接口(基于UDP)。为了执行网络输入输出,一个进程必须做的第一件事就是调用 Socket 函数获得一个文件描述符。当用socket建立了套接口后,可以调用connect为这个套接字指明远程端的地址;如果是字节流套接口,connect就使用三次握手建立一个连接;如果是数据报套接口,connect仅指明远程端地址,而不向它发送任何数据。
基于连接的TCP方式。以该模式编程时,服务端有一个进程(或多个进程)在指定的端口等待客户来连接,服务程序等待客户的连接信息,一旦连接上之后,就可以按设计的数据交换方法和格式进行数据传输。在本系统中,蓝牙GPS接收机(被发现设备)作为一个服务器端,接收客户端(手机蓝牙接收模块)在发出的服务端连接请求。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。同时能保证数据到达的先后顺序。
另外一种socket的通信方式是基于无连接的UDP数据通信。使用无连接的UDP协议时,服务端进程创建一个socket,之后调用recvfrom接收客户端的数据报,然后调用sendto将要返回客户端的消息发送给客户进程。客户端也要先创建一个socket,再使用sendto向服务端进程发出请求,使用recvfrom得到返回的消息。该通信方式是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。
在GPS应用中,数据到达的顺序有一定的要求影响,本系统采用前一种基于连接的方式。将蓝牙GPS数据接收部分模拟成网络形式,在可靠的连接上读取GPS数据。
6. 改进方法的代码实现
首先,建立PDA与蓝牙GPS的连接,以下代码说明了建立Socket连接的过程
WSADATA wsd;
WSACleanup();
int i = WSAStartup(MAKEWORD(1,1), &wsd);
if (i)//Initialization socket faiLED
{
…//显示错误消息,返回
}
m_btSocket = socket(AF_BT, SOCK_STREAM, BTHPROTO_RFCOMM);
if (m_btSocket == INVALID_SOCKET) //create socket failed
{
…//显示错误消息,返回
}
SOCKADDR_BTH sa;
MEMSet (&sa, 0, sizeof(sa));
sa.addressFamily = AF_BT;
sa.btAddr = 0x0000*********
www.55dianzi.com
*; // 蓝牙 GPS 物理地址
定义sa.servICeClassId.Data4[7]=0xFB;
sa.port = 1;
if (connect(m_bt Socket , (SOCKADDR *)&sa, sizeof(sa)))
{
str.Format(_T("CONNCET faiLED %d %04x %08x"),WSAGetLastError (),GET_NAP(sa.btAddr), GET_SAP(sa.btAddr));
m_status.SetWindowText(str);
closesocket (m_btSocket);
}
else
{
SOCKADDR_BTH sa3;
int len;
if (0 == getsockname(m_btSocket, (SOCKADDR *)&sa3, &len))
…//显示Socket连接成功信息
& nbsp; m_status.SetWindowText(str);
}
pThreadRecv=::AfxBeginThread(_RecvThread, m_btSocket); //开始TCP线程
在接收线程中,将接收到的GPS数据提取所需要的信息即可。
while(recv(m_btSocket,readBuf,256,0))
{…//处理接收到的GPS数据}
GPS数据提取部分与以上介绍的方法相同。
7. 结论
本文创新点:基于Windows Mobile的蓝牙GPS 数据采集 方法的改进,将通常的蓝牙GPS虚拟串口数据采集方法转换成基于Socket通信方法,解决了部分系统由于在虚拟串口过程中不一致而导致无法从虚拟串口中读取数据的问题,以上的解决方法在CU928机型接收蓝牙GPS数据的中已经调试成功。该解决方法已经在一个监控系统中取得成功的应用,该解决方法对类似的蓝牙通信方案应用有一定的参考和实用价值。
参考文献
[1] 汪兵 李存斌 陈鹏/等编著,《EVC高级编程及其应用开发》,中国水利水电出版社
[2] 洪大永/编著,《GPS全球定位系统技术及其应用》厦门大学出版社
[3] 曹双贵富魏蒋芹韩晓春. 基于蓝牙和多线程技术的网络化数采系统[J]微计算机信 息2005,21
[4] PAUL A.LONGLEY/等编著 唐中实/等译 《地理信息系统(原理与技术)第二版》, 电子工业出版社
[5] BJARNE STROUSTRUP,贝尔实验室/编著 裘宗燕/译,《C++程序设计语言》,机械工业出版社
[7] 马建仓等编著,《蓝牙核心技术与应用》 第一版 北京 科学出版社
[8] 陆小锋,陆亨立,张芳琴. GPRS 与GPS 在汽车信息服务系统中的设计应用[J]微计算机信息2005,3:188- 189