kopia lustrzana https://github.com/pimoroni/pimoroni-pico
SCD4X: Add calibration commands for #1056.
rodzic
9866736ffd
commit
cfa3d1d90d
|
@ -35,5 +35,25 @@ while True:
|
|||
time.sleep(1.0)
|
||||
```
|
||||
|
||||
The `measure()` method will return a Tuple containing the CO2 reading, temperature in degrees C and humidity.
|
||||
The `measure()` method will return a Tuple containing the CO₂ reading, temperature in degrees C and humidity.
|
||||
|
||||
## Changing Calibration
|
||||
|
||||
By default the SCD41 will perform automatic self calibration, which could lead to drift in readings over time.
|
||||
|
||||
You can stop this with `breakout_scd41.set_automatic_self_calibration(False)`.
|
||||
|
||||
You can then use force recalibration with a known good CO₂ PPM baseline to calibrate your sensor:
|
||||
|
||||
```python
|
||||
correction_amount = breakout_scd41.scd41_perform_forced_recalibration(target_co2_concentration);
|
||||
```
|
||||
|
||||
`correction_amount` is the resulting correction in CO₂ PPM.
|
||||
|
||||
To successfully conduct an accurate forced recalibration, the following steps must be carried out:
|
||||
|
||||
1. Operate the SCD4x in a periodic measurement mode for > 3 minutes in an environment with homogenous and constant CO₂ concentration. (read: don't breathe)
|
||||
2. Stop periodic measurement.
|
||||
3. Wait 500 ms.
|
||||
4. Issue the perform_forced_recalibration command.
|
||||
|
|
|
@ -20,6 +20,10 @@ static MP_DEFINE_CONST_FUN_OBJ_0(scd41_get_data_ready_obj, scd41_get_data_ready)
|
|||
static MP_DEFINE_CONST_FUN_OBJ_1(scd41_set_temperature_offset_obj, scd41_set_temperature_offset);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_0(scd41_get_temperature_offset_obj, scd41_get_temperature_offset);
|
||||
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(scd41_perform_forced_recalibration_obj, scd41_perform_forced_recalibration);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(scd41_set_automatic_self_calibration_obj, scd41_set_automatic_self_calibration);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_0(scd41_get_automatic_self_calibration_obj, scd41_get_automatic_self_calibration);
|
||||
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(scd41_set_sensor_altitude_obj, scd41_set_sensor_altitude);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(scd41_set_ambient_pressure_obj, scd41_set_ambient_pressure);
|
||||
|
||||
|
@ -39,6 +43,10 @@ static const mp_map_elem_t scd41_globals_table[] = {
|
|||
{ MP_ROM_QSTR(MP_QSTR_set_temperature_offset), MP_ROM_PTR(&scd41_set_temperature_offset_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_get_temperature_offset), MP_ROM_PTR(&scd41_get_temperature_offset_obj) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_perform_forced_recalibration), MP_ROM_PTR(&scd41_perform_forced_recalibration_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_set_automatic_self_calibration), MP_ROM_PTR(&scd41_set_automatic_self_calibration_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_get_automatic_self_calibration), MP_ROM_PTR(&scd41_get_automatic_self_calibration_obj) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_set_sensor_altitude), MP_ROM_PTR(&scd41_set_sensor_altitude_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_set_ambient_pressure), MP_ROM_PTR(&scd41_set_ambient_pressure_obj) },
|
||||
};
|
||||
|
|
|
@ -88,11 +88,66 @@ mp_obj_t scd41_get_data_ready() {
|
|||
mp_raise_msg(&mp_type_RuntimeError, READ_FAIL_MSG);
|
||||
return mp_const_none;
|
||||
}
|
||||
// The datasheet doesn't really say *which* bit might be 1 if data is ready...
|
||||
// so check if the least significant eleven bits are != 0
|
||||
return data_ready ? mp_const_true : mp_const_false;
|
||||
}
|
||||
|
||||
/*
|
||||
To successfully conduct an accurate forced recalibration, the following
|
||||
steps need to be carried out:
|
||||
1. Operate the SCD4x in a periodic measurement mode for > 3 minutes in an
|
||||
environment with homogenous and constant CO₂ concentration.
|
||||
2. Stop periodic measurement. Wait 500 ms.
|
||||
3. Subsequently issue the perform_forced_recalibration command and
|
||||
optionally read out the baseline correction. A return value of 0xffff
|
||||
indicates that the forced recalibration failed.
|
||||
*/
|
||||
mp_obj_t scd41_perform_forced_recalibration(mp_obj_t target_co2_concentration_in) {
|
||||
if(!scd41_initialised) {
|
||||
mp_raise_msg(&mp_type_RuntimeError, NOT_INITIALISED_MSG);
|
||||
return mp_const_none;
|
||||
};
|
||||
uint16_t frc_correction;
|
||||
uint16_t target_co2_concentration = mp_obj_get_int(target_co2_concentration_in);
|
||||
int error = scd4x_perform_forced_recalibration(target_co2_concentration, &frc_correction);
|
||||
if(error) {
|
||||
mp_raise_msg(&mp_type_RuntimeError, FAIL_MSG);
|
||||
}
|
||||
// FRC correction value in CO₂ ppm or 0xFFFF if the
|
||||
// command failed. Convert value to CO₂ ppm with: value - 0x8000
|
||||
// The mp_const_none return and guardrails here are hopefully unecessary
|
||||
// since it'll throw an error
|
||||
return frc_correction == 0xffff ? mp_const_none : mp_obj_new_int(frc_correction - 0x8000);
|
||||
}
|
||||
|
||||
mp_obj_t scd41_set_automatic_self_calibration(mp_obj_t asc_enabled) {
|
||||
if(!scd41_initialised) {
|
||||
mp_raise_msg(&mp_type_RuntimeError, NOT_INITIALISED_MSG);
|
||||
return mp_const_none;
|
||||
};
|
||||
int error = scd4x_set_automatic_self_calibration(asc_enabled == mp_const_true ? 1u : 0u);
|
||||
if(error) {
|
||||
mp_raise_msg(&mp_type_RuntimeError, FAIL_MSG);
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t scd41_get_automatic_self_calibration() {
|
||||
if(!scd41_initialised) {
|
||||
mp_raise_msg(&mp_type_RuntimeError, NOT_INITIALISED_MSG);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
uint16_t asc_enabled;
|
||||
int error = scd4x_get_automatic_self_calibration(&asc_enabled);
|
||||
if(error) {
|
||||
mp_raise_msg(&mp_type_RuntimeError, FAIL_MSG);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
return asc_enabled ? mp_const_true : mp_const_false;
|
||||
}
|
||||
|
||||
mp_obj_t scd41_set_temperature_offset(mp_obj_t offset) {
|
||||
if(!scd41_initialised) {
|
||||
mp_raise_msg(&mp_type_RuntimeError, NOT_INITIALISED_MSG);
|
||||
|
|
|
@ -14,3 +14,7 @@ extern mp_obj_t scd41_set_temperature_offset(mp_obj_t offset);
|
|||
extern mp_obj_t scd41_get_temperature_offset();
|
||||
extern mp_obj_t scd41_set_sensor_altitude(mp_obj_t altitude);
|
||||
extern mp_obj_t scd41_set_ambient_pressure(mp_obj_t pressure);
|
||||
|
||||
extern mp_obj_t scd41_perform_forced_recalibration(mp_obj_t target_co2_concentration_in);
|
||||
extern mp_obj_t scd41_set_automatic_self_calibration(mp_obj_t asc_enabled);
|
||||
extern mp_obj_t scd41_get_automatic_self_calibration();
|
Ładowanie…
Reference in New Issue