Trying to receive only one packet per connection interval for every connection on a multi-link environment on SDK 1.7.0

Hi,

The project is a multi-link environment of nrf52840, The 7 peripherals has the task of send data constantly of a sensors. All is working on coded_s8.

The objective is keep the higher data rate of msgs received by central, but to guarantee the uniformity between every peripheral. For that i have done a deep investigation on how the central schedule the connections, and what is the best strategy to receive the data.

The ATT_MTU is set to minimum 23 bytes because of coded_s8.

Time on air of a packet= 80+256+16+24+(23*8*8)+(24*8)+(3*8)=2'064ms

So if I disable Connection Event Length extension with:

static int EvtLen(void)
{       
        int err;
	struct net_buf *buf;
	sdc_hci_cmd_vs_conn_event_extend_t *evt_enable;

	buf = bt_hci_cmd_create(SDC_HCI_OPCODE_CMD_VS_CONN_EVENT_EXTEND,
				sizeof(*evt_enable));
	if (!buf) {
		printk("Could not allocate LLPM command buffer\n");
		return -ENOMEM;
	}
        evt_enable = net_buf_add(buf, sizeof(*evt_enable));
	evt_enable->enable = 0;

	err = bt_hci_cmd_send_sync(SDC_HCI_OPCODE_CMD_VS_CONN_EVENT_EXTEND, buf, NULL);
	if (err) {
		printk("Error enabling EVENT %d\n", err);
		return err;
	}

	printk("EVENT mode enabled\n");
	return 0;
}

And fix the maximum T event length on Kconfig with:

CONFIG_SDC_MAX_CONN_EVENT_LEN_DEFAULT=2500
Theorically making this configuration i guarantee that on a connection interval of 2500ms*7devices=17500ms/1.25=14 units i have enought time to attend the 7 devices and receive 1 packet of every one (Maybe could be packet drop but no may be systematic). Unfortunately I am not able to achieve this. Most of the times one or 2 devices keep sending half data comparing with the rest. I tried to modify a little the conn_interval without success.
If you could suggest me something more to try I will appreciate it, all code shared is done on Central
Thank you and regards.
Parents
  • I have another related question of schedule of central:

    Imagine the next context, only one peripheral with a maximum forced Tevent=2.5ms, Extended connection Event disabled, and a Conn_interval=1000ms.

    Independently of how much messages queued on tx of peripheral, theorically the Central only is going to receive 1 message every second, isn't it? Because on all Conn_interval of 1000ms the Central attend to peripheral once while the 2.5ms of Tevent.

    Thank you, regards.

  • Hi,

    If you could suggest me something more to try I will appreciate it

    Yes, if you could try to increase CONFIG_SDC_MAX_CONN_EVENT_LEN_DEFAULT closer to 3600 us. Looking at a sniffer trace a captured  a while back, the transmission time plus T_IFS for a 27 byte s8 encoded packet is actually 2600 us. You also need  time to time receive the acknowledgment packet from the central.

    Also, when determining what connection interval to use, note that there is a ~1.4 ms delay between scheduling of connection events that need to be accounted for:

    sotillo2409 said:
    Independently of how much messages queued on tx of peripheral, theorically the Central only is going to receive 1 message every second, isn't it? Because on all Conn_interval of 1000ms the Central attend to peripheral once while the 2.5ms of Tevent.

    Yes, that is correct.

    Best regards,

    Vidar

  • Yes, if you could try to increase CONFIG_SDC_MAX_CONN_EVENT_LEN_DEFAULT closer to 3600 us. Looking at a sniffer trace a captured  a while back, the transmission time plus T_IFS for a 27 byte s8 encoded packet is actually 2600 us. You also need  time to time receive the acknowledgment packet from the central.

    Ok, tomorrow I will try and comment with you, without an sniffer to coded_s8 is difficult to find that details, i am so gratefull.

    Independently of how much messages queued on tx of peripheral, theorically the Central only is going to receive 1 message every second, isn't it? Because on all Conn_interval of 1000ms the Central attend to peripheral once while the 2.5ms of Tevent.

    So I think that I have an error on the implementation of Conn interval or event length or I miss some param, because of when I try to make this example work I receive msgs every time, not once at second.

    Could you check if the code shared on the last post is correct? On this case could you suggest me the way to check if all the configurtion that i need is applied?

    I use this appi to set the conection parameters:

    //Connection Param
    struct bt_le_conn_param m_conn_param=
    {
    	.interval_min=6,//
    	.interval_max=6,
    	.timeout=1000,
            .latency=0,
          
    };
    //Scan params
    static struct bt_le_scan_param m_scan_param=
    {
            .type = BT_LE_SCAN_TYPE_ACTIVE,
            .options = BT_LE_SCAN_OPT_CODED | BT_LE_SCAN_OPT_NO_1M,
            .interval = 6,//60ms
            .window = 6,//30ms
    };

    static void scan_filter_match(struct bt_scan_device_info *device_info,
    			      struct bt_scan_filter_match *filter_match,
    			      bool connectable)
    {
    	char addr[BT_ADDR_LE_STR_LEN];
            struct bt_conn_le_create_param *conn_params;
            int err;
    
    	bt_addr_le_to_str(device_info->recv_info->addr, addr, sizeof(addr));
    
    	//LOG_INF("Filters matched. Address: %s connectable: %d",
    		//addr, connectable);
    	printk("Filters matched. Address: %s connectable: %d\n",
    		addr, connectable);
    
            err = bt_scan_stop();
    	if (err) {
    		//printk("Stop LE scan failed (err %d)\n", err);
                    return;
    	}
    
            conn_params = BT_CONN_LE_CREATE_PARAM(
    			BT_CONN_LE_OPT_CODED | BT_CONN_LE_OPT_NO_1M,
    			m_scan_param.interval,
                            m_scan_param.window);
    
    
           err = bt_conn_le_create(device_info->recv_info->addr, conn_params,
    				&m_conn_param,
    				&default_conn);
    
            //default_conn= bt_conn_create_le(device_info->recv_info->addr, &m_conn_param);
            
    	if (err) {
    		printk("Create conn failed (err %d)\n", err);
                    if (Numconnection<MAX_CONN)
                    {
                          err = bt_scan_start(BT_SCAN_TYPE_SCAN_ACTIVE);
                          if (err) {
                                  LOG_ERR("Scanning failed to start (err %d)", err);
                                  printk("Scanning failed to start (err %d)", err);
                                  return;
                          }
                   }
    	}
    }

    And i check some parameters here, on connected() function, always the params match with I set:

    err = bt_conn_get_info(conn, &info);
            if(err)
            {
                   //printk("No conn_get_info() %d", err);
            }
            else printk("CONN_Interval %d\n",info.le.interval);
    
            set_tx_power(BT_HCI_VS_LL_HANDLE_TYPE_CONN,0,+8);//OJOOoooooooooooooooooooooooooooooooooooooooooo
            get_tx_power(BT_HCI_VS_LL_HANDLE_TYPE_CONN,0, &txp);
            
            
            //Zona de cambio de param de conn
            //err = bt_conn_le_data_len_update(info.handle, &data_len);
            //if (err) {
            //        printk("LE data length update failed %d",err);
            //}
            //else printk("data_len done");
    
    	static struct bt_gatt_exchange_params exchange_params;
    
    	exchange_params.func = exchange_func;
    
    	err = bt_gatt_exchange_mtu(conn, &exchange_params);
    	if (err) {
    		LOG_WRN("MTU exchange failed (err %d)", err);
    	}
            mtu=bt_gatt_get_mtu(conn);
            printk("%s Connection (%d) - Initial Tx Power = %d, ATT_MTU = %d\n",addr,info.id, txp, mtu);

    Thank you for the suggestions, 

    regards.

Reply
  • Yes, if you could try to increase CONFIG_SDC_MAX_CONN_EVENT_LEN_DEFAULT closer to 3600 us. Looking at a sniffer trace a captured  a while back, the transmission time plus T_IFS for a 27 byte s8 encoded packet is actually 2600 us. You also need  time to time receive the acknowledgment packet from the central.

    Ok, tomorrow I will try and comment with you, without an sniffer to coded_s8 is difficult to find that details, i am so gratefull.

    Independently of how much messages queued on tx of peripheral, theorically the Central only is going to receive 1 message every second, isn't it? Because on all Conn_interval of 1000ms the Central attend to peripheral once while the 2.5ms of Tevent.

    So I think that I have an error on the implementation of Conn interval or event length or I miss some param, because of when I try to make this example work I receive msgs every time, not once at second.

    Could you check if the code shared on the last post is correct? On this case could you suggest me the way to check if all the configurtion that i need is applied?

    I use this appi to set the conection parameters:

    //Connection Param
    struct bt_le_conn_param m_conn_param=
    {
    	.interval_min=6,//
    	.interval_max=6,
    	.timeout=1000,
            .latency=0,
          
    };
    //Scan params
    static struct bt_le_scan_param m_scan_param=
    {
            .type = BT_LE_SCAN_TYPE_ACTIVE,
            .options = BT_LE_SCAN_OPT_CODED | BT_LE_SCAN_OPT_NO_1M,
            .interval = 6,//60ms
            .window = 6,//30ms
    };

    static void scan_filter_match(struct bt_scan_device_info *device_info,
    			      struct bt_scan_filter_match *filter_match,
    			      bool connectable)
    {
    	char addr[BT_ADDR_LE_STR_LEN];
            struct bt_conn_le_create_param *conn_params;
            int err;
    
    	bt_addr_le_to_str(device_info->recv_info->addr, addr, sizeof(addr));
    
    	//LOG_INF("Filters matched. Address: %s connectable: %d",
    		//addr, connectable);
    	printk("Filters matched. Address: %s connectable: %d\n",
    		addr, connectable);
    
            err = bt_scan_stop();
    	if (err) {
    		//printk("Stop LE scan failed (err %d)\n", err);
                    return;
    	}
    
            conn_params = BT_CONN_LE_CREATE_PARAM(
    			BT_CONN_LE_OPT_CODED | BT_CONN_LE_OPT_NO_1M,
    			m_scan_param.interval,
                            m_scan_param.window);
    
    
           err = bt_conn_le_create(device_info->recv_info->addr, conn_params,
    				&m_conn_param,
    				&default_conn);
    
            //default_conn= bt_conn_create_le(device_info->recv_info->addr, &m_conn_param);
            
    	if (err) {
    		printk("Create conn failed (err %d)\n", err);
                    if (Numconnection<MAX_CONN)
                    {
                          err = bt_scan_start(BT_SCAN_TYPE_SCAN_ACTIVE);
                          if (err) {
                                  LOG_ERR("Scanning failed to start (err %d)", err);
                                  printk("Scanning failed to start (err %d)", err);
                                  return;
                          }
                   }
    	}
    }

    And i check some parameters here, on connected() function, always the params match with I set:

    err = bt_conn_get_info(conn, &info);
            if(err)
            {
                   //printk("No conn_get_info() %d", err);
            }
            else printk("CONN_Interval %d\n",info.le.interval);
    
            set_tx_power(BT_HCI_VS_LL_HANDLE_TYPE_CONN,0,+8);//OJOOoooooooooooooooooooooooooooooooooooooooooo
            get_tx_power(BT_HCI_VS_LL_HANDLE_TYPE_CONN,0, &txp);
            
            
            //Zona de cambio de param de conn
            //err = bt_conn_le_data_len_update(info.handle, &data_len);
            //if (err) {
            //        printk("LE data length update failed %d",err);
            //}
            //else printk("data_len done");
    
    	static struct bt_gatt_exchange_params exchange_params;
    
    	exchange_params.func = exchange_func;
    
    	err = bt_gatt_exchange_mtu(conn, &exchange_params);
    	if (err) {
    		LOG_WRN("MTU exchange failed (err %d)", err);
    	}
            mtu=bt_gatt_get_mtu(conn);
            printk("%s Connection (%d) - Initial Tx Power = %d, ATT_MTU = %d\n",addr,info.id, txp, mtu);

    Thank you for the suggestions, 

    regards.

Children
Related