diff options
author | Florian Baumann <derflob@derflob.de> | 2020-05-29 23:00:20 +0200 |
---|---|---|
committer | Florian Baumann <derflob@derflob.de> | 2020-05-29 23:00:20 +0200 |
commit | 4eee82e53ba659bd8ac59bfd516e604955dd0315 (patch) | |
tree | 42c6a796df34e128ea51a2342fd1bb9d47dadd48 | |
parent | f72dc0d488403f89efbf91bd004ce64016addcc8 (diff) | |
download | ULPSoilMonitor-rewrite.tar.gz ULPSoilMonitor-rewrite.tar.bz2 |
WIPrewrite
-rw-r--r-- | ULPSoilMonitor.ino | 421 |
1 files changed, 207 insertions, 214 deletions
diff --git a/ULPSoilMonitor.ino b/ULPSoilMonitor.ino index 76a14d3..e742844 100644 --- a/ULPSoilMonitor.ino +++ b/ULPSoilMonitor.ino @@ -1,10 +1,3 @@ -/* - * Must allocate more memory for the ulp in - * esp32/tools/sdk/include/sdkconfig.h - * -> #define CONFIG_ULP_COPROC_RESERVE_MEM - * for this sketch to compile. 2048b seems - * good. - */ #include "esp_sleep.h" #include "driver/rtc_io.h" #include "driver/adc.h" @@ -25,23 +18,23 @@ 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; + 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; + float vcc; + float soil0; + float soil1; + float soil2; + float soil3; + float soil4; + float soil5; + bool valid = false; } soil; const char default_name[] = "ULPSoilMonitor"; @@ -52,12 +45,12 @@ const char inital_ap_password[] = "SuperSavePassword"; /* This function is called once after power-on reset, to load ULP program into RTC memory and configure the ADC. -*/ + */ static void init_ulp_program(); /* This function is called every time before going into deep sleep. It starts the ULP program and resets measurement counter. -*/ + */ static void start_ulp_program(); /* measures voltage on GPIO26 */ @@ -98,186 +91,186 @@ boolean do_reset = false; unsigned long last_mqtt_connection_attempt = 0; void setup() { - Serial.begin(115200); - - measure_vcc(); + Serial.begin(115200); - setup_webconf(); + measure_vcc(); - esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause(); - if (cause == ESP_SLEEP_WAKEUP_ULP) { + esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause(); + if (cause == ESP_SLEEP_WAKEUP_ULP) { + setup_webconf(); - 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("Deep sleep wakeup\n"); + /* Count temperature form -5 ℃ , so ulp_temperature minus 5 */ + Serial.printf("max_diff:%d\n", (uint16_t)ulp_max_diff); - calculate_soil_data(); - print_soil_data(); + calculate_soil_data(); + print_soil_data(); + elif - } else { + } 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); + 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); - } + } } void loop() { - webconf.doLoop(); - mqtt_client.loop(); + webconf.doLoop(); + mqtt_client.loop(); - if (do_connect_mqtt) { - if (connect_mqtt()) { - do_connect_mqtt = false; + if (do_connect_mqtt) { + if (connect_mqtt()) { + do_connect_mqtt = false; + } + } else if (webconf.getState() == IOTWEBCONF_STATE_ONLINE && !mqtt_client.connected()) { + connect_mqtt(); } - } else if (webconf.getState() == IOTWEBCONF_STATE_ONLINE && !mqtt_client.connected()) { - connect_mqtt(); - } - - if (do_reset) { - webconf.delay(1000); - ESP.restart(); - } - - if (mqtt_client.connected()) { - Serial.println("Sending data via MQTT."); - String topic_prefix = String("/ULPSoilMonitor/") + webconf.getThingName() + String("/"); - if (soil.valid) { - mqtt_client.publish(topic_prefix + "vcc", String(soil.vcc)); - mqtt_client.publish(topic_prefix + "soil0", String(soil.soil0)); - mqtt_client.publish(topic_prefix + "soil1", String(soil.soil1)); - mqtt_client.publish(topic_prefix + "soil2", String(soil.soil2)); - mqtt_client.publish(topic_prefix + "soil3", String(soil.soil3)); - mqtt_client.publish(topic_prefix + "soil4", String(soil.soil4)); - mqtt_client.publish(topic_prefix + "soil5", String(soil.soil5)); - } else { - mqtt_client.publish(topic_prefix + "vcc", String(NAN)); - mqtt_client.publish(topic_prefix + "soil0", String(NAN)); - mqtt_client.publish(topic_prefix + "soil1", String(NAN)); - mqtt_client.publish(topic_prefix + "soil2", String(NAN)); - mqtt_client.publish(topic_prefix + "soil3", String(NAN)); - mqtt_client.publish(topic_prefix + "soil4", String(NAN)); - mqtt_client.publish(topic_prefix + "soil5", String(NAN)); + + if (do_reset) { + webconf.delay(1000); + ESP.restart(); + } + + if (mqtt_client.connected()) { + Serial.println("Sending data via MQTT."); + String topic_prefix = String("/ULPSoilMonitor/") + webconf.getThingName() + String("/"); + if (soil.valid) { + mqtt_client.publish(topic_prefix + "vcc", String(soil.vcc)); + mqtt_client.publish(topic_prefix + "soil0", String(soil.soil0)); + mqtt_client.publish(topic_prefix + "soil1", String(soil.soil1)); + mqtt_client.publish(topic_prefix + "soil2", String(soil.soil2)); + mqtt_client.publish(topic_prefix + "soil3", String(soil.soil3)); + mqtt_client.publish(topic_prefix + "soil4", String(soil.soil4)); + mqtt_client.publish(topic_prefix + "soil5", String(soil.soil5)); + } else { + mqtt_client.publish(topic_prefix + "vcc", String(NAN)); + mqtt_client.publish(topic_prefix + "soil0", String(NAN)); + mqtt_client.publish(topic_prefix + "soil1", String(NAN)); + mqtt_client.publish(topic_prefix + "soil2", String(NAN)); + mqtt_client.publish(topic_prefix + "soil3", String(NAN)); + mqtt_client.publish(topic_prefix + "soil4", String(NAN)); + mqtt_client.publish(topic_prefix + "soil5", String(NAN)); + } + goto_sleep(); } - goto_sleep(); - } } static void init_ulp_program() { - /* Configure ADC channel */ - adc1_ulp_enable(); - adc1_config_channel_atten(ADC1_CHANNEL_7, ADC_ATTEN_DB_0); - adc1_config_channel_atten(ADC1_CHANNEL_4, ADC_ATTEN_DB_0); - adc1_config_channel_atten(ADC1_CHANNEL_5, ADC_ATTEN_DB_0); - adc1_config_channel_atten(ADC1_CHANNEL_6, ADC_ATTEN_DB_0); - adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_DB_0); - adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_0); - adc1_config_width(ADC_WIDTH_BIT_12); - - 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); - rtc_gpio_set_level(GPIO_NUM_25, 1); - rtc_gpio_hold_en(GPIO_NUM_25); - - /* Set ULP wake up period */ - ulp_set_wakeup_period(0, ULP_PERIOD_MS * 1000); - - /* Disable pullup on GPIO15, in case it is connected to ground to suppress - boot messages. - */ - rtc_gpio_pullup_dis(GPIO_NUM_15); - rtc_gpio_hold_en(GPIO_NUM_15); + /* Configure ADC channel */ + adc1_ulp_enable(); + adc1_config_channel_atten(ADC1_CHANNEL_7, ADC_ATTEN_DB_0); + adc1_config_channel_atten(ADC1_CHANNEL_4, ADC_ATTEN_DB_0); + adc1_config_channel_atten(ADC1_CHANNEL_5, ADC_ATTEN_DB_0); + adc1_config_channel_atten(ADC1_CHANNEL_6, ADC_ATTEN_DB_0); + adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_DB_0); + adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_0); + adc1_config_width(ADC_WIDTH_BIT_12); + + 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); + rtc_gpio_set_level(GPIO_NUM_25, 1); + rtc_gpio_hold_en(GPIO_NUM_25); + + /* Set ULP wake up period */ + ulp_set_wakeup_period(0, ULP_PERIOD_MS * 1000); + + /* Disable pullup on GPIO15, in case it is connected to ground to suppress + boot messages. + */ + rtc_gpio_pullup_dis(GPIO_NUM_15); + rtc_gpio_hold_en(GPIO_NUM_15); } static void start_ulp_program() { - init_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); + /* 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; + 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); + 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); + 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); + 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); + 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; - } + 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; + 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 (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; + if (moisture > 100.0) + moisture = 100.0; + else if (moisture < 0.0) + moisture = 0.0; - return moisture; + return moisture; } static void calculate_soil_data() { - if (isnan(soil.valid)) - return; + if (isnan(soil.valid)) + return; - init_sensor_coefficients(); + 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.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; + soil.valid = true; } static void print_soil_data() @@ -294,94 +287,94 @@ static void print_soil_data() static void setup_webconf() { - webconf.addParameter(¶m_mqtt_server); - webconf.setConfigSavedCallback(&config_saved); - webconf.setWifiConnectionCallback(&wifi_connected); - webconf.setupUpdateServer(&http_updater); - webconf.setWifiConnectionTimeoutMs(250); - webconf.setApTimeoutMs(1); - - boolean config_valid = webconf.init(); - if (!config_valid) { - mqtt_server[0] = '\0'; - - Serial.println("Config invalid"); - } + webconf.addParameter(¶m_mqtt_server); + webconf.setConfigSavedCallback(&config_saved); + webconf.setWifiConnectionCallback(&wifi_connected); + webconf.setupUpdateServer(&http_updater); + webconf.setWifiConnectionTimeoutMs(250); + webconf.setApTimeoutMs(1); + + boolean config_valid = webconf.init(); + if (!config_valid) { + mqtt_server[0] = '\0'; + + Serial.println("Config invalid"); + } - webconf.setApTimeoutMs(500); + webconf.setApTimeoutMs(500); - server.on("/", handle_root); - server.on("/config", []{ webconf.handleConfig(); }); - server.onNotFound([](){ webconf.handleNotFound(); }); + server.on("/", handle_root); + server.on("/config", []{ webconf.handleConfig(); }); + server.onNotFound([](){ webconf.handleNotFound(); }); - mqtt_client.begin(mqtt_server, net); + mqtt_client.begin(mqtt_server, net); - net.setNoDelay(true); + net.setNoDelay(true); } void handle_root() { - if (webconf.handleCaptivePortal()) { - // -- Captive portal request were already served. - return; - } - - String s = "<!DOCTYPE html><html lang=\"en\"><head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\"/>"; - s += "<title>ULPSoilMonitor</title></head><body>MQTT App demo"; - s += "<ul>"; - s += "<li>MQTT server: "; - s += mqtt_server; - s += "</ul>"; - s += "Go to <a href='config'>configure page</a> to change values."; - s += "</body></html>\n"; - - server.send(200, "text/html", s); + if (webconf.handleCaptivePortal()) { + // -- Captive portal request were already served. + return; + } + + String s = "<!DOCTYPE html><html lang=\"en\"><head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\"/>"; + s += "<title>ULPSoilMonitor</title></head><body>MQTT App demo"; + s += "<ul>"; + s += "<li>MQTT server: "; + s += mqtt_server; + s += "</ul>"; + s += "Go to <a href='config'>configure page</a> to change values."; + s += "</body></html>\n"; + + server.send(200, "text/html", s); } void wifi_connected() { - do_connect_mqtt = true; + do_connect_mqtt = true; } void config_saved() { - do_reset = true; + do_reset = true; } boolean connect_mqtt() { - unsigned long now = millis(); + unsigned long now = millis(); - if (1000 > now - last_mqtt_connection_attempt) { - return false; - } + if (1000 > now - last_mqtt_connection_attempt) { + return false; + } - Serial.println("Connecting to MQTT server..."); - if (!mqtt_client.connect(webconf.getThingName())) { - last_mqtt_connection_attempt = now; - return false; - } + Serial.println("Connecting to MQTT server..."); + if (!mqtt_client.connect(webconf.getThingName())) { + last_mqtt_connection_attempt = now; + return false; + } - Serial.println("Connected to MQTT server!"); - return true; + Serial.println("Connected to MQTT server!"); + return true; } void goto_sleep() { - if (mqtt_client.connected()) { - mqtt_client.loop(); - net.flush(); - mqtt_client.disconnect(); - mqtt_client.loop(); - } + if (mqtt_client.connected()) { + mqtt_client.loop(); + net.flush(); + mqtt_client.disconnect(); + mqtt_client.loop(); + } - net.flush(); - net.stop(); - delay(20); + net.flush(); + net.stop(); + delay(20); - Serial.printf("Entering deep sleep\n\n"); - start_ulp_program(); - ESP_ERROR_CHECK(esp_sleep_enable_ulp_wakeup()); - esp_deep_sleep_start(); + Serial.printf("Entering deep sleep\n\n"); + start_ulp_program(); + ESP_ERROR_CHECK(esp_sleep_enable_ulp_wakeup()); + esp_deep_sleep_start(); } |