本帖最后由 friendyh 于 2015-2-6 19:57 编辑
BBB使用串口主要是接收MU6050加速度与角速度传感器的数据。MPU-6000(6050)为全球首例整合性6轴运动处理组件,MPU-6000(6050)的角速度全格感测范围为±250、±500、±1000与±2000°/sec (dps),可准确追踪快速与慢速动作,并且,用户可程式控制的加速器全格感测范围为±2g、±4g±8g与±16g。该传感器使用在智能型手机,平板装置设备,手持型游戏产品,游戏机,3D遥控器,可携式导航设备等上面。这个是在淘宝上买买的,图片如下:
这样两边都是半孔,不好焊接,建议大家使用的时候再买一个串口MPU6050底板,可以转换成圆孔,这样焊接方便。
BBB启动后不会自动加载串口设备。根据另外一篇帖子,帖子链接如下: 如果要使得BBB自动加载串口设备,需这样设置: 在Angstrom系统下,USB连接好BBB以后在电脑里会出现一个盘符,里面有一个叫做uEnv.txt的文件。通过它可以设置系统启动时加载或禁止加载的dtbo。比如我想在系统启加载BB-UART2。我们就可以打开它,在下面添加一行: optargs=quiet capemgr.enable_partno=BB-UART2. 然后安全弹出这个盘符,重启BBB就行啦。如果要禁用HDMI,就在这里面加上一行 optargs=quietcapemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN 我不使用HDMI,所以把HDMI关闭了。帖子里面说这两行必须合并成一行才有效,但我试过之后不行,我的板子这两行要分开写才有效,也许是因为系统版本不一样的缘故。 之前以为Linux串口编程是很简单的事情,可是经过这次使用串口,发现串口还是有很多需要注意的细节。这个链接: 对串口编程的每个参数都进行了比较详细的介绍,或者大家也可以查看相关的书籍。 这个帖子:
是对BBB串口操作的介绍,串口的每个引脚如下图所示: 根据BBB用户手册的介绍: 这里面我使用的是串口2.将串口MPU6050的TX引脚接到BBB的9_22引脚,将串口MPU6050的RX引脚接到BBB的9_21引脚,将串口MPU6050的VCC引脚接到BBB的9_3引脚(3.3v电压),将串口MPU6050的GND引脚接到BBB的9_1引脚。
根据串口MPU6050说明书提供的示例代码: 我编写了用while循环读取串口数据的代码,运行没有问题。可是如果在程序中先用while循环读取一段时间数据,然后sleep一段时间,再用while循环读取数据,就时不时的读取不到数据,程序就会卡在读取的这一步,一直等待。刚开始我也没在意这个问题,以为是硬件的问题。于是我换了BBB和串口MPU6050的四根线,又更换了串口,从串口2换到串口5,可是还是出现这个问题。因为四轴飞行器在飞行过程中不是一直读取传感器数据的,中间还要控制四个PWM转速,如果在读取过程中卡主了,就不能执行其他的代码,也就没有PWM信号,飞机就会掉下来,把上面的器件摔坏,很危险。
于是我就仔细研究代码,在BBB上面单步调试串口的这个程序,看看是什么问题,后来找到原因了。根据MPU6050说明书: MPU6050发出的每个数据包都是11个字节,循环发送3个数据包,所以参考程序中将读取的buffer设置为11个字节。这样子就会出现问题,角度数据包的前两位是十六进制的55和十六进制的53,代码中必须先检测到前两位是这两个字符,然后才去解析后面9个字节的数据,但是如果没有检测到这两个字符,代码就把读取到的这11个字符丢弃,读取接下来的11个字符,然后再判断是不是这两个字节,如果不是,再丢弃,然后读取,再判断。除非第一次读取的时候正好碰到前两个字符是十六进制的55和十六进制的53,那么可以得到正确的数据,之后读取的11个字节的数据前两位正好也是55和53。如果第一次不是这两个字符,将会一直循环判断,永远也找不到正确的前两个字符。这就是为什么程序读取不到串口数据的原因。
要解决这个问题,必须要找到前两个标识字符,就是55和53。因此每次读取11个字节不够。MPU6050发出的每个数据包都是11个字节,循环发送3个数据包,我只需要的是最后一个角度数据包。根据数学计算,每次读取43个字节肯定能至少读取到一个完整的角度数据包。然后去判断头两个字符,如果不是55和53,就让指针后移,直到找到这两个字符,然后进行数据解析。代码如下:
tcflush(SerFd,TCIOFLUSH); for(i=0;i<200;i++) //浼犳劅鍣ㄦ暟鎹? { nTmp= read_datas_tty(SerFd, buff, 100, 43); if(nTmp) { while(!(buff[uartweiyi]==0x55&&buff[uartweiyi+1]==0x53)) //妫€鏌儏抚澶? { uartweiyi++; } switch(buff[uartweiyi+1]) { case 0x53: angle[0]= ((short)(buff [uartweiyi+3]<<8| buff [uartweiyi+2]))/32768.0*180; angle[1] = ((short)(buff[uartweiyi+5]<<8| buff[uartweiyi+4]))/32768.0*180; angle[2] =((short)(buff[uartweiyi+7]<<8| buff[uartweiyi+6]))/32768.0*180; ox+=angle[0]; oy+=angle[1]; oz+=angle[2]; jianceu ++;//妫€娴嬪埌鏁版嵁 printf("%f %f%f\n",angle[0],angle[1],angle[2]); break; } } uartweiyi=0;
} 在linux下面填写的注释在windows记事本下面打开是乱码。还有一个问题要注意,之前我发现经常读取到的数据不是当前传感器的数据。这是因为LINUX系统会把读取到的串口数据先放到一个缓存中,然后再从缓存中读取数据,因此读取到的数据不一定是当前值,这个和单片机不一样。四轴飞行器需要的是当前三个角度,也就是俯仰角,横滚角和偏航角,根据这三个角度来自动进行调整。要解决这个问题,再每次读取数据前,使用tcflush函数清空缓存即可,该函数有几个参数可选: TCIFLUSH 清除正收到的数据,且不会读取出来。 TCOFLUSH 清除正写入的数据,且不会发送至终端。 TCIOFLUSH 清除所有正在发生的I/O数据。 把这两个问题解决后,BBB就可以读取到当前时刻的传感器数据,并且不会出现程序找不到数据包标志字符的情况。
BBB连接MPU6050传感器的图片如下:
|