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.

关于扫描

Other Parts Discussed in Thread: CC2540

请教一个问题:

我使用串口解析指令,然后根据指令执行相关命令,我发送一个指令,然后调用到这个扫描函数GAPCentralRole_StartDiscovery(),普通情况是我会在串口上面输出发现的设备,但是有时候出现的问题是,没有任何回应,当然这个扫描函数执行成功了的。

我再一次使用命令执行这个函数时,返回的是bleAlreadyInRequestedMode,应该是底层正在处理但是没有返回?

那请问,我有什么办法可以消除这种底层没有任何回应的方法?

  • admsadm,

    做设备查找的时候,往往是要查找一定时间的,这段时间内,你再发送查找命令,自然会回应你“老子已经在干了”。

    你要重新查找的话,先发一条 GAPCentralRole_CancelDiscovery(), 再重新发送 GAPCentralRole_StartDiscovery()。

  • Hi,Yan

    我知道他一定会说“老子已经在做了”,因此我再一次请求GAPCentralRole_StartDiscovery的时候返回的是bleAlreadyInRequestedMode。

    使用GAPCentralRole_CancelDiscovery()的确能取消掉当前的扫描,但是我进行扫描这个动作他还是会出现“老子就是不理你”的情况!

  • [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秒,

    你的代码里面是多少?

  • 没动过这个函数参数,那个值也是4sec

  • admsadm,

    huh,那就奇怪了。正常搜索4秒就该停止了。

    你这个貌似不手动停止,不会主动停止。

    是默认的central代码吗?

  • 在central例程代码上面改的~

    我那些情况只是有时候出现的,大多数情况还是正常的,scan之后会返回给我信息的。

    出现这种不正常状况我发现的是两种方式下:

    在SimpleBLECentral_Init()初始化完成之后,我发送scan命令;

    在多次 scan然后取消scan 命令之后,再发送scan命令,Discovery就没有结果了。

  • 刚才发的怎么不见了。。

    是在central例程上面改的。

    大多是情况是没有问题的,就是Discovery之后会返回搜索到的设备。

    出现这种不正常情况一般是在这些方式下:

    多次discovery并且canceldiscovery之后 ,Discovery就没有任何回应了;

    或者偶尔在初始化(SimpleBLECentral_Init)完成之后,再Discovery就没有回应了。

  • Hi,Yan

    不好意思,原来是因为串口的缘故,我串口线这边有点接触不良的,导致有些数据根本没有发送出去!

  • 这个问题太囧了。。。。。。

  • 楼主,我也遇到过跟你类似的问题。不过不是串口线接触不良。

    而是在使用串口前,忘了配置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:

        以下是我做过的测试,暂没有发现问题,你看看会不会是由于从机广播时间到了,停止广播了呢?

    另外,你再确认下是   协议栈扫描过程问题   还是   打印时出现的问题..

  • Hi admsadm

        你轮询的内容是什么?主机的状态或者扫描的结果吗?

    我目前没有采用轮询的方式,而是在状态改变 、 事件发生时才将结果打印出来。。。

       “内部无法及时反馈给你数据?”,你轮询的间隔很短吗?

    我目前也不确定,是否过于频繁的轮询会导致这样的问题。但是我试过,频繁的打印,有时会丢数据。。。

        这部分,其实我也还在想办法解决中。。。

  • shaokai,

    谢谢你的热心回复,希望能再接再厉, TI 是有奖品的哈 :)

    admsadm,

    问个基础问题,你把POWER_SAVING 关闭了吗?

  • No Thanks, Yan!

        我最近也遇到过类似的问题,不过可能跟他的不太一样。

        我现在也担心我哪一天出现他的问题,而解决不了。

        所以趁现在他正在解决问题,一起讨论,呵呵。。。

  • 你看我贴的代码, 我是在串口接收,如果有数据就一直轮询,直到将数据读完为止。

    不知道是不是这样的轮询导致了蓝牙协议栈那边的工作停滞或者其他情况。

    不是打印出现问题,而是Discovery这个过程根本没有完成,因为我再次请求,他返回的是bleAlreadyInRequestedMode。

  • Hi,Yan

    确定是关的!

  • 也有可能,但我不确定。
    你能否把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,

    你的意思是你本来想让他扫描以后直接连上?这段代码是按键处理的么?

    还有,你可以把那个编译的优先级改低一点。

    希望能帮到你~

  • 是不是 跟从机 没有链接上呢?  

  • 我也发现和楼主一样的问题,Discovery只有第一次能收到回应,第二次执行就没反应了(主动调用Cancel也是一样);但是如果Discovery后对某个设备进行Connect然后再Discovery却可以运行。gap底层代码貌似没有开源,自己也没办法分析原因。
      
    这问题真的是很囧呀。