I'm trying to get cy8ckit-042-ble-a to read a I2C sensor power efficiently. I got it working OK when I start the measurement ~1 ms before next BLE RX/TX using WDT timer and then read the result and create a notification while BLESS is in ECO_STABLE state. The fresh data got sent OK and everything worked just fine.
But now I would like to use also slave latency to save more power, if data stays the same. AFAIK BLE system will not wake up unless there is something to send or it has to due to slave latency. So e.g. slave latency=4 BLE will wake up only every 5th connection interval, if there is nothing to be sent. So how can I tell BLE that there is something to be sent?
I assume that I should create a notification. So I put the whole sensor measurement system to start 3 ms before the BLE event and created a notification. It didn't work out as I expected. Even with slave latency 0 the measurement gets missed often. That's because I used the BLESS state ECO_ON for the base point of timing. When I create a notification before ECO_ON I never see ECO_ON BLESS state. Also current consumption does not go down to DEEPSLEEP anymore after the notification. Instead it draws around 3 mA all the time from notification to BLE event. And this wont change, if I increase the time between notification and BLE event.
I guess sending a notification during BLESS DEEPSLEEP state wakes up BLESS and It will not go to DEEPSLEEP untill after the BLE RX/TX.
What is a proper way to get what I want?
What I want is:
1. Measure every connection interval (250 ms)
2. Send fresh data via notification, if data has changed
3. If data has not change, do not start a BLE RX/TX.
4. All this to save power compared to slave latency = 0
Sorry I don't want to put my project on a public forum and I just now I don't have the time to strip it to something I could put here.
But I have made a lot of progress and was able to fit most of the measuring routines into BLE event. I start the measurement at "ECO_ON". I can read the measurement after 700 us and I use WDT to interrupt after that. Thanks to my fast I2C routines I'm still able to read the data and make a notification (calling CyBle_GattsNotification) before actual RX/TX starts. It seems to work much better than waking up before ECO_ON. Especially making a notification before ECO_ON seems to be a bad idea.
Also I have learned that one should avoid making two notifications (two different characteristics), since this seems to be much less efficient than sending more data in one notification. So I used custom profile to fit all the data needed into one notification and disabled e.g. battery level notification.
Now I get ~110 uA average with 250 ms connection interval sending 12 bytes notification of fresh data at each 250 ms and also doing the measurements (the sensors take about 12 uA + the extra active time needed for I2C communication + calculation, all included in the of the total 110 uA).
I'm quite happy with this, but there would still be room for improvement using latency. If I just run the measurement without a BLE connection using WDT to get the same 250 ms measuring interval, I get about 30 uA. But how could I effectively combine this with BLE connection + latency? So that I could send fresh data immediately after it has been measured. Calling CyBle_GattsNotification outside BLE RX/TX seems to consume a lot, thus making latency useless, when you are likely to send new data quite often (maybe 50% probability of getting different data at each measurement).