Illuminance regulator interface
This module defines an interface for implementation and interaction with an abstract illuminance regulator.
Using the regulator
As this defines an interface for an abstract illuminance regulator, it cannot be used on its own. For an example of regulator usage, see Light Lightness Control Server.
A regulator implementation will provide a bt_mesh_light_ctrl_reg
instance, and this is used as the interface to the regulator.
Field bt_mesh_light_ctrl_reg.user_data
of this struct can be used to store a user context.
Before using the regulator, it needs to be initialized through the bt_mesh_light_ctrl_reg.init
function.
Functions bt_mesh_light_ctrl_reg.start
and bt_mesh_light_ctrl_reg.stop
are used to start and stop the regulator.
Regulator inputs
The regulator has two inputs:
Target value
Measured value
The illuminance regulator takes the specified target value as the reference level and compares it to the reported measured value. The inputs are compared to establish an error for the regulator, which the regulator tries to minimize.
The measured value is passed through the bt_mesh_light_ctrl_reg.measured
variable.
The passed value is to be used in the next regulator step.
The regulator depends on measurement frequency to provide a stable output.
The measurement frequency should be as close as possible to the update interval of the regulator.
If the measurement frequency is too low, the regulator might oscillate as it attempts to compensate for outdated feedback.
The desired target value is passed through the bt_mesh_light_ctrl_reg_target_set()
function.
If the transition time is greater than zero, the target value will be interpolated linearly over the transition time from the previously set value to the new one.
Regulator output
The regulator contains a proportional (P) and an integral (I) component whose outputs are summarized to a regulator output value.
To get output from the regulator, set the bt_mesh_light_ctrl_reg.updated
callback.
When the regulator is running, it will repeatedly call this callback.
Tuning the regulator
Regulator tuning is complex and depends on a lot of internal and external parameters. Varying sensor delay, light output and light change rate may significantly affect the regulator performance and accuracy. To compensate for the external parameters, each regulator component provides user controllable coefficients that change their impact on the output value:
Kp - for the proportional component
Ki - for the integral component
These coefficients can have individual values for positive and negative errors, referenced as follows in the API:
Kpu - proportional up; used when target is higher.
Kpd - proportional down; used when target is lower.
Kiu - integral up; used when target is higher.
Kid - integral down; used when target is lower
Regulators are tuned to fit their environment by changing the coefficients. The coefficient adjustments are typically done by analyzing the system’s step response. The step response is the overall system response to a change in reference value, for instance in a state change in the light level state machine.
Note
The transition time between states in the Light LC Server makes the feedback loop more forgiving. A larger transition time can compensate for poor regulator response.
The illuminance regulator is a PI regulator, which uses the following components to compensate for a mismatch between the reference and the measured level:
Instantaneous error - The proportional component that is typically the main source of correction for a PI regulator. It compares the reference value to the most recent feedback value, and attempts to correct the error by eliminating the difference.
Accumulated error - The integral component that compensates for errors by adding up the sum of the error over time. Its main contribution is to eliminate system bias and accelerate the system step response.
Changing different coefficients will affect the step response differently. Increasing the two coefficients will have the following effect on the step response:
Coefficient |
Rise time |
Overshoot |
Settling time |
Steady-state error |
---|---|---|---|---|
Kp |
Faster |
Higher |
- |
- |
Ki |
Faster |
Higher |
Longer |
Reduced |
The value of the coefficients is typically a trade-off between fast response time and system instability:
If the value is too high, the system might become unstable, potentially leading to oscillation and loss of control.
If the value is too low, the step response might be too slow or unable to reach the target value altogether.
Implementing a new regulator
To implement a new regulator using this generic interface, declare a bt_mesh_light_ctrl_reg
struct, and set the bt_mesh_light_ctrl_reg.init
, bt_mesh_light_ctrl_reg.start
, and bt_mesh_light_ctrl_reg.stop
fields to implementations of these functions.
Use bt_mesh_light_ctrl_reg_input_get()
to get the current target value for the regulator supplied by the regulator user.
The value returned is interpolated linearly over the transition time, if a transition time is requested by the regulator user.
The bt_mesh_light_ctrl_reg.init
function must perform the necessary steps to initialize the implementation, such as initializing interrupt handlers or timers, but not start the regulator.
Use the bt_mesh_light_ctrl_reg.start
and bt_mesh_light_ctrl_reg.stop
functions to start and stop the regulator after it has been initialized by a call to init
.
On every regulator step, the regulator must call bt_mesh_light_ctrl_reg.updated
callback supplied by the user.
For an example of regulator implementation, see Specification-defined illuminance regulator.
API documentation
include/bluetooth/mesh/light_ctrl_reg.h
subsys/bluetooth/mesh/light_ctrl_reg.c
- group bt_mesh_light_ctrl_reg
Illuminance regulator API.
Functions
-
void bt_mesh_light_ctrl_reg_target_set(struct bt_mesh_light_ctrl_reg *reg, float target, int32_t transition_time)
Set the target lightness for the regulator.
Sets the target lightness, also known as the setpoint, for the regulator. Transition time is optional.
- Parameters:
reg – [in] Illuminance regulator instance.
target – [in] Target lightness (setpoint).
transition_time – [in] Transition time until the target lightness should reach the specified value. Pass 0 to change immediately.
-
float bt_mesh_light_ctrl_reg_target_get(struct bt_mesh_light_ctrl_reg *reg)
Get the target lightness for the regulator.
Returns the target lightness, taking the requested transition time into account, for use in regulator implementations.
- Parameters:
reg – [in] Illuminance regulator instance.
- Returns:
The current target lightness, interpolated during transition time.
-
struct bt_mesh_light_ctrl_reg_coeff
- #include <light_ctrl_reg.h>
-
struct bt_mesh_light_ctrl_reg_cfg
- #include <light_ctrl_reg.h>
Illuminance regulator configuration.
Public Members
-
struct bt_mesh_light_ctrl_reg_coeff ki
Regulator integral coefficient.
-
struct bt_mesh_light_ctrl_reg_coeff kp
Regulator proportional coefficient.
-
float accuracy
Regulator dead zone (in percentage).
-
struct bt_mesh_light_ctrl_reg_coeff ki
-
struct bt_mesh_light_ctrl_reg
- #include <light_ctrl_reg.h>
Common regulator context
Public Members
-
void (*init)(struct bt_mesh_light_ctrl_reg *reg)
Initialize the regulator.
- Param reg:
[in] Illuminance regulator instance.
-
void (*start)(struct bt_mesh_light_ctrl_reg *reg, uint16_t lightness)
Start the regulator.
- Param reg:
[in] Illuminance regulator instance.
- Param lightness:
[in] Current lightness level value equal to
lightness
.
-
void (*stop)(struct bt_mesh_light_ctrl_reg *reg)
Stop the regulator.
- Param reg:
[in] Illuminance regulator instance.
-
struct bt_mesh_light_ctrl_reg_cfg cfg
Regulator configuration.
-
float measured
Measured value.
-
void (*updated)(struct bt_mesh_light_ctrl_reg *reg, float output)
Regulator output update callback.
-
void *user_data
User data, available in update callback.
-
void (*init)(struct bt_mesh_light_ctrl_reg *reg)
-
void bt_mesh_light_ctrl_reg_target_set(struct bt_mesh_light_ctrl_reg *reg, float target, int32_t transition_time)