summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Baumann <derflob@derflob.de>2020-05-06 23:14:38 +0200
committerFlorian Baumann <derflob@derflob.de>2020-05-06 23:20:49 +0200
commit24f4b93b499cd8896892729c4d1f7ba63d24c976 (patch)
tree7731fb08e73d65af1ba48bcd5d04a02e96d3b444
parentea5cd01a6202c9b0ff04fb1ce847af86cecfd35d (diff)
downloadULPSoilMonitor-24f4b93b499cd8896892729c4d1f7ba63d24c976.tar.gz
ULPSoilMonitor-24f4b93b499cd8896892729c4d1f7ba63d24c976.tar.bz2
calculate soil moisture on wake from deep sleep
-rw-r--r--ULPSoilMonitor.ino161
1 files changed, 144 insertions, 17 deletions
diff --git a/ULPSoilMonitor.ino b/ULPSoilMonitor.ino
index f7ccdb1..ded644c 100644
--- a/ULPSoilMonitor.ino
+++ b/ULPSoilMonitor.ino
@@ -11,10 +11,34 @@
#include "esp32/ulp.h"
#include "ulp_soil.h"
#include "ulptool.h"
+#include <math.h>
+
+#define ADC_FACTOR (3.5f)
+#define ADC_VCC_PIN (ADC2_CHANNEL_9)
extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_main_bin_start");
extern const uint8_t ulp_main_bin_end[] asm("_binary_ulp_main_bin_end");
+struct {
+ float soil0;
+ float soil1;
+ float soil2;
+ float soil3;
+ float soil4;
+ float soil5;
+} sensor_offset, sensor_gradient;
+
+struct soil_data {
+ float vcc;
+ float soil0;
+ float soil1;
+ float soil2;
+ float soil3;
+ float soil4;
+ float soil5;
+ bool valid = false;
+} soil;
+
/* This function is called once after power-on reset, to load ULP program into
RTC memory and configure the ADC.
*/
@@ -25,27 +49,43 @@ static void init_ulp_program();
*/
static void start_ulp_program();
+/* measures voltage on GPIO26 */
+static void measure_vcc();
+
+static void init_sensor_coefficients();
+
+static float soil_moisture(uint16_t adc_value, float vcc, float offset, float gradient);
+
+/* fills soil_data struct */
+static void calculate_soil_data();
+
+/* logs current soil_data */
+static void print_soil_data();
+
void setup() {
Serial.begin(115200);
- delay(100);
+
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
- if (cause != ESP_SLEEP_WAKEUP_ULP) {
- Serial.printf("Not ULP wakeup\n");
- init_ulp_program();
- } else {
+ if (cause == ESP_SLEEP_WAKEUP_ULP) {
+
Serial.printf("Deep sleep wakeup\n");
/* Count temperature form -5 ℃ , so ulp_temperature minus 5 */
Serial.printf("max_diff:%d\n", (uint16_t)ulp_max_diff);
- Serial.printf("Soil0:%d\n", (uint16_t)ulp_soil0);
- Serial.printf("Soil1:%d\n", (uint16_t)ulp_soil1);
- Serial.printf("Soil2:%d\n", (uint16_t)ulp_soil2);
- Serial.printf("Soil3:%d\n", (uint16_t)ulp_soil3);
- Serial.printf("Soil4:%d\n", (uint16_t)ulp_soil4);
- Serial.printf("Soil5:%d\n", (uint16_t)ulp_soil5);
+
+ measure_vcc();
+ calculate_soil_data();
+ print_soil_data();
+
+ } else {
+
+ esp_err_t err = ulptool_load_binary(0, ulp_main_bin_start, (ulp_main_bin_end - ulp_main_bin_start) / sizeof(uint32_t));
+ ESP_ERROR_CHECK(err);
+
}
+
Serial.printf("Entering deep sleep\n\n");
start_ulp_program();
- ESP_ERROR_CHECK( esp_sleep_enable_ulp_wakeup() );
+ ESP_ERROR_CHECK(esp_sleep_enable_ulp_wakeup());
esp_deep_sleep_start();
}
@@ -55,10 +95,6 @@ void loop() {
static void init_ulp_program()
{
- esp_err_t err = ulptool_load_binary(0, ulp_main_bin_start,
- (ulp_main_bin_end - ulp_main_bin_start) / sizeof(uint32_t));
- ESP_ERROR_CHECK(err);
-
/* Configure ADC channel */
adc1_ulp_enable();
adc1_config_channel_atten(ADC1_CHANNEL_7, ADC_ATTEN_DB_0);
@@ -71,6 +107,7 @@ static void init_ulp_program()
gpio_deep_sleep_hold_en();
+ /* Configure SENSOR_ENABLE */
rtc_gpio_init(GPIO_NUM_25);
rtc_gpio_set_direction(GPIO_NUM_25, RTC_GPIO_MODE_OUTPUT_ONLY);
rtc_gpio_pullup_en(GPIO_NUM_25);
@@ -78,7 +115,7 @@ static void init_ulp_program()
rtc_gpio_hold_en(GPIO_NUM_25);
/* Set ULP wake up period to 1000ms */
- ulp_set_wakeup_period(0, 10000 * 1000);
+ ulp_set_wakeup_period(0, 1000 * 1000);
/* Disable pullup on GPIO15, in case it is connected to ground to suppress
boot messages.
@@ -89,7 +126,97 @@ static void init_ulp_program()
static void start_ulp_program()
{
+ init_ulp_program();
+
/* Start the program */
esp_err_t err = ulp_run((&ulp_entry - RTC_SLOW_MEM) / sizeof(uint32_t));
ESP_ERROR_CHECK(err);
}
+
+static void measure_vcc()
+{
+ int raw;
+
+ gpio_reset_pin(GPIO_NUM_25);
+ gpio_pad_select_gpio(GPIO_NUM_25);
+ gpio_hold_dis(GPIO_NUM_25);
+ gpio_set_direction(GPIO_NUM_25, GPIO_MODE_OUTPUT_OD);
+ gpio_set_level(GPIO_NUM_25, 0);
+
+ vTaskDelay(10);
+
+ adc2_config_channel_atten(ADC_VCC_PIN, ADC_ATTEN_DB_0);
+ esp_err_t r = adc2_get_raw(ADC_VCC_PIN, ADC_WIDTH_12Bit, &raw);
+
+ gpio_set_level(GPIO_NUM_25, 1);
+ gpio_hold_en(GPIO_NUM_25);
+
+ if (r != ESP_OK) {
+ soil.vcc = NAN;
+ soil.valid = false;
+ } else {
+ float vcc = ((float)raw * ADC_FACTOR) / 4095;
+ soil.vcc = vcc;
+ }
+}
+
+static void init_sensor_coefficients()
+{
+ sensor_offset.soil0 = 1.746;
+ sensor_offset.soil1 = 1.746;
+ sensor_offset.soil2 = 1.746;
+ sensor_offset.soil3 = 1.746;
+ sensor_offset.soil4 = 1.746;
+ sensor_offset.soil5 = 1.746;
+
+ sensor_gradient.soil0 = -2.849;
+ sensor_gradient.soil1 = -2.849;
+ sensor_gradient.soil2 = -2.849;
+ sensor_gradient.soil3 = -2.849;
+ sensor_gradient.soil4 = -2.849;
+ sensor_gradient.soil5 = -2.849;
+}
+
+static float soil_moisture(uint16_t adc_value, float vcc, float offset, float gradient)
+{
+ if (adc_value == 0.0) {
+ return NAN;
+ }
+ float moisture = 100.0 * (gradient * ((adc_value * ADC_FACTOR / 4095) / vcc) + offset);
+
+ if (moisture > 100.0)
+ moisture = 100.0;
+ else if (moisture < 0.0)
+ moisture = 0.0;
+
+ return moisture;
+}
+
+static void calculate_soil_data()
+{
+ if (isnan(soil.valid))
+ return;
+
+ init_sensor_coefficients();
+
+ soil.soil0 = soil_moisture(ulp_soil0, soil.vcc, sensor_offset.soil0, sensor_gradient.soil0);
+ soil.soil1 = soil_moisture(ulp_soil1, soil.vcc, sensor_offset.soil1, sensor_gradient.soil1);
+ soil.soil2 = soil_moisture(ulp_soil2, soil.vcc, sensor_offset.soil2, sensor_gradient.soil2);
+ soil.soil3 = soil_moisture(ulp_soil3, soil.vcc, sensor_offset.soil3, sensor_gradient.soil3);
+ soil.soil4 = soil_moisture(ulp_soil4, soil.vcc, sensor_offset.soil4, sensor_gradient.soil4);
+ soil.soil5 = soil_moisture(ulp_soil5, soil.vcc, sensor_offset.soil5, sensor_gradient.soil5);
+
+ soil.valid = true;
+}
+
+static void print_soil_data()
+{
+ Serial.printf("valid: %d\n", soil.valid);
+ Serial.printf("VCC: %f\n", soil.vcc);
+ Serial.printf("Soil0:%d -> %f\n", (uint16_t)ulp_soil0, soil.soil0);
+ Serial.printf("Soil1:%d -> %f\n", (uint16_t)ulp_soil1, soil.soil1);
+ Serial.printf("Soil2:%d -> %f\n", (uint16_t)ulp_soil2, soil.soil2);
+ Serial.printf("Soil3:%d -> %f\n", (uint16_t)ulp_soil3, soil.soil3);
+ Serial.printf("Soil4:%d -> %f\n", (uint16_t)ulp_soil4, soil.soil4);
+ Serial.printf("Soil5:%d -> %f\n", (uint16_t)ulp_soil5, soil.soil5);
+}