diff --git a/code/nrf-connect/prstlib/boards/arm/bparasite_nrf52840/bparasite_nrf52840.dts b/code/nrf-connect/prstlib/boards/arm/bparasite_nrf52840/bparasite_nrf52840.dts index 578a023..8dd7eb2 100644 --- a/code/nrf-connect/prstlib/boards/arm/bparasite_nrf52840/bparasite_nrf52840.dts +++ b/code/nrf-connect/prstlib/boards/arm/bparasite_nrf52840/bparasite_nrf52840.dts @@ -40,6 +40,12 @@ pulse = ; }; + 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 { diff --git a/code/nrf-connect/prstlib/dts/bindings/pwm-fixed.yaml b/code/nrf-connect/prstlib/dts/bindings/pwm-fixed.yaml index 7b111df..c9dee3c 100644 --- a/code/nrf-connect/prstlib/dts/bindings/pwm-fixed.yaml +++ b/code/nrf-connect/prstlib/dts/bindings/pwm-fixed.yaml @@ -1,4 +1,3 @@ -# Hello description: A fixed frequency & pulse PWM. diff --git a/code/nrf-connect/prstlib/dts/bindings/soil-calibration-coeffs.yaml b/code/nrf-connect/prstlib/dts/bindings/soil-calibration-coeffs.yaml new file mode 100644 index 0000000..5ff7c5b --- /dev/null +++ b/code/nrf-connect/prstlib/dts/bindings/soil-calibration-coeffs.yaml @@ -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. diff --git a/code/nrf-connect/prstlib/src/adc.c b/code/nrf-connect/prstlib/src/adc.c index f13232d..ef64200 100644 --- a/code/nrf-connect/prstlib/src/adc.c +++ b/code/nrf-connect/prstlib/src/adc.c @@ -1,6 +1,7 @@ #include "prstlib/adc.h" #include +#include #include #include #include @@ -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; } diff --git a/code/nrf-connect/samples/ble/ble.code-workspace b/code/nrf-connect/samples/ble/ble.code-workspace index 44c0e47..4e759b6 100644 --- a/code/nrf-connect/samples/ble/ble.code-workspace +++ b/code/nrf-connect/samples/ble/ble.code-workspace @@ -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}" } } \ No newline at end of file