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!

  • Hello,

    Adrian1504 said:
    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 for clarifying. I assume then that this means that you are sending the dummy data over your BLE link, and the main question is why some of the numbers in the sequence is missing.
    In essence, BLE is a lossless protocol - no data is ever lost in the link - since every packet is either acknowledged by the peer. If a packet it not acknowledged by the peer in its next packet it will be retransmitted until acknowledged, or until the link is terminated.
    Therefore, the data must be lost before it is queued for sending.
    Could you be that your call to queue the data for sending failed, for instance due to a full buffer?
    This could lead to some missing samples in the sequence.
    If you share your relevant 'loop' code then I can take a look.

    Adrian1504 said:
    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?

    You can send an array in a single packet, yes - it just depends on the size of the data and frequency.
    How often are you reading the sensor data, how large as the samples, and what latency requirements do you have for your application?

    Best regards,
    Karl

Reply
  • Hello,

    Adrian1504 said:
    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 for clarifying. I assume then that this means that you are sending the dummy data over your BLE link, and the main question is why some of the numbers in the sequence is missing.
    In essence, BLE is a lossless protocol - no data is ever lost in the link - since every packet is either acknowledged by the peer. If a packet it not acknowledged by the peer in its next packet it will be retransmitted until acknowledged, or until the link is terminated.
    Therefore, the data must be lost before it is queued for sending.
    Could you be that your call to queue the data for sending failed, for instance due to a full buffer?
    This could lead to some missing samples in the sequence.
    If you share your relevant 'loop' code then I can take a look.

    Adrian1504 said:
    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?

    You can send an array in a single packet, yes - it just depends on the size of the data and frequency.
    How often are you reading the sensor data, how large as the samples, and what latency requirements do you have for your application?

    Best regards,
    Karl

Children
  • Dear Karl,

    Thank you for the answer.

     I saw that in fact I was getting all the data, but I am getting 3 int_8 per second. I would like to receive more often, I tried lowering the notify interval, which was set to 500. And I still get the same amount of numbers. 

    I need to read my sensor which throws 3 values per reading (x,y,z), the frequency of reading is still not defined, but I am thinking on doing it via I2C. 

    Should I do an array of 3 arrays for each of the values?

    I am not understanding how I can should send with the bt_gatt_notify(). Should it be: bt_gatt_nottify(NULL,<characteristic declaration index>, &<array>,sizeof(array)); ?

    Or should it be one gatt_notify() per each array that I have?

    Thank you!

  • Hello,

    Adrian1504 said:
    Thank you for the answer.

    No problem at all, I am happy to help! :) 

    Adrian1504 said:
    I would like to receive more often, I tried lowering the notify interval, which was set to 500. And I still get the same amount of numbers. 

    Which value did you change here exactly?
    Please note that the peripheral device may only have a preference for the connection parameters, it does not actually set it. It is the central that decides which connection parameters that will be used.

    Adrian1504 said:

    I am not understanding how I can should send with the bt_gatt_notify(). Should it be: bt_gatt_nottify(NULL,<characteristic declaration index>, &<array>,sizeof(array)); ?

    Or should it be one gatt_notify() per each array that I have?

    If you would like to see a good example of how you can regularly output your sensor data over the BLE link you can take a look at the Peripheral Nordic UART example, which forwards everything it receives over BLE out on its UART, and visa versa. In the ble_write_thread you can see how it checks the FIFO for new data, and then queues it for transfer over BLE is there is any.

    Best regards,
    Karl

  • 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
Related