How can ESL establish periodic sync with the special AP?

Hi,my board is nRF52840,and the demo is periodic_sync_conn within ncs2.7.0, 

I want to establish periodic sync with the  AP whose rssi is better,but i am failed。The ESL will sync with another AP automatically Disappointed

Thanks.

struct _AP_info
{
    int8_t sid;
    int8_t rssi;
    bt_addr_le_t addr;
} __packed;
static struct _AP_info AP_info={.rssi=-80};

static void scan_AP(const struct bt_le_scan_recv_info *info)
{
    if (info->rssi > AP_info.rssi)
    {
        AP_info.sid = info->sid;
        AP_info.rssi = info->rssi;
        bt_addr_le_copy(&(AP_info.addr), info->addr);
        printk("Get better rssi AP:sid=%d,rssi=%i,addr=0x%X\n", AP_info.sid, AP_info.rssi, AP_info.addr.a.val[0]);
    }
}
static void scan_recv(const struct bt_le_scan_recv_info *info, struct net_buf_simple *buf)
{
    char name[NAME_LEN] = {0};
    char le_addr[BT_ADDR_LE_STR_LEN];
    struct _AP_info *p_AP_info = NULL;

    (void)memset(name, 0, sizeof(name));
    bt_data_parse(buf, data_cb, name);
    bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr));


    if (0 == strstr(name, "PAwR conn sample") || 0 == info->interval){
        return;
    }

    printk("scan_recv:%s,sid:%d,rssi:%i,type:%d,addr:%s\n", name, info->sid, info->rssi, info->addr->type, le_addr);
    scan_AP(info);


    if (!per_adv_found){

        // per_sid = info->sid;
        // bt_addr_le_copy(&per_addr, info->addr);

        per_sid = AP_info.sid;
        bt_addr_le_copy(&per_addr, &(AP_info.addr));

        per_adv_found = true;
        k_sem_give(&sem_per_adv);
    }
}

