暑假为了参加比赛做项目买了青风的nrf52832开发板,研究蓝牙mesh组网,最终系统跑起来的效果还是不错的,不料还没来得及优化系统,就已经被告知初赛落选,甚是无奈。手上还有十几片剩下的芯片,于是开始寻思做点什么好玩的小东西,考虑自身能力和时间都是有限的,以及外出旅游时拍照的各种不爽,遂决定做个简单的小自拍器。
将就
我的代码是参照开发板的自拍器例程写的,因为青风的开发板配套的例程使用的SDK版本太老了,所以我参照他写的教程,把相关代码移植到了最新的SDK example里,下载运行似乎一切正常,但是当我在手机上取消配对,然后重新连接的时候,发现从机(自拍器)是拒绝配对的,但是其他已经跟自拍器配对的手机还可以正常连接,很迷茫,去百度搜,查到一篇博客是关于nrf52832实现自拍器的,但是博主用的SDK似乎也是较老的版本,许多变量和函数在新版SDK里面并没有找到。一番度娘之后并没有发现能对解决问题有帮助的任何信息。所以我把问题丢到了群里,但却就像是石沉大海。我无奈了,暑假做项目的时候只是大概了解了mesh协议栈,对于BLE协议栈没有啥深入的了解,许多问题并不能自行解决,网上的参考资料又是少之又少,猛然感觉学STM32是一件多么幸福的事情---有那么多的资料参考。所以我们暂时放弃了,简单的优化了一下代码,把日志打印去掉,所有无关东西砍掉,降低功耗,把所有的功能通过一个按键实现。这样子一个不完美的自拍器就做完了,如果你取消了配对,想要再次连接只能在开机的时候按下按键来清除所有绑定信息。
不将就
一个多月过去了,当我收到从某东低价撸来的自拍器时,我震惊了,它是那么的好用!于是我再次拾起信心,一定要解决这个问题,时隔许久的今天,我装好了开发环境,打开了我的bug代码,尝试了多种不同的办法
NO1
在上电的时候清除所有绑定信息
然后突然发现,如果这样的话,其他绑定的手机岂不是就gg了?所以放弃了。
NO2
在断开连接的时候(断开和取消配对其实都是触发这个事件),清除所有绑定信息,同理,这样也是跟NO1一样,放弃。
NO3
于是我顺着delete_bonds()往上层找,寻找真正清除设备的地方,看看能不能只删除一个指定的设备。果然不出所料,在ret_code_t pm_peers_delete(void)里面是通过一个while循环将设备逐个清除的。瞬间看到了希望。
将删除单个设备的函数放在ble_evt_handler断开连接的位置执行,下载代码发现跟之前一样,并没有成功删除设备。
查了一下手册发现,这个函数只能在断开连接的时候执行,否则结果将无法预测,所以我把条删除语句放到了bsp事件断开连接那里,结果还是不行。
后来偶然发现了一个pm_evt_handler,看了一下所有的事件,并没有断开连接事件,但是有一个连接失败事件 PM_EVT_CONN_SEC_FAILED ,在后面加了一条case,编译下载运行,发现在取消配对连接失败之后,再次重启之后就能正常连接了,但是这样还是不完美啊。后来我又发现了另外一个事件 PM_EVT_CONN_SEC_CONFIG_REQ ,又用这个试了一下,跟PM_EVT_CONN_SEC_FAILED 的效果差不多,仔细看手册,发现后边说了这么一句
-
The peer (central) has requested pairing, but a bond already exists with that peer. Reply by calling pm_conn_sec_config_reply before the event handler returns. If no reply is sent, a default is used.
原来是需要调用这个函数进行回复,点进去这个函数发现第二个参数是一个结构体,结构体里面有一个bool allow_repairing,哈哈哈哈哈哈哈哈哈哈,到此为止,现在讲前边尝试的那些代码全部删除,在 pm_evt_handler里面加入
case PM_EVT_CONN_SEC_CONFIG_REQ:
{
pm_conn_sec_config_t temp;
temp.allow_repairing=true;
pm_conn_sec_config_reply(p_evt->conn_handle,&temp);
break;
}
到此结束,在取消配对之后,再次连接的时候出现了***请求配对,连接成功!!!问题解决!!
总结
-
SDK总是在更新升级的,出现某些函数或变量废弃,或者增加了什么函数或变量,这些很正常,当没有资料可以参考的时候,不要过于依赖别人,静下心来研究代码,研究SDK配套的手册。
-
在一些嵌入式处理器的开发中,我们往往无法像8051那样自己建立一个空白工程,比如nrf52832,工程实在是太复杂了,所以一般是直接用SDK里面的样例工程,或者直接基于例程修改,所有的前提是你对于工程结构要足够清晰,知道哪些需要自己写。
-
在找BUG的过程中,发现SDK里面不止提供了基于IDE的(KEIL IAR)的工程,还提供了armgcc用的Makefile和ld文件。所以完全可以不使用keil,在安装了armgcc的机器上使用makefile开发nrf52832,这个有时间再搞搞。前段时间也在搞STM32 基于armgcc的开发,研究如何写Makefile,发现如果用armgcc开发,需要.c.h文件,makefile,ld文件这三个东西就够了,恰好这些都在nrf的sdk里面提供了。