Updating the firmware of Wiced SENSE

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

Hi,

I want to change the dynamic range and Output Data Rate (ODR) of magnetometer sensor (LSM303D) sensor present in the WICED Sense device. The current default setting is (-8, +8) Gauss and 25 Hz respectively ( from ./WICED_Sense_SDK 2.1_1.3Final/wiced_sense.c: Line 1171). I have two questions:

(1) How shall I compile the new firmware for Wiced SENSE? I already have the source code (WICED_Sense_SDK 2.1_1.3Final.zip). In the past, I have successfully changed the MAC address of my SENSE using a USB connection.

(2) When I receive the accelerometer/magnetometer sensor data in self developed Android app (SENSE is in notification mode), I get data at approximately 10Hz. However, the source code states that it is currently set to 25 Hz ( from ./WICED_Sense_SDK 2.1_1.3Final/wiced_sense.c: Line 1186). Why this difference in the output data rate?

Regards,

Abhishek

0 Likes
1 Solution
JacobT_81
Employee
Employee
250 replies posted 100 replies posted 50 replies posted

abhishekdutta

I'm glad to hear you were able to implement the connection event callbacks, thanks for the update.

I can't say why your connection interval is changing so drastically, but I do know that it is controlled on the android side--from the firmware we can only make requests. There's not too much information available, but this stack overflow answer may be of some help: http://stackoverflow.com/a/31607968

There are things you can do that affect your BLE connection interval. For example, turning off your wifi will usually help to achieve a lower connection interval. As for assuring the same one consistently, the code in the stack overflow answer may be able to help.

Jacob

View solution in original post

0 Likes
12 Replies
MichaelF_56
Moderator
Moderator
Moderator
250 sign-ins 25 comments on blog 10 comments on blog

Start with the sample app for WICED Sense that is located here within the SDK: /WICED-Smart-SDK/Apps/wiced_sense

To change the BD_ADDR of the WICED Sense device, you can connect the board to your PC over USB and use the instructions here: BD_ADDR: Changing BCM20737 Board Address for Production (PART 2: Process for BD_ADDR Manufacturing Programming - Using SDK) to assign random/static addresses using both the .btp file and Make Target.

I will ask jakewtorres, kwang, jamesle1 and j.t to respond to the sensor/Android aspects of your request.

JacobT_81
Employee
Employee
250 replies posted 100 replies posted 50 replies posted

abhishekdutta


The function to initialize the sensor is where all of the parameters are setup: ODR, Fullscale, etc. See the following function in the .c file to change these:


     void wiced_sense_initialize_lsm303d(void){

     }


Within this function you'll find two calls to the driver which setup the two parameters you're looking for:


     LSM303D_SetMagODR(LSM303D_ODR_25Hz_M);


     LSM303D_SetMagFullScale(LSM303D_FULLSCALE_8_M);


These calls to the driver can be made at any time, dynamically in your code. To change the value, control-click the parameter to see lists of possible input values:


    ODR:

          typedef enum {

           LSM303D_ODR_3_125Hz_M          = 0x00,

           LSM303D_ODR_6_25Hz_M           = 0x01,

          LSM303D_ODR_12_5Hz_M           = 0x02,

           LSM303D_ODR_25Hz_M             = 0x03,

           LSM303D_ODR_50Hz_M             = 0x04,

           LSM303D_ODR_100Hz_M            = 0x05

          } LSM303D_ODR_M_t;

       

Fullscale/range:

          typedef enum {

            LSM303D_FULLSCALE_2_M      = 0x00,

            LSM303D_FULLSCALE_4_M      = 0x01,

            LSM303D_FULLSCALE_8_M      = 0x02,

            LSM303D_FULLSCALE_12_M     = 0x03

          } LSM303D_Fullscale_M_t;

BUT, the ODR of the sensor is not related to the 10Hz you're seeing on your Android. The ODR of a sensor is the environmental sampling rate of that sensor internally. But the wiced_sense firmware is only polling that sensor once per connection interval. The connection interval of the wiced_sense firmware is approximately 100ms (10Hz). For that reason, you only see an updated value every 100ms.

No matter how much you increase you ODR, your phone will not update faster until you change the connection interval.

