@SiberiaBear
2015-10-22T10:38:59.000000Z
字数 3176
阅读 1973
Edison
固定链接:https://www.zybuluo.com/SiberiaBear/note/198035
在最近的2个星期中,我与另外一位小伙伴一起学习了用Edison模块来控制ble蓝牙模块的实验,当然是自己探索,最后基本实现了通信的功能,但是仍然有一些问题有待改进,当然也值得我们更加深入的学习Edison。现在把这段时间的学习进度和心得整理如下。
HC-06
,可以上网上查。具体是这样的: HC-06是采用CC2540F256芯片的一种单模式低功耗蓝牙解决方案,采用8051型MCU,128k或256k内建快闪记忆体,8kSRAM,完整整合了无线射频低功耗蓝牙模块。
TXD-1
RXD-2
RST-11
VCC-12
GND-13
KEY-26
LED-24
GND-22
其中后边接的数字是引脚号,如果我写错了不要怪我哦,自己查手册最有保障。供电最好3.3V,手册推荐的,我也试过用5V,反正能用没烧。
其中LED我认为挺方便的,在后边的调试时帮我解决了一个很大的问题,所以推荐接上,LED的指令是这样的:
- 主机未记录从机地址时:每秒100ms
- 主机记录从机地址时:每秒900ms
- 从机:每2s亮1s
- 通信连接后:常亮
最后注意:蓝牙模块在未连接时可以通过AT类指令操作蓝牙,连接后进入串口透传模式。这也是挺坑爹的地方,为什么?因为每次想配置蓝牙时,都要招呼小伙伴把他们的蓝牙关掉,因为会自动连接上。
该蓝牙的使用特别简单,当周围环境中该型号的蓝牙只有一个时可以上电并对其进行配置,留出来的接口命令有:
AT //检查模块是否正常,正常返回OK
AT+RX //查看模块基本参数,返回基本参数
AT+VERSION //获取当前版本、日期
AT+ROLE=X //X可取M或S,分别代表设置主机或从机,正常返回OK
AT+NAME=XXX //修改蓝牙名称,XXX可取任何字符串,代表蓝牙名称
等等等等,我就不列举了,可以上网查资料。
首先,将蓝牙与Edison通过UART接口相连,不管是breakout板子还是arduino板子,都可以有UART接口引出。其次,通过在Edison上调用mraa库的uart函数来与蓝牙模块通信。最后,实现用Edison板子发送配置命令到蓝牙模块来配置蓝牙状态,同时可以通过该蓝牙与另一个板子上的蓝牙通信。
插一句,Edison本身就有BLE低功耗蓝牙,所以这次实验仅仅是为了学习,没有太多实际的用途,通过该实验可以学习Edison的uart操作(mraa库对uart的操作),以及ble的基本通信方式,当然还有调试成功时满满的成就感。
第一阶段:
第一阶段当然是调试ble模块,将ble模块通过uart转usb串口线连接到PC,通过PC串口助手调试ble,当然,很简单,将PC串口助手调通就行,然后发送啥命令就是啥命令。
第二阶段:
在Edison上开发程序,实现与PC的UART通信,这部分是最主要工作。在Edison上,我们使用的串口是ttyMFD1,是Edison上是UART1,ttyMFD0英特尔为我们设置成了UART0,暂时还不知道怎么使用。
然后就是我调试这个实验的血雨史。
首先,我通过mraa库完成了基本的通信功能,可是,在与PC串口助手通信时,PC发送的指令无法发给Edison,Edison上并没有显示,最初以为是读buf出了问题,认为mraa_uart_read()
函数使用不正确。后来发现并不是这个问题,该函数的使用正确,而问题出在需要在串口助手发送字符串时,最后加一个回车,也就是人工加一个字符串结束符才可以,Edison正常接收。Edison的发送没有问题。
然后,我尝试将两个蓝牙模块进行通信,将蓝牙接到PC上直接控制,发现无法配置蓝牙,大概犹豫了5分钟,突然发现另一个蓝牙已经接到了所有的数据,自此之后才发现该蓝牙芯片是可以自动连接的,所以就有了前边的那些陈述。
mraa_uart_write(uart1, writebit, strlen(writebit))
函数中的strlen函数计算实际长度来发送即可。调试该问题时可以在PC串口助手上设置为使用十六进制数值接收,就可以看到多余的00,就是空白字符了。mraa_uart_read(uart1, readbit, READBUFSIZE)
函数读取字符串时,最多读取71个字符,其实至今不知道为什么是71,不过问题原来是出在了fscanf()
函数中,当我使用该函数读取键盘输入值时,会丢失大于71个字符的数据,但后来改成了使用getchar()
循环来读取键盘输入值,就不会丢失任何字符了,可以无限接收字符。有一个一直没有解决的问题,将整个系统建立完成后,Edison1为breakout板子扩展的uart,Edison2为arduino板子扩展的uart,问题是:通过Edsion2控制的ble可以发送任意不带字符结束符的字符串给Edison1,可以正常接到;但是通过Edison1发送的不带字符结束符的字符串给Edison2,Edison2无法接到,而唯独携带字符结束符才可以被Edison2接收。但,Edison1对ble1的配置命令需要不带字符结束符(当然,如上所说的所有不带字符结束符都是指在程序里不显式的添加字符结束符),所以Edison1的ble1无法正常使用。
另外,经测试,Edison2其实接收到了Edison1不带字符结束符的字符串,但是Edison2却接收到了该字符串,只是无法被mraa_uart_read()
函数读取,准确的说是mraa_uart_available()
函数并没有认为当前满足了读取buf的条件,直到字符结束符接到时才满足了条件。BUT!,同样的程序写入到两个板子里,为什么breakout板子没有问题,但是arduino板子有问题?会是硬件的问题吗?
10月22日:这个问题的解决办法是:我没有深刻的理解字符串结束符中的'\0'与'\n',我在发送一个字符串(比如AT
)时,默认给这个字符串加了一个'\n'结束符,并认为这个是字符串的结束符,由于程序是通过getchar()
函数一个个的接收字符,所以最终组成的字符数组并没有由系统自动添加字符串结束标志'\0',而是由我添加了一个'\n',当然我不是故意添加的,getchar()
函数会捕获键盘输入的一个字符串的最后一个字符,也就是'\n'。所以,最后解决办法是,判断当前最后一个字符串的值是不是'\n',如果是就转换成'\0',这样就可以正常发送。