请教一个问题:
我使用串口解析指令,然后根据指令执行相关命令,我发送一个指令,然后调用到这个扫描函数GAPCentralRole_StartDiscovery(),普通情况是我会在串口上面输出发现的设备,但是有时候出现的问题是,没有任何回应,当然这个扫描函数执行成功了的。
我再一次使用命令执行这个函数时,返回的是bleAlreadyInRequestedMode,应该是底层正在处理但是没有返回?
那请问,我有什么办法可以消除这种底层没有任何回应的方法?
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
请教一个问题:
我使用串口解析指令,然后根据指令执行相关命令,我发送一个指令,然后调用到这个扫描函数GAPCentralRole_StartDiscovery(),普通情况是我会在串口上面输出发现的设备,但是有时候出现的问题是,没有任何回应,当然这个扫描函数执行成功了的。
我再一次使用命令执行这个函数时,返回的是bleAlreadyInRequestedMode,应该是底层正在处理但是没有返回?
那请问,我有什么办法可以消除这种底层没有任何回应的方法?
[2014:04:29:13:19:14][发送]AT+SCAN //这边发送指令扫描
[2014:04:29:13:19:14][接收]Discovering... //调用GAPCentralRole_StartDiscovery
[2014:04:29:13:19:22][发送]AT+CANCELSCAN //然后取消扫描
[2014:04:29:13:19:22][接收]Cancel scan success //取消扫描成功
[2014:04:29:13:19:28][发送]AT+SCAN //再次扫描
[2014:04:29:13:19:28][接收]Discovering... //调用GAPCentralRole_StartDiscovery
[2014:04:29:13:20:29][发送]AT+SCAN //等了差不多一分钟,每反应
[2014:04:29:13:20:29][接收]Already In Request Mode! //这边再取消扫描,还是成功的
为什么?
admsadm,
一分钟?
central初始化函数里面有个定义扫描时间的参数, GAP_SetParamValue( TGAP_GEN_DISC_SCAN, DEFAULT_SCAN_DURATION ); 默认是4秒,
你的代码里面是多少?
楼主,我也遇到过跟你类似的问题。不过不是串口线接触不良。
而是在使用串口前,忘了配置IO口。
后来我在注册串口回调函数之前,给IO口做了初始化工作,就避免了这个问题。
我在SimpleBLECentral_Init()中,使用串口之前,加了个IO口配置子函数,把P0_2 P0_3配置为串口复用功能:
GPIO_Init();//Important!!!
NPI_InitTransport(NPI_SerialCBs);
NPI_WriteTransport("Hello\n",6);
NPI_RegisterUserTaskID(task_id);
你试试吧,一开始我也以为是串口线的问题呢,每次碰一下就发一次,呵呵~~
多次测试好像还是会出现这个问题,不是硬件原因。
头疼~
也就是我确确实实已经执行成功GAPCentralRole_StartDiscovery(),但是多次反复Discovery并cancel Discovery之后,再次Discovery就没有任何结果了 。
贴一下我代码
//uart 接收回调
void SerialCallback(uint8 port, uint8 event)
{
...
static uint8 dataLen = 0;
//有数据则一直读取
while(Hal_UART_RxBufLen(port))
{
HalUARTRead(port,&rcvBuf[dataLen],1);
dataLen++;
...
//满足条件
if(rcvDataFlag == 1)
{
CommandHandle(rcvBuf,dataLen);
dataLen = 0;
rcvDataFlag = 0;
osal_memset(rcvBuf,0,SBP_UART_RX_BUF_SIZE);
}
}
...
}
void CommondHandle(uint8 *pBuffer, uint16 length)
{
...
if(length>=7 && str_cmp(pBuffer+3,"SCAN",4)==0)
{
simpleBLEScanning = TRUE;
simpleBLEScanRes = 0;
bStatus_t status;
status = GAPCentralRole_StartDiscovery(DEFAULT_DISCOVERY_MODE,
DEFAULT_DISCOVERY_ACTIVE_SCAN,
DEFAULT_DISCOVERY_WHITE_LIST );
if(status == SUCCESS)
{
//LCD_WRITE_STRING( "Discovering...", HAL_LCD_LINE_1 );
PrintString("Discovering...\r\n");
}
else if(status == bleIncorrectMode)
{
PrintString("Invalid profile role\r\n");
}
else if(status == bleAlreadyInRequestedMode)
{
PrintString("Already In Request Mode!\r\n");
}
return ;
}
...
if(length>=13 && str_cmp(pBuffer+3,"CANCELSCAN",10)==0)
{
bStatus_t status;
simpleBLEScanning = FALSE;
simpleBLEScanRes = 0;
status = GAPCentralRole_CancelDiscovery();
if(status == SUCCESS)
{
SendStr("Cancel scan success\r\n");
}
return ;
}
}Hi,shaokai Lin
我试了,好像还是一样的结果么~
我在想是不是因为我那个轮询的原因,导致他内部无法及时反馈给我数据~
Hi admsadm
你轮询的内容是什么?主机的状态或者扫描的结果吗?
我目前没有采用轮询的方式,而是在状态改变 、 事件发生时才将结果打印出来。。。
“内部无法及时反馈给你数据?”,你轮询的间隔很短吗?
我目前也不确定,是否过于频繁的轮询会导致这样的问题。但是我试过,频繁的打印,有时会丢数据。。。
这部分,其实我也还在想办法解决中。。。
shaokai,
谢谢你的热心回复,希望能再接再厉, TI 是有奖品的哈 :)
admsadm,
问个基础问题,你把POWER_SAVING 关闭了吗?
你看我贴的代码, 我是在串口接收,如果有数据就一直轮询,直到将数据读完为止。
不知道是不是这样的轮询导致了蓝牙协议栈那边的工作停滞或者其他情况。
不是打印出现问题,而是Discovery这个过程根本没有完成,因为我再次请求,他返回的是bleAlreadyInRequestedMode。
也有可能,但我不确定。
你能否把while(Hal_UART_RxBufLen(port))试试改为:
uint8 slen = Hal_UART_RxBufLen(port);
while(slen)
{
...
HalUARTRead(port,&rcvBuf[dataLen],1);
slen--;
}Hi,shaokai Lin
谢谢你的热心回答。
现在出错的概率比较少了,发现是串口的原因。
第一,串口有时候丢包,所以有出现discovery之后并没有打印任何信息。
第二,我串口接收回调函数里处理的东西过多,导致串口可能会死掉,这部分我将commandhandle处理的部分给移了出去。
Hi admsadm
请问你的问题解决了吗?我现在偶尔也会出现这样的问题:
在多次连接及断开后,发指令 让主机发起连接,发现主机没有响应。
出现的次数很少,很难跟踪。不过我可以排除了从机的问题,因为我在出现这样的问题时,用手机可以扫描到并连接从机。
我通过打印simpleBLEState,发现一直处于BLE_STATE_DISCONNECTING状态
以下是我的跟踪:
一般的流程:请求连接->连接完成->请求断开连接->断开连接完成
蓝色字体是用户的控制输入,红色字体是CC2540响应产生的事件。
按正常来说,一次输入会对于一个事件返回,但偶尔会出现异常:
在发起 请求断开连接 ,没有收到断开连接完成的事件:
simpleBLECentralEventCB()
{
case GAP_LINK_TERMINATED_EVENT:
...
}
而,我在请求断开连接时,赋值simpleBLEState = BLE_STATE_DISCONNECTING。
之后由于没有收到断开连接完成的事件,而没有使simpleBLEState = BLE_STATE_IDLE;
这就导致simpleBLEState后来一直都为BLE_STATE_DISCONNECTING的状态。
我觉得应该在请求断开连接之后加个超时控制,超过一段时间没有收到“连接断开完成”的事件,则默认为已断开。
Hi,shaokai Lin
不好意思,五一放假了刚回来。这个情况我没有遇到,
我觉得,
第一,你确认下发送出去的指令有没有错误?可能串口会出现少部分的丢包;
第二,确定指令发送成功,那在case GAP_LINK_TERMINATED_EVENT:打个断点看能不能进来。
第三,请求超时控制我觉得蓝牙底层应该会做吧,这个我试试看。
1. 发送的指令没有错误,不是因为丢包。
2. 正常能进到这个断点,偶尔异常就进不来了。
3. 这个真不好说啊。。。
指令没有问题的话,你试试看抓包了吧,看主机那边有没有收到peripheral发过来的包。
还有关于simpleBLEState状态值,你那个是正常的。进入到disconnecting状态了,但是不影响你下一次扫描连接 的,我试过了。
simpleBLECentral工程里只要未连接就可扫描,但是当出现异常时,simpleBLEState = BLE_STATE_DISCONNECTING,并没有回到BLE_STATE_IDLE状态。
simpleBLECentral工程的扫描:
if ( simpleBLEState != BLE_STATE_CONNECTED )
{
if ( !simpleBLEScanning )
{
...
}
}
而我的工程做了点修改:
if(simpleBLEState == BLE_STATE_IDLE)
{
if(!simpleBLEScanning)
{
...
}
}
OK,我屏蔽修改,采样原先工程的代码,那扫描后总要连接吧。
if( simpleBLEState == BLE_STATE_IDLE )
{
//发起连接
}
else if ( simpleBLEState == BLE_STATE_CONNECTING ||
simpleBLEState == BLE_STATE_CONNECTED )
{
//取消连接
}
else
{
//另类状态。。。偶尔的异常就跑到这里了。
//simpleBLEState = BLE_STATE_DISCONNECTING
}
Hi,shaokai Lin,
你的意思是你本来想让他扫描以后直接连上?这段代码是按键处理的么?
还有,你可以把那个编译的优先级改低一点。
希望能帮到你~