From the perspective of the slave (the firmware), the connection interval can only be requested, not demanded. And it is done so in this line in the firmware (line 689):

    bleprofile_SendConnParamUpdateReq(64, 96, 0, 500);

This requests an interval between 64 and 96 ms which the master (your android) generally approves as around 100ms, 10Hz.

Jacob

   


Anonymous
Not applicable

Thank you mwf_mmfae and Jacob for the detailed response.

My aim is to sample the (accelerometer, magnetometer, gyroscope) sensors at a higher sample rate. I don't need data from other sensors. Since the sensors are capable of sampling at higher than 10Hz rate, I see that the BLE connection is the only bottleneck. A quick search on the internet reveals that Android can support delay interval from 7.5 ms to 4sec in BLE connection. Have you every tried a connection interval lower than (64,96)ms? Did you ever succeed in getting sensor data at a rate higher than 10Hz?

Regards,

Abhishek

0 Likes
Anonymous
Not applicable

With only magnetometer sensor enabled and

bleprofile_SendConnParamUpdateReq(1, 20, 0, 500);

I managed to receive magnetometer samples at the rate of 20Hz in an Android app. However, this will probably drain the battery rapidly. I think it is possible to receive magnetometer samples at higher rate if we can pack multiple samples in a single BLE packet. Which part of the code should I look into to pack multiple magnetometer samples into a single BLE packet such that when I receive a BLE packet in Android, I get the following multiple magnetometer samples:

(mx,my,mz)_{1}, (mx,my,mz)_{2}, .... (mx,my,mz)_{5}

Any further advice would highly appreciated.

Regards,

Abhishek

0 Likes

abhishekdutta

If all you want to send is magnetometer data, you can fit 3 data samples into a single packet. Since each raw sample is 6 bytes (2 per axis), any more than 3 samples will require scaling down your values (BLE data packet is 20 bytes at the largest).

Using the wiced_sense app as an example, once per connection interval the following function is called:


     static void   wiced_sense_tx_opportunity_notice

                              (void* context, UINT32 unused);

Within this function there are calls to the following functions:

     static UINT8  wiced_sense_poll_hpt_and_fill_notification_packet

                              (UINT16* data_ptr, UINT8* size);

     static UINT8  wiced_sense_poll_agm_and_fill_notification_packet

                              (UINT16* data_ptr, UINT8* size);

The latter functions are where configuration of the packets takes place. Since you only want magnetometer, you can comment out the "_hpt_" function. And use only "_agm_."

Within the _agm_ function, calls to actually poll the sensors over i2c are made. Instead of polling all three sensors, you can poll just the magnetometer and increment the packet appropriately. To do this 3 times before the next connection interval, your easiest route is to utilize the fine timer.

Remove the call to the  _agm_ function from the _tx_opportunity_notice function and put it in the fine timer. Adjust the fine timer to be called 3 times per connection interval.

The alternative, and better option, would be to register for three different connection callbacks, all called at different times throughout the connection interval, and increment the packet before the final send. You can do this by emulating the original callback seen on line 698:

     blecm_connectionEventNotifiationEnable

            ((void (*)(void*, UINT32))wiced_sense_tx_opportunity_notice,

              0, 6250/625, 30000/625, wiced_sense_connection_handle);

See the comments in the code for ways to go about adjusting the parameters.

Jacob

Anonymous
Not applicable

jakewtorres

I prefer the "alternative, and better option". So I updated the wiced_sense_tx_opportunity_notice()to only poll the magnetometer sensor.

If I correctly understand your advice, I need to register three callbacks to the same function blecm_connectionEventNotifiationEnable() but with different offset value so that they are called at different times in the window when tx opportunity is announced. So for three callbacks, I provide the following three offsets: 2080, 4160, 6250. Is this correct? If not, please advise the correct offset values needed to obtain the desired behaviour where the magnetometer is polled three times where each instant fills the data packet by 6 bytes of magnetometer sensor data.


blecm_connectionEventNotifiationEnable

            ((void (*)(void*, UINT32))wiced_sense_tx_opportunity_notice,

              0, 2080/625, 30000/625, wiced_sense_connection_handle);

blecm_connectionEventNotifiationEnable

            ((void (*)(void*, UINT32))wiced_sense_tx_opportunity_notice,

              0, 4160/625, 30000/625, wiced_sense_connection_handle);

