Store calibration polynomial in devicetree

This will enable us to transparently use different calibration for
different board revisions. The 2.0.0 revision changes the sensing
circuitry and will need its own coeffs.

In this commit, both models are run in parallel for debugging.
This commit is contained in:
rbaron 2023-03-19 09:44:58 +01:00
parent dbf288138e
commit 1983f31af9
5 changed files with 62 additions and 6 deletions

View file

@ -40,6 +40,12 @@
pulse = <PWM_USEC(1)>;
};
soil_calibration_coeffs: soil_calibration_coeffs {
compatible = "soil-calibration-coeffs";
dry = <306000 101000 (-11700)>;
wet = <19000 (-4980) 3420>;
};
ctrl {
compatible = "gpio-keys";
fast_disch: fast_disch {

View file

@ -1,4 +1,3 @@
# Hello
description: A fixed frequency & pulse PWM.

View file

@ -0,0 +1,25 @@
description: >
Calibration coefficients for the soil sensing circuit. We have two polynomials whose input variable
is the battery voltage in Volts. The evaluated polynomial corresponds to the estimated ADC value,
assumed to be 10 bits, so in [0, 1024). The two polynomials are:
dry: For estimation of the fully dry state, given the battery voltage
wet: For estimation of the fully dry state, given the battery voltage
Note that each poly coefficient is specified as 1000 times its real values. This is because we can't
directly represent floating points in devicetree. The final evaludated value should be divided by
1000.0f in code.
compatible: soil-calibration-coeffe
include: base.yaml
properties:
dry:
type: array
required: true
description: The coefficients * 1000, as integers. 0th degree first, then 1st and 2nd last.
wet:
type: array
required: true
description: The coefficients * 1000, as integers. 0th degree first, then 1st and 2nd last.

View file

@ -1,6 +1,7 @@
#include "prstlib/adc.h"
#include <math.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/adc.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/pwm.h>
@ -16,6 +17,10 @@ static const struct pwm_dt_spec soil_pwm_dt =
PWM_DT_SPEC_GET(DT_NODELABEL(soil_pwm));
static const uint32_t pulse = DT_PROP(DT_NODELABEL(soil_pwm), pulse);
// Calibration coefficients for the soil sensing circuit.
static const int dry_coeffs[3] = DT_PROP(DT_NODELABEL(soil_calibration_coeffs), dry);
static const int wet_coeffs[3] = DT_PROP(DT_NODELABEL(soil_calibration_coeffs), wet);
struct gpio_dt_spec fast_disch_dt =
GPIO_DT_SPEC_GET(DT_NODELABEL(fast_disch), gpios);
@ -79,14 +84,27 @@ static void set_battery_percent(const prst_adc_read_t* read, prst_batt_t* out) {
return;
}
static inline float eval_poly(const int coeffs[3], float x) {
// The coefficients are specified times 1000, as a workaround the lack of support for floating
// points in devicetree bindings.
return (coeffs[0] + coeffs[1] * x + coeffs[2] * x * x) / 1000.0f;
}
static inline float get_soil_moisture_percent(float battery_voltage,
int16_t raw_adc_output) {
const double x = battery_voltage;
const double dry = -11.7f * x * x + 101.0f * x + 306.0f;
const double wet = 3.42f * x * x - 4.98f * x + 19.0f;
const float x = battery_voltage;
const float dry = -11.7f * x * x + 101.0f * x + 306.0f;
const float wet = 3.42f * x * x - 4.98f * x + 19.0f;
const float percent = (raw_adc_output - dry) / (wet - dry);
LOG_DBG("Read soil moisture: %.2f | Raw %u | Batt: %.2f | Dry: %.2f | Wet: %.2f",
LOG_INF("Read soil moisture: %.2f | Raw %u | Batt: %.2f | Dry: %.2f | Wet: %.2f",
100.0f * percent, raw_adc_output, x, dry, wet);
const float dry2 = eval_poly(dry_coeffs, x);
const float wet2 = eval_poly(wet_coeffs, x);
const float percent2 = (raw_adc_output - dry) / (wet - dry);
LOG_INF("Read soil moisture 2: %.2f | Raw %u | Batt: %.2f | Dry: %.2f | Wet: %.2f",
100.0f * percent2, raw_adc_output, x, dry2, wet2);
return percent;
}
@ -121,6 +139,12 @@ int prst_adc_init() {
RET_IF_ERR(gpio_pin_configure_dt(&ldr_enable_dt, GPIO_OUTPUT));
#endif
for (size_t idx = 0; idx < ARRAY_SIZE(dry_coeffs); idx++) {
LOG_INF("Dry coeff %d: %d\n", idx, dry_coeffs[idx]);
}
for (size_t idx = 0; idx < ARRAY_SIZE(wet_coeffs); idx++) {
LOG_INF("Wet coeff %d: %d\n", idx, wet_coeffs[idx]);
}
return 0;
}

View file

@ -11,6 +11,8 @@
"C_Cpp.autoAddFileAssociations": false,
"nrf-connect.applications": [
"${workspaceFolder}"
]
],
"nrf-connect.toolchain.path": "${nrf-connect.toolchain:2.2.0}",
"nrf-connect.topdir": "${nrf-connect.sdk:2.2.0}"
}
}