Which is the best way of sending the data read from a sensor?

Hi,

I need to read the data from an acceleration sensor. I tried with a custom program of mine to simulate some data, but it is delaying too much.

I tried reducing the notification interval, but sometimes it just jumps numbers so to say, it should show 1,2,3. But now it shows 1,3,5.

Am I missing something?

Thank you!

Parents
  • Hello,

    I need to read the data from an acceleration sensor. I tried with a custom program of mine to simulate some data, but it is delaying too much.

    Could you elaborate on what you are doing here, and which delay you are referring to here?
    Are you reading out the sensor data over I2C for instance, and then sending it over BLE, where the mentioned delay applies to the BLE communication?


    If you are just starting out with the nRF Connect SDK then I highly recommend taking a look through the nRF Connect SDK Fundemental course to quickly familiarize with the SDK! :) 


    Best regards,
    Karl

  • Hi Karl, 

    I am still not reading any sensor, for now it is just dummy values, and supposedly they should be increasing in 1 unit each time the loop comes. But sometimes it is being increased in more than one unit. 
    I think maybe sending each time the sensor is being "read" is not the best. Is it possible to send maybe an array? Or which is the best way to send the most amount of the "read" sensor?

    Thank you!

  • Hi Karl,

    Again, thank you for your detailed and helpful answer.

    Which value did you change here exactly?

    The value that I changed here was the Notify interval. 

    I went through the code that you mentioned, and it looks like it can be really helpful, I just have some doubts: 

    In the function mentioned (ble_write thread), there is no notify_interval, this is not necessary for notifications? I also saw that the function being used is bt_nus_send(), here I could also use the bt_gatt_notify function? Or this function(bt_nus_send) is specific for sending buffers?

    And last, I guess that instead of the line 638, instead of using k_fifo_get, I should put the function which with I will read the information of my sensor? or it should be the function that will put the information in the buffer?

    Sorry for so many questions, but thank you for your help!

    Adrian Lopez

  • Hello Adrian Lopez,

    Adrian1504 said:
    Sorry for so many questions, but thank you for your help!

    No need to apologize, I am happy to help! :) 

    Adrian1504 said:
    The value that I changed here was the Notify interval. 

    By this I assume you mean the connection interval?
    It would be great if you could be explicit about the changes you made, so that I can know with certainty which value or parameter was changed, since it seems to me that the change was unsuccessful.

    Adrian1504 said:
    In the function mentioned (ble_write thread), there is no notify_interval, this is not necessary for notifications? I also saw that the function being used is bt_nus_send(), here I could also use the bt_gatt_notify function? Or this function(bt_nus_send) is specific for sending buffers?

    You are correct that there is no notify_interval directly, and this is because the peripheral will send the notification in the next possible connection event - there is one connection event each time the connection interval has elapsed.
    So for example, if you queue a notification for sending every 500 ms, and your connection have a connection interval of 250 ms, then your peripheral will send one empty packet in the first connection event (because it did not have any notification to send), and then send queued notification in the next connection event, then it will revert to sending an empty packet again to maintain the connection until a new notification is queued for sending.

    You are also correct that this particular example uses the bt_nus_send function to send the notification, because the example is made to showcase the use of the Nordic UART service in particular - but if you look into the implementation of this service you will see that it also uses the bt_gatt_notify functionality behind the scenes :) 

    Adrian1504 said:
    And last, I guess that instead of the line 638, instead of using k_fifo_get, I should put the function which with I will read the information of my sensor? or it should be the function that will put the information in the buffer?

    This depends on the requirements to your application - such as whether it would be acceptable or perhaps important to drop older sensor measurements, or whether it is important that all measurements make it across the link.
    In your case, I would recommend using a FIFO buffer in the same way that the NUS does, since this lets you gather data for sending independently of the BLE notification queueing.

    Best regards,
    Karl

     

  • Hi Karl,

    By this I assume you mean the connection interval?

    No, here I meant that there was a sleeping function after the notification for delaying the notification process. But now I deleted it. I also created a buffer of size 80 and each position has a 3 variable struct. Now I am able to get 11 buffers per second (That is 2640 bytes per second which is nothing if we convert it to Mbps). To be able to achieve this, because I was getting only 2 buffers per second, in the prj.conf I changed the following parameters: 

    CONFIG_BT_PERIPHERAL_PREF_MIN_INT=10
    CONFIG_BT_PERIPHERAL_PREF_MAX_INT=10
    Why am i getting so little?
    Would it be useful for me to send my code?
    Best regards,
    Adrian Lopez
  • Hello Adrian Lopez,

    Adrian1504 said:
    No, here I meant that there was a sleeping function after the notification for delaying the notification process. But now I deleted it. I also created a buffer of size 80 and each position has a 3 variable struct. Now I am able to get 11 buffers per second (That is 2640 bytes per second which is nothing if we convert it to Mbps). To be able to achieve this, because I was getting only 2 buffers per second, in the prj.conf I changed the following parameters: 

    This way it does not actually matter when you queue the notification, since the check in essence is 'is there a notification ready for sending' when a connection event is upcoming.

    Adrian1504 said:
    CONFIG_BT_PERIPHERAL_PREF_MIN_INT=10
    CONFIG_BT_PERIPHERAL_PREF_MAX_INT=10
    Why am i getting so little?
    Would it be useful for me to send my code?

    Those kconfig options only sets the peripheral's preferences, while it is still the central that decides which connection interval that will actually be used. What does your central's device log say when you connect to your peripheral device?
    Does it log the used connection parameters that it uses?

    The peripheral may send a connection parameter update request, to suggest to use its preferred connection parameters, but the central may reject this update request and instead use whichever connection parameters it would like. The peripheral may then either accept this, or terminate the connection.

    I think the key to your throughput in this case is the connection parameters. Please change these on your central device, or make sure that the central device will accept any connection parameter update request from the peripheral, and then use one of the connection parameter configurations shown here to achieve higher throughput.

    Best regards,
    Karl

  • Hi Karl,

    What does your central's device log say when you connect to your peripheral device?
    Does it log the used connection parameters that it uses?

    When I connect my device it prints this notifications in the nrf Connect app: 

    • PHY updated (TX: LE 2M, RX: LE 2M)
    • Connection parameters updated (interval: 11.25ms, latency: 0, timeout: 10000ms)

    And in the terminal I am getting this messages:

    • MTU exchange successful, new MTU: 244 bytes
    • Data length updated. Length 251/27 bytes, time 2120/2120 us

    So I think that the central is accepting the changes successfully and is setting the same parameters as in the link you provided me. 

    I will leave here a stackoverflow link that I created in case you can have a look at some of the code I have.

     stackoverflow.com/.../nrf52840-not-achieving-sending-2-mbps

    Thank you so much for your time.

    Adrian Lopez.

Reply
  • Hi Karl,

    What does your central's device log say when you connect to your peripheral device?
    Does it log the used connection parameters that it uses?

    When I connect my device it prints this notifications in the nrf Connect app: 

    • PHY updated (TX: LE 2M, RX: LE 2M)
    • Connection parameters updated (interval: 11.25ms, latency: 0, timeout: 10000ms)

    And in the terminal I am getting this messages:

    • MTU exchange successful, new MTU: 244 bytes
    • Data length updated. Length 251/27 bytes, time 2120/2120 us

    So I think that the central is accepting the changes successfully and is setting the same parameters as in the link you provided me. 

    I will leave here a stackoverflow link that I created in case you can have a look at some of the code I have.

     stackoverflow.com/.../nrf52840-not-achieving-sending-2-mbps

    Thank you so much for your time.

    Adrian Lopez.

Children
  • Hello Adrian Lopez,

    Adrian1504 said:

    When I connect my device it prints this notifications in the nrf Connect app: 

    • PHY updated (TX: LE 2M, RX: LE 2M)
    • Connection parameters updated (interval: 11.25ms, latency: 0, timeout: 10000ms)

    And in the terminal I am getting this messages:

    • MTU exchange successful, new MTU: 244 bytes
    • Data length updated. Length 251/27 bytes, time 2120/2120 us

    So I think that the central is accepting the changes successfully and is setting the same parameters as in the link you provided me. 

    Thank you for clarifying - it is good to have it confirmed that you are using a 11.25 ms connection interval.

    It seems that you have successfully changed your connection parameters, and so that should not be what is causing the issue with the throughput either. Could you detail how you are generating and queueing the data for sending again? It would be great to see the relevant code as well, if possible.

    If the throughput is still an issue we will need to capture a sniffer trace of the communication between the devices. Are you familiar with the nRF Sniffer tool?


    Best regards,
    Karl

  • Hi Karl,

    A small update, I changed some things in my code and was able to achieve now .9 Mbps, so I guess the way I am queueing the data and sending it is still not correct. I would be happy to be able to get it up to 1.2. Of course, I will leave some of my functions here:

    static void simulate_dataX(void)
    {
    	sensor_valueX++;
    	if (sensor_valueX == 9) {
    		sensor_valueX = 0;
    	}
    }
    
    static void simulate_data(void){
    	simulate_dataX();
    	simulate_dataY();
    	simulate_dataZ();
    }
    
    int my_lbs_send_sensor_notify(void)
    {
    	if (!notify_sensor_enabled) {
    		return -EACCES;
    	}
    
    	return bt_gatt_notify(NULL, &accelerometer_svc.attrs[1], 
    			      &buffer,
    			      sizeof(buffer));
    }
    
    static void pack_data(uint8_t x, uint8_t y, uint8_t z){
    	buffer[buffer_index].x = x;
        buffer[buffer_index].y = y;
        buffer[buffer_index].z = z;
        buffer_index++;
    
    	if (buffer_index == BUFFER_SIZE){
    		int err = my_lbs_send_sensor_notify();
    		if (err) {
    			LOG_ERR("Notification failed:  %d", err);
    		}
    		buffer_index = 0;
    	}
    
    }
    
    void send_data_thread(void)
    {
    	while(1){
    		if(notify_sensor_enabled){ //Without this if I was only achieveing .02 Mbps
    			simulate_data();
    			pack_data(sensor_valueX,sensor_valueY,sensor_valueZ);
    		}
    
    	}
    		
    }
    
    K_THREAD_DEFINE(send_data_thread_id, STACKSIZE, send_data_thread, NULL, NULL,
    		NULL, PRIORITY, 0, 0);

    Here is the prj:

    # nothing here
    CONFIG_LOG=y
    
    CONFIG_BT=y
    CONFIG_BT_PERIPHERAL=y
    CONFIG_BT_DEVICE_NAME="BLE Device"
    CONFIG_BT_DEVICE_APPEARANCE=0
    #CONFIG_BT_BAS=y
    
    CONFIG_BT_GATT_CLIENT=y
    
    CONFIG_DEBUG_OPTIMIZATIONS=y
    CONFIG_DEBUG_THREAD_INFO=y
    CONFIG_FPU=y
    
    CONFIG_BT_PERIPHERAL_PREF_MIN_INT=30
    CONFIG_BT_PERIPHERAL_PREF_MAX_INT=40
    CONFIG_BT_PERIPHERAL_PREF_LATENCY=0
    CONFIG_BT_PERIPHERAL_PREF_TIMEOUT=1000
    CONFIG_BT_GAP_AUTO_UPDATE_CONN_PARAMS=y
    
    CONFIG_BT_USER_PHY_UPDATE=y
    
    CONFIG_BT_USER_DATA_LEN_UPDATE=y
    CONFIG_BT_CTLR_DATA_LENGTH_MAX=251
    CONFIG_BT_BUF_ACL_RX_SIZE=251
    CONFIG_BT_BUF_ACL_TX_SIZE=251
    CONFIG_BT_L2CAP_TX_MTU=247
    
    CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
    CONFIG_MAIN_STACK_SIZE=2048
    CONFIG_BT_RX_STACK_SIZE=2048

    If you need any other part of the code, let me know. Also, I am not familiar to this tool, but I will have a look at it! Thank you!

    Best regards, 

    Adrian Lopez Vudoyra

  • Hello Adrian.

    Thank you for clarifying - I am glad to hear that you are having progress on the throughput!

    The next step in figuring out where the bottleneck in the communication is would be to gather a sniffer trace, so that we can verify that the application always have data ready to send, and whether there is anything hampering the data from being sent.
    It could for instance here be that the application is not supplying the data fast enough due to other tasks taking time away from the data generation.
    Have you had a look at my suggestion for sniffer in my previous comment?

    Best regards,
    Karl

  • Hello Karl,

    Sorry for the late response. I have been trying to install it, but I ran into this problem:
    "The term 'nrf_sniffer_ble.bat' is not recognized as
    the name of a cmdlet, function, script file, or operable program."

    I have already checked and I have python installed. Do you know what is the problem?

  • Hello again, Adrian

    Thank you for your patience with this - I have been out of office due to the public easter holiday last week, but now I am back.

    Please make sure that you have followed all the steps in the Installing the sniffer guide - especially the part on Installing the sniffer capture tool. Please do this, and let me know if the issue persists!

    Best regards,
    Karl

Related