static struct bt_le_scan_cb scan_callbacks = {
    .recv = scan_recv,
};
Parents
  • Hi Tan, 

    What I can see in the log is that it will sync to the first one it find (you can see Creating Periodic Advertising Sync is printed). If you do what you do right now, it will give the semaphore after any AP has RSSI > the default RSSI = -80. 
    That's why I suggested that you need to use a timer. You need to run for a certain time before you decide which AP it should connect to. You should not give the semaphore like what you are doing now. 

    The function bt_le_per_adv_sync_create() will not update if you call it again. If you want to change the AP it should try to sync to you need to call bt_le_per_adv_sync_delete() to stop that before you call it again. But anyway, the correct way is to implement a timer so that you only connect to the best AP after you have scanned all of them or scanned for a certain period of time. 

  • PAwR test code.zip

    Hi,would you please build the code on your board? 

    thanks

  • Hi Tan, 

    Did you make any modification ? 
    Do you have any question regarding my explanation ? 

    I don't see the point of trying your code on my board. It will show the same thing what you observed, it will connect to the first AP it scans. 

  • Hi Hung,

    I add a timeout,but it don`t work like we want to.

  • Please show the code where you edited it. How you expect it to work ? And what doesn't work ? 

  • ok,

    I add a timer like this:

    k_timer_start(&my_timer, K_SECONDS(1), K_SECONDS(1));

    void timer_func(struct k_timer *timer_id)
    {
        secondTick++;
    }
    Init startScan  when scan starts:  startScan = secondTick;
    static void scan_AP(const struct bt_le_scan_recv_info *info)
    {
        if (info->rssi > AP_info.rssi){
            AP_info.sid = info->sid;
            AP_info.rssi = info->rssi;
            bt_addr_le_copy(&(AP_info.addr), info->addr);       
            printk("Get better rssi ap:sid=%d,rssi=%i,addr=0x%X\n", AP_info.sid, AP_info.rssi, AP_info.addr.a.val[0]);
        }
    }
    static void scan_recv(const struct bt_le_scan_recv_info *info, struct net_buf_simple *buf)
    {
        char name[NAME_LEN] = {0};
        char le_addr[BT_ADDR_LE_STR_LEN];

        (void)memset(name, 0, sizeof(name));
        bt_data_parse(buf, data_cb, name);
        bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr));

        if (0 == strstr(name, "PAwR conn sample") || 0 == info->interval){
            return;
        }

        printk("scan_recv:%s,sid:%d,rssi:%i,type:%d,addr:%s\n", name, info->sid, info->rssi, info->addr->type, le_addr);
        scan_AP(info);

       
    if ( !per_adv_found && (secondTick-startScan>5) ){
            per_sid = AP_info.sid;
            bt_addr_le_copy(&per_addr, &(AP_info.addr));

            per_adv_found = true;
            k_sem_give(&sem_per_adv);
        }
    }
     
    Next is the log:
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-49,type:1,addr:71:8E:E0:39:A6:F6 (random)
    Get better rssi ap:sid=1,rssi=-49,addr=0xF6
    Creating Periodic Advertising Sync
    Waiting for periodic sync
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-48,type:1,addr:71:8E:E0:39:A6:F6 (random)
    Get better rssi ap:sid=1,rssi=-48,addr=0xF6
    scan_recv:sid=3_PAwR conn sample,sid:3,rssi:-53,type:1,addr:60:A5:88:64:00:6F (random)
    scan_recv:sid=3_PAwR conn sample,sid:3,rssi:-52,type:1,addr:60:A5:88:64:00:6F (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-43,type:1,addr:79:D7:19:CA:C1:9D (random)
    Get better rssi ap:sid=2,rssi=-43,addr=0x9D
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-48,type:1,addr:71:8E:E0:39:A6:F6 (random)
    scan_recv:sid=3_PAwR conn sample,sid:3,rssi:-54,type:1,addr:60:A5:88:64:00:6F (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-43,type:1,addr:79:D7:19:CA:C1:9D (random)
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-49,type:1,addr:71:8E:E0:39:A6:F6 (random)
    scan_recv:sid=3_PAwR conn sample,sid:3,rssi:-51,type:1,addr:60:A5:88:64:00:6F (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-50,type:1,addr:79:D7:19:CA:C1:9D (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-45,type:1,addr:79:D7:19:CA:C1:9D (random)
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-48,type:1,addr:71:8E:E0:39:A6:F6 (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-44,type:1,addr:79:D7:19:CA:C1:9D (random)
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-48,type:1,addr:71:8E:E0:39:A6:F6 (random)
    scan_recv:sid=3_PAwR conn sample,sid:3,rssi:-54,type:1,addr:60:A5:88:64:00:6F (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-47,type:1,addr:79:D7:19:CA:C1:9D (random)
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-49,type:1,addr:71:8E:E0:39:A6:F6 (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-45,type:1,addr:79:D7:19:CA:C1:9D (random)
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-52,type:1,addr:71:8E:E0:39:A6:F6 (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-48,type:1,addr:79:D7:19:CA:C1:9D (random)
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-48,type:1,addr:71:8E:E0:39:A6:F6 (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-44,type:1,addr:79:D7:19:CA:C1:9D (random)
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-49,type:1,addr:71:8E:E0:39:A6:F6 (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-47,type:1,addr:79:D7:19:CA:C1:9D (random)
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-47,type:1,addr:71:8E:E0:39:A6:F6 (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-49,type:1,addr:79:D7:19:CA:C1:9D (random)
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-49,type:1,addr:71:8E:E0:39:A6:F6 (random)
    scan_recv:sid=3_PAwR conn sample,sid:3,rssi:-54,type:1,addr:60:A5:88:64:00:6F (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-45,type:1,addr:79:D7:19:CA:C1:9D (random)
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-58,type:1,addr:71:8E:E0:39:A6:F6 (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-45,type:1,addr:79:D7:19:CA:C1:9D (random)
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-52,type:1,addr:71:8E:E0:39:A6:F6 (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-46,type:1,addr:79:D7:19:CA:C1:9D (random)
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-49,type:1,addr:71:8E:E0:39:A6:F6 (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-45,type:1,addr:79:D7:19:CA:C1:9D (random)
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-48,type:1,addr:71:8E:E0:39:A6:F6 (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-46,type:1,addr:79:D7:19:CA:C1:9D (random)
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-48,type:1,addr:71:8E:E0:39:A6:F6 (random)
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-48,type:1,addr:71:8E:E0:39:A6:F6 (random)
    Synced to sid=1,addr_info_71:8E:E0:39:A6:F6 (random),service_data_0 has 128 subevents,phy=2,reassembly.len=0:0 0 0.
    Rx_2, sub_0, RSSI=-47, len=0, data: 0xde_92_35
    Periodic sync established.
    Stopped scanning
    Rx_2, sub_1, RSSI=-48, len=0, data: 0xde_92_35
Reply
  • ok,

    I add a timer like this:

    k_timer_start(&my_timer, K_SECONDS(1), K_SECONDS(1));

    void timer_func(struct k_timer *timer_id)
    {
        secondTick++;
    }
    Init startScan  when scan starts:  startScan = secondTick;
    static void scan_AP(const struct bt_le_scan_recv_info *info)
    {
        if (info->rssi > AP_info.rssi){
            AP_info.sid = info->sid;
            AP_info.rssi = info->rssi;
            bt_addr_le_copy(&(AP_info.addr), info->addr);       
            printk("Get better rssi ap:sid=%d,rssi=%i,addr=0x%X\n", AP_info.sid, AP_info.rssi, AP_info.addr.a.val[0]);
        }
    }
    static void scan_recv(const struct bt_le_scan_recv_info *info, struct net_buf_simple *buf)
    {
        char name[NAME_LEN] = {0};
        char le_addr[BT_ADDR_LE_STR_LEN];

        (void)memset(name, 0, sizeof(name));
        bt_data_parse(buf, data_cb, name);
        bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr));

        if (0 == strstr(name, "PAwR conn sample") || 0 == info->interval){
            return;
        }

        printk("scan_recv:%s,sid:%d,rssi:%i,type:%d,addr:%s\n", name, info->sid, info->rssi, info->addr->type, le_addr);
        scan_AP(info);

       
    if ( !per_adv_found && (secondTick-startScan>5) ){
            per_sid = AP_info.sid;
            bt_addr_le_copy(&per_addr, &(AP_info.addr));

            per_adv_found = true;
            k_sem_give(&sem_per_adv);
        }
    }
     
    Next is the log:
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-49,type:1,addr:71:8E:E0:39:A6:F6 (random)
    Get better rssi ap:sid=1,rssi=-49,addr=0xF6
    Creating Periodic Advertising Sync
    Waiting for periodic sync
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-48,type:1,addr:71:8E:E0:39:A6:F6 (random)
    Get better rssi ap:sid=1,rssi=-48,addr=0xF6
    scan_recv:sid=3_PAwR conn sample,sid:3,rssi:-53,type:1,addr:60:A5:88:64:00:6F (random)
    scan_recv:sid=3_PAwR conn sample,sid:3,rssi:-52,type:1,addr:60:A5:88:64:00:6F (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-43,type:1,addr:79:D7:19:CA:C1:9D (random)
    Get better rssi ap:sid=2,rssi=-43,addr=0x9D
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-48,type:1,addr:71:8E:E0:39:A6:F6 (random)
    scan_recv:sid=3_PAwR conn sample,sid:3,rssi:-54,type:1,addr:60:A5:88:64:00:6F (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-43,type:1,addr:79:D7:19:CA:C1:9D (random)
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-49,type:1,addr:71:8E:E0:39:A6:F6 (random)
    scan_recv:sid=3_PAwR conn sample,sid:3,rssi:-51,type:1,addr:60:A5:88:64:00:6F (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-50,type:1,addr:79:D7:19:CA:C1:9D (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-45,type:1,addr:79:D7:19:CA:C1:9D (random)
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-48,type:1,addr:71:8E:E0:39:A6:F6 (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-44,type:1,addr:79:D7:19:CA:C1:9D (random)
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-48,type:1,addr:71:8E:E0:39:A6:F6 (random)
    scan_recv:sid=3_PAwR conn sample,sid:3,rssi:-54,type:1,addr:60:A5:88:64:00:6F (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-47,type:1,addr:79:D7:19:CA:C1:9D (random)
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-49,type:1,addr:71:8E:E0:39:A6:F6 (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-45,type:1,addr:79:D7:19:CA:C1:9D (random)
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-52,type:1,addr:71:8E:E0:39:A6:F6 (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-48,type:1,addr:79:D7:19:CA:C1:9D (random)
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-48,type:1,addr:71:8E:E0:39:A6:F6 (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-44,type:1,addr:79:D7:19:CA:C1:9D (random)
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-49,type:1,addr:71:8E:E0:39:A6:F6 (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-47,type:1,addr:79:D7:19:CA:C1:9D (random)
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-47,type:1,addr:71:8E:E0:39:A6:F6 (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-49,type:1,addr:79:D7:19:CA:C1:9D (random)
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-49,type:1,addr:71:8E:E0:39:A6:F6 (random)
    scan_recv:sid=3_PAwR conn sample,sid:3,rssi:-54,type:1,addr:60:A5:88:64:00:6F (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-45,type:1,addr:79:D7:19:CA:C1:9D (random)
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-58,type:1,addr:71:8E:E0:39:A6:F6 (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-45,type:1,addr:79:D7:19:CA:C1:9D (random)
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-52,type:1,addr:71:8E:E0:39:A6:F6 (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-46,type:1,addr:79:D7:19:CA:C1:9D (random)
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-49,type:1,addr:71:8E:E0:39:A6:F6 (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-45,type:1,addr:79:D7:19:CA:C1:9D (random)
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-48,type:1,addr:71:8E:E0:39:A6:F6 (random)
    scan_recv:sid=2_PAwR conn sample,sid:2,rssi:-46,type:1,addr:79:D7:19:CA:C1:9D (random)
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-48,type:1,addr:71:8E:E0:39:A6:F6 (random)
    scan_recv:sid=1_PAwR conn sample,sid:1,rssi:-48,type:1,addr:71:8E:E0:39:A6:F6 (random)
    Synced to sid=1,addr_info_71:8E:E0:39:A6:F6 (random),service_data_0 has 128 subevents,phy=2,reassembly.len=0:0 0 0.
    Rx_2, sub_0, RSSI=-47, len=0, data: 0xde_92_35
    Periodic sync established.
    Stopped scanning
    Rx_2, sub_1, RSSI=-48, len=0, data: 0xde_92_35
Children
  • Hi Tan, 
    As you can see in your log: 


    Creating Periodic Advertising Sync is printed right after the first AP is captured. So you need to check what's wrong with the check if (!per_adv_found && second_cnt>5) . Is 5 seconds too short. Or if the second_cnt is counting correctly or not or the if condition was correct or not. Please try to print the log out. 

    I don't think this is something very hard to debug. Please show the log with all the output, for example the second_cnt print out in the timer handler and in the if (!per_adv_found && second_cnt>5) 

    I think what you implement is OK , about the timer. You can increase the timer to 10 sec just to test. 

  • Hi,

    I'm trying to implement a similar function in the Nordic ESL Getting Started demo.  In my application, there may be multiple APs and I would like the tags to associate with the AP with the strongest signal.  However, I can't find any simple way to achieve this in the demo code without modifying the SDK.  Are there any existing functions/methods in the BLE driver that would allow a tag to listen for APs before it starts advertising?

    Thanks

    Scott

  • Hi Scott, 

    Please create a new ticket for your question. As far as I know the scanning for APs is done in the application, not in the stack or driver, so you just need to modify the application/sample to do so. I would suggest to take a look at the periodic_sync_conn sample. 

Related