summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Baumann <derflob@derflob.de>2020-05-29 23:00:20 +0200
committerFlorian Baumann <derflob@derflob.de>2020-05-29 23:00:20 +0200
commit4eee82e53ba659bd8ac59bfd516e604955dd0315 (patch)
tree42c6a796df34e128ea51a2342fd1bb9d47dadd48
parentf72dc0d488403f89efbf91bd004ce64016addcc8 (diff)
downloadULPSoilMonitor-rewrite.tar.gz
ULPSoilMonitor-rewrite.tar.bz2
-rw-r--r--ULPSoilMonitor.ino421
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(&param_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(&param_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();
}