Some boiler plate code to show abstracting BLE services to a different file in NCS/Zephyr ecosystem, retrieving i2c sensor data from a device and then advertising it as custom characteristics. It also utilizes device power management API with the i2c device for when it is not needed.
For more details on exchange in BLE (characteristics, etc), visit this section in the Nordic DevAcademy.
File | Function |
---|---|
main.c | main application |
si7021.c | si7021 sensor inits, commands, and power management for i2c device |
services/* | shs.c/h (sensorhubservice) for BLE service to be able to read humidity and temperature from phone |
Compatible devices |
---|
nRF52832DK |
nRF52840DK* |
nRF5340DK** |
*should work, haven't tried.
**need to change i2c instance from 0 to 1.
- nRF5340DK / nRF5340 doc, nRF5340DK doc
- Adafruit Si7021 / Si7021 doc
(nice little sensor pack)
Device Runtime Power Management
Device Power Management Implementation Guidelines
CONFIG_PM: This option enables the board to implement extra power management
policies whenever the kernel becomes idle. The kernel informs the
power management subsystem of the number of ticks until the next kernel
timer is due to expire.
CONFIG_PM_DEVICE: This option enables the device power management interface. The
interface consists of hook functions implemented by device drivers
that get called by the power manager application when the system
is going to suspend state or resuming from suspend state. This allows
device drivers to do any necessary power management operations
like turning off device clocks and peripherals. The device drivers
may also save and restore states in these hook functions.
CONFIG_PM_DEVICE_RUNTIME: Enable Runtime Power Management to save power.
With device runtime PM enabled, devices can be suspended or resumed based on the device
usage even while the CPU or system is running.
Looking at the code for the nRF5340's power management, you can see that the only supported power management state is PM_STATE_SOFT_OFF
.
To wake from PM_STATE_SOFT_OFF
, you can use a gpio, nfc, or lpcomp.
Review: https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/services/pm/system.html
PM_STATE_ACTIVE
Runtime active state.
The system is fully powered and active.
PM_STATE_RUNTIME_IDLE
Runtime idle state.
Runtime idle is a system sleep state in which all of the cores enter deepest possible idle state and wait for interrupts, no requirements for the devices, leaving them at the states where they are.
PM_STATE_SUSPEND_TO_IDLE
Suspend to idle state.
The system goes through a normal platform suspend where it puts all of the cores in deepest possible idle state and may puts peripherals into low-power states. No operating state is lost (ie. the cpu core does not lose execution context), so the system can go back to where it left off easily enough.
PM_STATE_STANDBY
Standby state.
In addition to putting peripherals into low-power states all non-boot CPUs are powered off. It should allow more energy to be saved relative to suspend to idle, but the resume latency will generally be greater than for that state. But it should be the same state with suspend to idle state on uniprocesser system.
PM_STATE_SUSPEND_TO_RAM
Suspend to ram state.
This state offers significant energy savings by powering off as much of the system as possible, where memory should be placed into the self-refresh mode to retain its contents. The state of devices and CPUs is saved and held in memory, and it may require some boot- strapping code in ROM to resume the system from it.
PM_STATE_SUSPEND_TO_DISK
Suspend to disk state.
This state offers significant energy savings by powering off as much of the system as possible, including the memory. The contents of memory are written to disk or other non-volatile storage, and on resume it’s read back into memory with the help of boot-strapping code, restores the system to the same point of execution where it went to suspend to disk.
PM_STATE_SOFT_OFF
Soft off state.
This state consumes a minimal amount of power and requires a large latency in order to return to runtime active state. The contents of system(CPU and memory) will not be preserved, so the system will be restarted as if from initial power-up and kernel boot.
from https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/services/pm/device.html#device-power-management-states
Each driver supports certain power management modes as well.
(In the case of i2c twi/twim, they only have PM_DEVICE_ACTION_RESUME
and PM_DEVICE_ACTION_SUSPEND
)
The TWIM peripheral uses DMA, and the TWI peripheral does not. That is not the only difference, but it is the most significant.
No i2c, barely any optimizations, just removing logging, making advertising slow (10 second interval), gpio still present in this...
Can optimize a lot further, but 235 mAh / 0.28 mA lasts a pretty long time.
on phone side: