完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
|
相关推荐
39 个讨论
|
|
|
Hi x,
如果你看simpleBLECentral.c 这个文件, 里面有个函数:simpleBLECentralProcessGATTMsg() 这个函数就是处理各种从peripheral过来的数据. 但是在示例代码中并没有加入通知, 就是notification的接收, 所以你得自己添加代码. 很简单, 类似 if ( ( pMsg->method == ATT_READ_RSP ) || ........), 你添加 else if ( ( pMsg->method == ATT_HANDLE_VALUE_NOTI ) ||......) |
|
|
|
|
|
|
|
骑猪去天山 发表于 2020-3-10 16:12 使能通知是向handle为0x002f写入0x0001 gattPrepareWriteReq_t req; req.handle = 0x002f; req.len = 2; req.pValue[0] = 0x00; req.pValue[1] = 0x01; req.offset = 0; GATT_WriteLongCharValue( simpleBLEConnHandle, &req, simpleBLETaskId ); 但还是无法收到? |
|
|
|
|
|
|
|
芯羿飞扬 发表于 2020-3-10 16:26 Hi x, 首先请确定你找的handle是正确的. 这个handle应该是相应的characteristic value的handle的后面一个, 就是characteristic valude的handle加 1 . 另外, 你的 req.pValue 填错了, 上下两个请反一下. 最后, 这里不要用write long, 用一般的写就行, 就两个字节的内容. 下面是个例子: attWriteReq_t writeReq; writeReq.handle = 0x002f; writeReq.len = 2; writeReq.value[0] = LO_UINT16(GATT_CLIENT_CFG_NOTIFY); 这里是 0x01 writeReq.value[1] = HI_UINT16(GATT_CLIENT_CFG_NOTIFY); 这里是 0x00 writeReq.sig = 0; writeReq.cmd = 0; GATT_WriteCharValue( simpleBLEConnHandle, &writeReq, simpleBLETaskId ); |
|
|
|
|
|
|
|
骑猪去天山 发表于 2020-3-10 16:37 Hi Yan, notification发送和接收都是在第四通道channel 4吗? 在simpleBLEcenter例子程序里有个按键触发读写的代码: // Do a read or write as long as no other read or write is in progress if ( simpleBLEDoWrite ) [ // Do a write attWriteReq_t req; req.handle = simpleBLECharHdl; req.len = 1; req.value[0] = simpleBLECharVal; req.sig = 0; req.cmd = 0; status = GATT_WriteCharValue( simpleBLEConnHandle, &req, simpleBLETaskId ); ] simpleBLECharHdl 应该是第一通道 channel 1的句柄吧。 req.value[0] = simpleBLECharVal应该是要发送的值。 跟踪发现句柄获得,其中句柄simpleBLECharHdl = BUILD_UINT16( pMsg->msg.readByTypeRsp.dataList[0], pMsg->msg.readByTypeRsp.dataList[1] ); 那我该如何获得第四通道数据的句柄? 还有你上面notification的例子怎么是 writeReq.value[0] = LO_UINT16(GATT_CLIENT_CFG_NOTIFY); 这里是 0x01 writeReq.value[1] = HI_UINT16(GATT_CLIENT_CFG_NOTIFY); 这里是 0x00 notification的要发送的值写在哪里呢?比如我要发送一个数值0xFF,我该怎么用notification发送? 谢谢! |
|
|
|
|
|
|
|
wangrubing 发表于 2020-3-10 16:47 Hi xie, 你说的channel是什么? 第四个channel说的是第四个characteristic? simpleBLECharHdl这里必须是你对应的characteristic的CCC的那个句柄. CCC指的是Client Characteristic Configuration 的这个descriptor. CCC句柄一般是在characteristic value的句柄后面. 句柄的顺序是characteristic declaration, characteristic value, 然后是 CCC. 你这个0xFF的value就填写在simpleBLECharVal里面啊. |
|
|
|
|
|
|
|
骑猪去天山 发表于 2020-3-10 16:53 Hi Yan, 我还是不懂,我说的channel是指 // Profile Parameters #define SIMPLEPROFILE_CHAR1 0 // RW uint8 - Profile Characteristic 1 value #define SIMPLEPROFILE_CHAR2 1 // RW uint8 - Profile Characteristic 2 value #define SIMPLEPROFILE_CHAR3 2 // RW uint8 - Profile Characteristic 3 value #define SIMPLEPROFILE_CHAR4 3 // RW uint8 - Profile Characteristic 4 value #define SIMPLEPROFILE_CHAR5 4 // RW uint8 - Profile Characteristic 4 value 第四个SIMPLEPROFILE_CHAR4 是GATT profile的第四个值,他是一个可以通过通知发送给GATT客户端设备。 在simpleBLEcenter例子程序中有一段按键读写第一个SIMPLEPROFILE_CHAR1的值的代码,如下: // Do a read or write as long as no other read or write is in progress if ( simpleBLEDoWrite ) [ // Do a write attWriteReq_t req; req.handle = simpleBLECharHdl; req.len = 1; req.value[0] = simpleBLECharVal; req.sig = 0; req.cmd = 0; status = GATT_WriteCharValue( simpleBLEConnHandle, &req, simpleBLETaskId ); ] else [ // Do a read attReadReq_t req; req.handle = simpleBLECharHdl; status = GATT_ReadCharValue( simpleBLEConnHandle, &req, simpleBLETaskId ); ] 这段代码很好理解,SIMPLEPROFILE_CHAR1的句柄和value值都在代码中体现了。 但是notification的代码我就很难理解,句柄和value值还有0x01和0x00( writeReq.value[0] = LO_UINT16(GATT_CLIENT_CFG_NOTIFY); 这里是 0x01 writeReq.value[1] = HI_UINT16(GATT_CLIENT_CFG_NOTIFY); 这里是 0x00 ) 不明白什么意思。 |
|
|
|
|
|
|
|
|
writeReq.value[0] = LO_UINT16(GATT_CLIENT_CFG_NOTIFY); 这里是 0x01
writeReq.value[1] = HI_UINT16(GATT_CLIENT_CFG_NOTIFY); 这里是 0x00 我之前解释可能有误, 没给你讲清楚. 这两个值目的是打开Notification功能. CCC的参数有两个, 一个Notification, 一个indication. value[0]就是打开关闭notification, value[1]是打开关闭indication. 至于接下来notification发的值是什么, 其实就是对应的characteristic value. 你有空最好去看一下协议栈对spec的定义, 我这样告诉你也只是很少的比较片面的协议栈定义里面的一些内容, 如果你要更好地理解, 最好去看一下spec. 你也可以看上面的教学视频, 也可以看上面的深度培训文档, 最好是可以去blueooth sig 官网上下载spec: https://www.bluetooth.org/en-us/specification/adopted-specifications 其中第三章 volume 3 Core System Package 里面的 part G: GENERIC ATTRIBUTE PROFILE (GATT) 里面的第三章 3 SERVICE INTEROPERABILITY REQUIREMENTS, 这里面有很详细的介绍 service, characteristic 定义的内容. 里面的 3.3.3.3, 就是Client Characteristic Configuration |
|
|
|
|
|
|
|
|
好的,非常感谢!
我还想问一下,simpleBLEcenter例子程序中,有个simpleBLECharHdl 句柄的获得,这个句柄应该是SIMPLEPROFILE_CHAR1的句柄吧 simpleBLECharHdl = BUILD_UINT16( pMsg->msg.readByTypeRsp.dataList[0], pMsg->msg.readByTypeRsp.dataList[1] ); 这段什么意思呢?dataList[0],dataList[1]代表什么?假如我想获得其他SIMPLEPROFILE_CHAR的句柄该如何获得呢?比如SIMPLEPROFILE_CHAR2、SIMPLEPROFILE_CHAR3等。 谢谢! |
|
|
|
|
|
|
|
|
是的.
如果你仔细看代码, 就应该不难看出, 这里有个状态机. 前面的状态里面的代码: req.type.uuid[0] = LO_UINT16(SIMPLEPROFILE_CHAR1_UUID); req.type.uuid[1] = HI_UINT16(SIMPLEPROFILE_CHAR1_UUID); GATT_ReadUsingCharUUID( simpleBLEConnHandle, &req, simpleBLETaskId ); 就是用来查找SIMPLEPROFILE_CHAR1的句柄的. 你贴的代码就是状态机进入到找到这个句柄后的状态. dagaList, 你如果也仔细看代码的话, 这个就是peripheral那边回复过来的具体数据, 这里就是句柄. 如果你要查找SIMPLEPROFILE_CHAR2,或者SIMPLEPROFILE_CHAR3, 你可以简单替换掉前面状态机里面(就是我上面贴的代码)的查找参数. 更好的方法是你在原先的状态机里面多添加几个状态, 在查找玩CHAR1之后添加查找CHAR2, CHAR3, 等等. 也很方便, 不难. |
|
|
|
|
|
|
|
|
在收到CHAR1的handle后立刻查找其他特征值的handle,会找不到
else if ( simpleBLEDiscState == BLE_DISC_STATE_CHAR ) [ 。。。 //simpleBLEDiscState = BLE_DISC_STATE_IDLE; 接着查找 if ( simpleBLESvcStartHdl != 0 ) [ // Discover characteristic simpleBLEDiscState = BLE_DISC_STATE_CHAR6; req.startHandle = simpleBLESvcStartHdl; req.endHandle = simpleBLESvcEndHdl; req.type.len = ATT_BT_UUID_SIZE; req.type.uuid[0] = LO_UINT16(SIMPLEPROFILE_CHAR6_UUID); req.type.uuid[1] = HI_UINT16(SIMPLEPROFILE_CHAR6_UUID); GATT_ReadUsingCharUUID( simpleBLEConnHandle, &req, simpleBLETaskId ); LCD_WRITE_STRING( "Finding", HAL_LCD_LINE_1 ); ] ] else if ( simpleBLEDiscState == BLE_DISC_STATE_CHAR6 ) [ // Characteristic found, store handle if ( pMsg->method == ATT_READ_BY_TYPE_RSP && pMsg->msg.readByTypeRsp.numPairs > 0 ) [ simpleBLECharHd6 = BUILD_UINT16( pMsg->msg.readByTypeRsp.dataList[0], pMsg->msg.readByTypeRsp.dataList[1] ); LCD_WRITE_STRING( "CHAR6 Found", HAL_LCD_LINE_1 ); ] simpleBLEDiscState = BLE_DISC_STATE_IDLE; ] 如果不马上查找就可以,请问是哪里有问题? |
|
|
|
|
|
|
|
|
Hi Yan, 我尝试了几次,然后用这种方法再次查找,终于发现了CHAR4的句柄,如下红色部分: static void simpleBLECentralProcessGATTMsg( gattMsgEvent_t *pMsg ) [ …… else if ( simpleBLEDiscState != BLE_DISC_STATE_IDLE ) [ simpleBLEGATTDiscoveryEvent( pMsg ); /*=====================================================*/ simpleBLEGATTDiscoveryEvent( pMsg ); //再次执行 /*=====================================================*/ ] ] static void simpleBLEGATTDiscoveryEvent( gattMsgEvent_t *pMsg ) [ attReadByTypeReq_t req; if ( simpleBLEDiscState == BLE_DISC_STATE_SVC ) [ // Service found, store handles if ( pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP && pMsg->msg.findByTypeValueRsp.numInfo > 0 ) [ simpleBLESvcStartHdl = pMsg->msg.findByTypeValueRsp.handlesInfo[0].handle; simpleBLESvcEndHdl = pMsg->msg.findByTypeValueRsp.handlesInfo[0].grpEndHandle; ] // If procedure complete if ( ( pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP && pMsg->hdr.status == bleProcedureComplete ) || ( pMsg->method == ATT_ERROR_RSP ) ) [ if ( simpleBLESvcStartHdl != 0 ) [ // Discover characteristic simpleBLEDiscState = BLE_DISC_STATE_CHAR; req.startHandle = simpleBLESvcStartHdl; req.endHandle = simpleBLESvcEndHdl; req.type.len = ATT_BT_UUID_SIZE; req.type.uuid[0] = LO_UINT16(SIMPLEPROFILE_CHAR1_UUID); req.type.uuid[1] = HI_UINT16(SIMPLEPROFILE_CHAR1_UUID); GATT_ReadUsingCharUUID( simpleBLEConnHandle, &req, simpleBLETaskId ); ] ] ] else if ( simpleBLEDiscState == BLE_DISC_STATE_CHAR ) [ // Characteristic found, store handle if ( pMsg->method == ATT_READ_BY_TYPE_RSP && pMsg->msg.readByTypeRsp.numPairs > 0 ) [ simpleBLECharHdl = BUILD_UINT16( pMsg->msg.readByTypeRsp.dataList[0], pMsg->msg.readByTypeRsp.dataList[1] ); LCD_WRITE_STRING( "Simple Svc Found", HAL_LCD_LINE_1 ); //simpleBLEProcedureInProgress = FALSE; ] // simpleBLEDiscState = BLE_DISC_STATE_IDLE; //] /*================================================================================*/ if ( simpleBLESvcStartHdl != 0 ) [ // Discover characteristic simpleBLEDiscState = BLE_DISC_STATE_CHAR4; req.startHandle = simpleBLESvcStartHdl; req.endHandle = simpleBLESvcEndHdl; req.type.len = ATT_BT_UUID_SIZE; req.type.uuid[0] = LO_UINT16(SIMPLEPROFILE_CHAR4_UUID); req.type.uuid[1] = HI_UINT16(SIMPLEPROFILE_CHAR4_UUID); GATT_ReadUsingCharUUID( simpleBLEConnHandle, &req, simpleBLETaskId ); ] ] else if ( simpleBLEDiscState == BLE_DISC_STATE_CHAR4 ) [ // Characteristic found, store handle if ( pMsg->method == ATT_READ_BY_TYPE_RSP && pMsg->msg.readByTypeRsp.numPairs > 0 ) [ simpleBLECharHd4 = BUILD_UINT16( pMsg->msg.readByTypeRsp.dataList[0], pMsg->msg.readByTypeRsp.dataList[1] ); LCD_WRITE_STRING( "Simple Svc Found", HAL_LCD_LINE_1 ); simpleBLEProcedureInProgress = FALSE; ] simpleBLEDiscState = BLE_DISC_STATE_IDLE; ] /*================================================================================*/ ] 在线调试可以看到CHAR4的句柄:simpleBLECharHd4 =0x0025; 但是我感觉这样写的程序比较纠结、不顺眼,如下: else if ( simpleBLEDiscState != BLE_DISC_STATE_IDLE ) [ simpleBLEGATTDiscoveryEvent( pMsg ); /*=====================================================*/ simpleBLEGATTDiscoveryEvent( pMsg ); //再次执行 /*=====================================================*/ ] 执行一次,再执行一次一样的函数,感觉非常的2,还有没有更好的方法? 谢谢! |
|
|
|
|
|
|
|
只有小组成员才能发言,加入小组>>
550 浏览 0 评论
1613 浏览 0 评论
2047 浏览 0 评论
为啥BQ7693003DBTR芯片在和BQ769X0盒子通讯时收不到信号?
1514 浏览 0 评论
DSP 28027F 开发板 XDS100v2调试探针诊断日志显示了 Error -150 (SC_ERR_FTDI_FAIL)如何解决
1338 浏览 0 评论
AT32F407在USART2 DMA发送数据时,接包接到了要发送的数据,程序还是处于等待传输完成的标识判断中,为什么?
1758浏览 29评论
2785浏览 23评论
请问下tpa3220实际测试引脚功能和官方资料不符,哪位大佬可以帮忙解答下
1725浏览 20评论
请教下关于TAS5825PEVM评估模块原理图中不太明白的地方,寻求答疑
1635浏览 14评论
两个TMP117传感器一个可以正常读取温度值,一个读取的值一直是0,为什么?
1646浏览 13评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-2 18:28 , Processed in 1.209462 second(s), Total 80, Slave 71 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
2307