blecm_connectionEventNotifiationEnable

            ((void (*)(void*, UINT32))wiced_sense_tx_opportunity_notice,

              0, 6250/625, 30000/625, wiced_sense_connection_handle);

0 Likes
Anonymous
Not applicable

Hello. Assuming you are using the wiced_sense.c file,

there's a function called wiced_sense_tx_opportunity_notice(void*, UINT32). This is where the notifications are sent after polling the sensors. In this function, there's a function call to this function: wiced_sense_poll_agm_and_fill_notification_packet(UINT16*, UINT8*), where the first parameter is the memory where the sensor values will be read to and the second value is the size. Inside this function, the actual magnetic sensor is read by a function call to wiced_sense_get_magnetometer_instantaneous_data(AxesRaw_t*) which calls LSM303D_getMagAxesRaw(AxesRaw_t*), where AxesRaw is a struct with 3 i16_t for each axes(x, y, z). All these functions are defined in the same source code except for LSM303D_getMagAxesRaw, which is driver function from ST.

In order to do what you want to do, I think the easiest way is to change some logic in the first two functions mentioned to fill the packet with only magnetometer readings. Each axis takes 2 bytes, so 1 magnetometer reading will take 6 bytes. Since the maximum payload size per BLE notification is 20 bytes, you can only put 3 sensor readings per packet. I hope this will give you some place to start with.

JacobT_81
Employee
Employee
250 replies posted 100 replies posted 50 replies posted

abhishekdutta

Yes, your understanding is correct. This should work in theory, although I've never personally executed something like it.

Spreading the callbacks appropriately depends a lot on your connection interval. Given that wiced_sense has roughly a 100ms interval, we would want to call the callback every ~30ms. Since 6250/625 corresponds to 6.25ms, I'd recommend trying   6250, 31250, and 62500.

Again, though, this depends on your connection interval, which depends on your client device. If you're using a smart phone, you have very little control over the granted connection interval (you can improve your chances of the requested connection interval being approved by turning off your wifi on your phone).

Jacob                                                                

0 Likes
Anonymous
Not applicable

I can confirm that this works in practical as well

I can now receive 3 magnetometer samples packed in a single ble packet at the rate of 10Hz. I used the following timing intervals:

blecm_connectionEventNotifiationEnable

            ((void (*)(void*, UINT32))wiced_sense_tx_opportunity_notice,

              0, 62500/625, 30000/625, wiced_sense_connection_handle);

blecm_connectionEventNotifiationEnable

            ((void (*)(void*, UINT32))wiced_sense_tx_opportunity_notice,

              0, 37500/625, 30000/625, wiced_sense_connection_handle);

blecm_connectionEventNotifiationEnable

            ((void (*)(void*, UINT32))wiced_sense_tx_opportunity_notice,

              0, 12500/625, 30000/625, wiced_sense_connection_handle);


The first magnetometer sample is packed 62.5ms before the ble-tx-opportunity. The next sample is filled 37.5ms before the ble-tx-opportunity. The final sample is packed 12.5ms before the ble-tx-opportunity. Note that the final sample packing requires more than 6.25ms because it not only involves packing the third magnetometer sample but also involves making the ble packet ready for transmission -- bleprofile_WriteHandle() and bleprofile_sendNotification().

Thanks Jacob.

Regards,

Abhishek




0 Likes
Anonymous
Not applicable

jakewtorres

When I receive data from a single WICED sensor, I get data at 10Hz. However, when I simultaneously receive data from two WICED sensors using a Android phone, I get data at around 30Hz. Why does the data rate change? Is it something related to Android?

0 Likes
Anonymous
Not applicable

abhishekdutta is this still an issue?

0 Likes
JacobT_81
Employee
Employee
250 replies posted 100 replies posted 50 replies posted

abhishekdutta

I'm glad to hear you were able to implement the connection event callbacks, thanks for the update.

I can't say why your connection interval is changing so drastically, but I do know that it is controlled on the android side--from the firmware we can only make requests. There's not too much information available, but this stack overflow answer may be of some help: http://stackoverflow.com/a/31607968

There are things you can do that affect your BLE connection interval. For example, turning off your wifi will usually help to achieve a lower connection interval. As for assuring the same one consistently, the code in the stack overflow answer may be able to help.

Jacob

0 Likes