bt_gatt_notify issues

I am developing a simple ble peripheral device that will measure temperature and humidity.  For the most

part, it's working but I can't get the behavior I expect when enabling notifications.  I have searched various

web sites - including Zephyr - for info; but am coming up short.  Some help would be appreciated.

I am using latest nrf connect sdk to develop the app,  I have been having problems consistently using

the vscode front-end, so I am currently using the nrf connect cli for building the app and nrf downloading

tool to flash.  Will leave questions about vscode for another thread.  I can reliably build and flash apps 

using the above and am using the android nrf connect test app on smartphone for verifying correct

service behavior.  Service declaration is as follows:

BT_GATT_SERVICE_DEFINE(svc,
    BT_GATT_PRIMARY_SERVICE(BT_UUID_ESS),
    BT_GATT_CHARACTERISTIC(BT_UUID_TEMPERATURE,
        BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
        BT_GATT_PERM_READ,
        read_temperature, NULL, &temp_ble),
    BT_GATT_CCC(BLE_temperature_ccc_cfg_changed,
            BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),
    BT_GATT_CHARACTERISTIC(BT_UUID_HUMIDITY,
        BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
        BT_GATT_PERM_READ,
        read_humidity, NULL, &hum_ble),
    BT_GATT_CCC(BLE_humidity_ccc_cfg_changed,
            BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),
);
temp_ble and hum_ble are updated from a SHT4x sensor over i2c using
existing Zephyr driver.  Values are reasonable and that part appears to be
working reliably.  I interrogate the sensor every 2 sec, and set both characteristic
values.  After service discovery using android nrf connect tool, both can be read
out successfully.  I also issue a bt_gatt_notify() for each value.  It's my understanding
that, if a ble central node is connected AND notification has been enabled, then
these values will be reported to the client (i.e. ble central)  and displayed.  Here's
the main code:
........

int bt_svc_set_temperature(int temp_ble) {
int rc = bt_gatt_notify(NULL, &svc.attrs[1], &temp_ble, sizeof(temp_ble));
return rc == -ENOTCONN ? 0 : rc;
}

int bt_svc_set_humidity(int hum_ble) {
int rc = bt_gatt_notify(NULL, &svc.attrs[3], &hum_ble, sizeof(hum_ble));
return rc == -ENOTCONN ? 0 : rc;
}

int main(void) {
// start advertising
int error = bt_enable(NULL);
........
error = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), NULL, 0);
.........
printk("Advertising successfully started\n");

while (1) {
k_sleep(K_SECONDS(2));
if (sensor_sample_fetch(sht)) {
printf("Failed to fetch sample from SHT4X device\n");
} else {
sensor_channel_get(sht, SENSOR_CHAN_AMBIENT_TEMP, &temp);
temp_ble = temp.val1; // Only integer part of temp for now
bt_svc_set_temperature(temp_ble);

sensor_channel_get(sht, SENSOR_CHAN_HUMIDITY, &hum);
hum_ble = hum.val1; // Only integer part of hum for now;
bt_svc_set_humidity(hum_ble);
}
As I mentioned, individual reads work fine.  But notify's yield weird
behavors.  In the above code, when temperature notifications are 
enabled, it works correctly.  When I subsequently enable humidity
notifications, the temperature value gets overwritten ( and contiinually
updated) with the humidity data.  Humidity values do not get updated
at all.  Various permutations of svc.attrs[x]
yield different - but also incorrect - behavior.
I clearly don't have the attrs[n] mapping to characteristics correct; but
can't find any discussion about it.  So:
-What's the correct usage of svc.attrs[x] for the above service descriptor
macro.
-Do I need to wait for a notification to complete before issuing another?
If so, how can I detect completion?
Or, do I have the whole model of notification behavior wrong?
Thanks
Parents Reply Children
Related