蓝牙模块设置成功后,主从模块LED灯长亮,见图3-5连接成功图。主模块能够主动搜索并发起连接,但是不能被其他蓝牙设备搜索到;从设备只能被搜索到,只能被动连接而不能主动搜索。
3.1.5主从模式配对
以上步骤为对蓝牙模块设置步骤。设置结束后便可将模块重新连接到相应的位置。重新打开开关,主设备自动搜索从设备并建立连接,蓝牙透传模块为心电手环与移动机器人搭建起了无线传输通道,传输通过无线串口进行。 3.2 串口通信 3.2.1交叉编译简介
交叉编译部分知识不在本论文详细研究的范围内,所以在此只对其做一些简要介绍。micro2440开发板上带有Linux系统,不能像在PC机上一样运行编写的程序,需要建立交叉编译工具链。本文选择在虚拟机上机上安装Fedora9.0系统作为其解决方案。具体安装过程不在详述。Fedora9.0安装完成后,在其中安装交叉编译器arm-linux-gcc-4.3.2。交叉
编译器安装成功后,用该编译器对程序进行编译,生成可执行文件,该文件便可以在带有Linux系统下的micro2440开发板上执行。 3.2.2 串口接收数据
蓝牙主从模块配对连接后,形成无线串口通路,下面介绍串口接收心电数据具体实现方式及实现代码。
首先定义char类型指针rbuf用于接收由串口发送过来的心率数据。然后打开串口,程序如下:
int open_serial(){ }
设置串口波特率为115200bps,波特率是串口通信时的速率。心电手环实时采集使用者的心率数据,将波特率设置为115200bps是为了保证传输数据能够及时传到移动机器人本体上。虽然相对低波特率功耗较大,考虑到系统属于医疗设备,为了保证系统的高效工作。设置波特率代码如下:
Cfsetispeed (&opt,B115200); Cfsetospeed (&opt,B115200);
在main函数中调用open_serial()函数打开串口3,定义int类型变量retv用于保存串口read()函数的返回值。read()函数是读取串口接收到的数据函数,包含3个参数。第一个参数为验证串口是否已经打开,当fd的值
fd = open(\perror (\
if( fd == -1)
return -1;
else
return 0;
为1时表示已经打开了。第二个参数是char类型指针,用于存放接收到的数据。第三个参数通常设置为1。
rbuf= btd; re=read(fd,rbuf,1); if(re==-1) perror(\
串口接收数据保存到char类型数组btd中,每次接收8位数据,数据类型为两个十六进制。心电数据格式为每帧有十个十六进制数据,其中帧头为EE,帧尾为FF,中间剩余六个十六进制数。这些是心率数据的有效值。接收到数据后对数据进行简单处理,通过网络编程发送到远程客户端,客户端对数据进行筛选和判断,正确识别使用者的健康状态。同时,对使用者的基本健康状况进行收集和建档,产生一个长时间的健康监控档案,为使用者提供长期有效的健康指导,也为日后的医疗就诊提供帮助。 3.3 网络编程
移动机器人上arm处理器通过串口接收到心率数据,需要通过无线网络发送到子女客户端。无线网络硬件系统以及设置方式已在上一章介绍完成,下面内容将详细讨论通过socket通信技术实现数据的传输。ARM处理器相当于服务器端,下面详细讲解服务器端如何通过socket通信向远程客户端发送心率数据。
第一步:初始化Socket。 代码如下:
if( (socket_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){ printf(\
error: %s(errno: %d)\\n\
socket
exit(0); }
Socket函数原型为int socket(int domain, int type, int protocol);它创建一个socket描述符,唯一标识一个socket。函数有三个参数。第一个参数表示协议族,其决定了socket的地址类型,AF_INET表示使用ipv4协议地址与端口号的组合。Type指定socket通信的类型。第三个参数是用来指定协议的,当把protocol设定为0时,函数将自动匹配通信类型所对应的通信协议。
第二步:设置IP和端口。服务器端自动获取到IP地址。 代码如下:
memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(DEFAULT_PORT); 第三步:将具体的本地地址与socket进行绑定。 代码如下:
if( bind(socket_fd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){
printf(\
error: %s(errno: %d)\\n\
exit(0); }
Bind函数原型为int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);本系统中代码完成的是将本地地址与端口号的组合赋给socket。Bind函数有三个参数。第一个参数是通过socket函数创建的唯
socket