diff --git a/src/_P109_ThermOLED.ino b/src/_P109_ThermOLED.ino index 7951064887..bf0f93a59a 100644 --- a/src/_P109_ThermOLED.ino +++ b/src/_P109_ThermOLED.ino @@ -41,7 +41,7 @@ - /control?cmd=thermo,mode,0 Switch heating off, absolutely do nothing until further notice ------------------------------------------------------------------------------------------ - Copyleft Nagy Sándor 2018 - https://bitekmindenhol.blog.hu/ + Copyleft Nagy Sandor 2018 - https://bitekmindenhol.blog.hu/ ------------------------------------------------------------------------------------------ 2022-12-08 tonhuisman: Add Relay invert state option, reorder config option Contrast Add setpoint delay option, switch relay after delay seconds @@ -138,16 +138,16 @@ boolean Plugin_109(uint8_t function, struct EventStruct *event, String& string) # ifndef LIMIT_BUILD_SIZE case PLUGIN_WEBFORM_SHOW_GPIO_DESCR: { - const char* separator = event->String1.c_str(); + const char *separator = event->String1.c_str(); string = strformat( F("Btn L: %s%sBtn R: %s%sBtn M: %s%sRelay: %s"), - formatGpioLabel(CONFIG_PIN1, false).c_str(), - separator, - formatGpioLabel(CONFIG_PIN2, false).c_str(), - separator, - formatGpioLabel(CONFIG_PIN3, false).c_str(), - separator, - formatGpioLabel(P109_CONFIG_RELAYPIN, false).c_str()); + formatGpioLabel(CONFIG_PIN1, false).c_str(), + separator, + formatGpioLabel(CONFIG_PIN2, false).c_str(), + separator, + formatGpioLabel(CONFIG_PIN3, false).c_str(), + separator, + formatGpioLabel(P109_CONFIG_RELAYPIN, false).c_str()); success = true; break; } @@ -170,18 +170,42 @@ boolean Plugin_109(uint8_t function, struct EventStruct *event, String& string) } } - addFormPinSelect(PinSelectPurpose::Generic_input, F("Button left/down"), F("taskdevicepin1"), CONFIG_PIN1); - addFormPinSelect(PinSelectPurpose::Generic_input, F("Button right/up"), F("taskdevicepin2"), CONFIG_PIN2); - addFormPinSelect(PinSelectPurpose::Generic_input, F("Button mode"), F("taskdevicepin3"), CONFIG_PIN3); + addFormPinSelect(PinSelectPurpose::Generic_input, F("Button left/down"), F("taskdevicepin1"), CONFIG_PIN1); + addFormCheckBox(F("Button left/down Pull mode (1=IntPullUp, 0=Input)"), F("IntPullupButton1"), P109_GET_BUTTON1_INT_PULL_UP == 0); // Inverted + addFormPinSelect(PinSelectPurpose::Generic_input, F("Button right/up"), F("taskdevicepin2"), CONFIG_PIN2); + addFormCheckBox(F("Button right/up Pull mode (1=IntPullUp, 0=Input)"), F("IntPullupButton2"), P109_GET_BUTTON2_INT_PULL_UP == 0); // Inverted + addFormPinSelect(PinSelectPurpose::Generic_input, F("Button mode"), F("taskdevicepin3"), CONFIG_PIN3); + addFormCheckBox(F("Button Mode Pull mode (1=IntPullUp, 0=Input)"), F("IntPullupButton3"), P109_GET_BUTTON3_INT_PULL_UP == 0); // Inverted - addFormPinSelect(PinSelectPurpose::Generic_output, F("Relay"), F("heatrelay"), P109_CONFIG_RELAYPIN); + addFormPinSelect(PinSelectPurpose::Generic_output, F("Relay"), F("heatrelay"), P109_CONFIG_RELAYPIN); addFormCheckBox(F("Invert relay-state (0=on, 1=off)"), F("invertrelay"), P109_GET_RELAY_INVERT); { - const __FlashStringHelper *options4[] = { F("0.2"), F("0.5"), F("1") }; - const int optionValues4[] = { 2, 5, 10 }; - addFormSelector(F("Hysteresis"), F("hyst"), 3, options4, optionValues4, static_cast(P109_CONFIG_HYSTERESIS * 10.0f)); + const __FlashStringHelper *options4[] = { F("0.2"), F("0.5"), F("1"), F("1.5"), F("2"), F("3"), F("4"), F("5") }; + const int optionValues4[] = { 2, 5, 10, 15, 20, 30, 40, 50 }; + addFormSelector(F("Hysteresis"), F("hyst"), NR_ELEMENTS(optionValues4), options4, optionValues4, static_cast(P109_CONFIG_HYSTERESIS * 10.0f)); + } + + { + const __FlashStringHelper *options5[] = { F("5"), F("10"), F("15"), F("20"), F("30"), F("45"), F("60"), F("90") }; + const int optionValues5[] = { 5, 10, 15, 20, 30, 45, 60, 90 }; + addFormSelector(F("Timeout default"), F("timeout"), NR_ELEMENTS(optionValues5), options5, optionValues5, P109_CONFIG_TIMEOUT); + addUnit('m'); + } + + { + const __FlashStringHelper *options6[] = { F("1.5"), F("2"), F("2.5"), F("3"), F("3.5"), F("4"), F("4.5"), F("5") }; + const int optionValues6[] = { 90, 120, 150, 180, 210, 240, 270, 300 }; + addFormSelector(F("Timeout MAX"), F("timeout_max"), NR_ELEMENTS(optionValues6), options6, optionValues6, P109_CONFIG_MAX_TIMEOUT); + addUnit('h'); + } + + { + const __FlashStringHelper *options7[] = { F("5"), F("10"), F("15"), F("20"), F("25"), F("30") }; + const int optionValues7[] = { 5, 10, 15, 20, 25, 30 }; + addFormSelector(F("Timeout step"), F("timeout_step"), NR_ELEMENTS(optionValues7), options7, optionValues7, static_cast(P109_CONFIG_STEP_TIMEOUT)); + addUnit('m'); } { @@ -196,6 +220,12 @@ boolean Plugin_109(uint8_t function, struct EventStruct *event, String& string) addUnit('s'); } + { + const __FlashStringHelper *options8[] = { F("Auto"), F("Off"), F("Manual") }; + const int optionValues8[] = { 1, 0, 2 }; + addFormSelector(F("Default mode"), F("mode"), NR_ELEMENTS(optionValues8), options8, optionValues8, static_cast(P109_MODE_STATE_INITIAL)); + } + success = true; break; } @@ -208,11 +238,18 @@ boolean Plugin_109(uint8_t function, struct EventStruct *event, String& string) P109_CONFIG_CONTRAST = getFormItemInt(F("contrast")); P109_CONFIG_RELAYPIN = getFormItemInt(F("heatrelay")); P109_CONFIG_HYSTERESIS = (getFormItemInt(F("hyst")) / 10.0f); + P109_CONFIG_TIMEOUT = getFormItemInt(F("timeout")); + P109_CONFIG_MAX_TIMEOUT = getFormItemInt(F("timeout_max")); P109_CONFIG_SETPOINT_DELAY = getFormItemInt(F("setpdelay")) + P109_SETPOINT_OFFSET; + P109_CONFIG_STEP_TIMEOUT = getFormItemInt(F("timeout_step")); + P109_MODE_STATE_INITIAL = getFormItemInt(F("mode")); uint32_t lSettings = 0u; - bitWrite(lSettings, P109_FLAG_TASKNAME_IN_TITLE, isFormItemChecked(F("ptask"))); - bitWrite(lSettings, P109_FLAG_ALTERNATE_HEADER, !isFormItemChecked(F("palt"))); // Inverted - bitWrite(lSettings, P109_FLAG_RELAY_INVERT, isFormItemChecked(F("invertrelay"))); + bitWrite(lSettings, P109_FLAG_TASKNAME_IN_TITLE, isFormItemChecked(F("ptask"))); + bitWrite(lSettings, P109_FLAG_ALTERNATE_HEADER, !isFormItemChecked(F("palt"))); // Inverted + bitWrite(lSettings, P109_FLAG_RELAY_INVERT, isFormItemChecked(F("invertrelay"))); + bitWrite(lSettings, P109_FLAG_BUTTON1_INT_PULL_UP, !isFormItemChecked(F("IntPullupButton1"))); // Inverted + bitWrite(lSettings, P109_FLAG_BUTTON2_INT_PULL_UP, !isFormItemChecked(F("IntPullupButton2"))); // Inverted + bitWrite(lSettings, P109_FLAG_BUTTON3_INT_PULL_UP, !isFormItemChecked(F("IntPullupButton3"))); // Inverted P109_FLAGS = lSettings; { diff --git a/src/src/PluginStructs/P109_data_struct.cpp b/src/src/PluginStructs/P109_data_struct.cpp index b43220bad6..58371ced9a 100644 --- a/src/src/PluginStructs/P109_data_struct.cpp +++ b/src/src/PluginStructs/P109_data_struct.cpp @@ -81,11 +81,14 @@ bool P109_data_struct::plugin_init(struct EventStruct *event) { delete _display; _display = nullptr; } - _taskIndex = event->TaskIndex; - _varIndex = event->BaseVarIndex; - _relaypin = P109_CONFIG_RELAYPIN; - _relayInverted = P109_GET_RELAY_INVERT; - _setpointTimeout = P109_CONFIG_SETPOINT_DELAY - P109_SETPOINT_OFFSET; + _taskIndex = event->TaskIndex; + _varIndex = event->BaseVarIndex; + _relaypin = P109_CONFIG_RELAYPIN; + _relayInverted = P109_GET_RELAY_INVERT; + _buttonIntPullup[0] = !P109_GET_BUTTON1_INT_PULL_UP; + _buttonIntPullup[1] = !P109_GET_BUTTON2_INT_PULL_UP; + _buttonIntPullup[2] = !P109_GET_BUTTON3_INT_PULL_UP; + _setpointTimeout = P109_CONFIG_SETPOINT_DELAY - P109_SETPOINT_OFFSET; if (P109_CONFIG_DISPLAYTYPE == 1) { _display = new (std::nothrow) SSD1306Wire(P109_CONFIG_I2CADDRESS, Settings.Pin_i2c_sda, Settings.Pin_i2c_scl); @@ -120,7 +123,7 @@ bool P109_data_struct::plugin_init(struct EventStruct *event) { for (uint8_t pin = 0; pin < 3; ++pin) { if (validGpio(PIN(pin))) { - pinMode(PIN(pin), INPUT_PULLUP); + pinMode(PIN(pin), _buttonIntPullup[pin] ? INPUT_PULLUP : INPUT); } } @@ -198,7 +201,7 @@ bool P109_data_struct::plugin_ten_per_second(struct EventStruct *event) { if (_initialized) { uint32_t current_time; - if (validGpio(CONFIG_PIN1) && !digitalRead(CONFIG_PIN1)) { + if (validGpio(CONFIG_PIN1) && (_buttonIntPullup[0] ? !digitalRead(CONFIG_PIN1) : digitalRead(CONFIG_PIN1))) { current_time = millis(); if (_buttons[0] + P109_BUTTON_DEBOUNCE_TIME_MS < current_time) { @@ -207,7 +210,7 @@ bool P109_data_struct::plugin_ten_per_second(struct EventStruct *event) { } } - if (validGpio(CONFIG_PIN2) && !digitalRead(CONFIG_PIN2)) { + if (validGpio(CONFIG_PIN2) && (_buttonIntPullup[1] ? !digitalRead(CONFIG_PIN2) : digitalRead(CONFIG_PIN2))) { current_time = millis(); if (_buttons[1] + P109_BUTTON_DEBOUNCE_TIME_MS < current_time) { @@ -216,7 +219,7 @@ bool P109_data_struct::plugin_ten_per_second(struct EventStruct *event) { } } - if (validGpio(CONFIG_PIN3) && !digitalRead(CONFIG_PIN3)) { + if (validGpio(CONFIG_PIN3) && (_buttonIntPullup[2] ? !digitalRead(CONFIG_PIN3) : digitalRead(CONFIG_PIN3))) { current_time = millis(); if (_buttons[2] + P109_BUTTON_DEBOUNCE_TIME_MS < current_time) { @@ -437,10 +440,10 @@ void P109_data_struct::actionLeft(struct EventStruct *event) { break; } case 2: { // manual on mode, timer dec - UserVar.setFloat(event->TaskIndex, 3, UserVar[event->BaseVarIndex + 3] - P109_BUTTON_DEBOUNCE_TIME_MS); + UserVar.setFloat(event->TaskIndex, 3, UserVar[event->BaseVarIndex + 3] - P109_CONFIG_STEP_TIMEOUT * 60); if (UserVar[event->BaseVarIndex + 3] < 0) { - UserVar.setFloat(event->TaskIndex, 3, 5400); + UserVar.setFloat(event->TaskIndex, 3, P109_CONFIG_MAX_TIMEOUT * 60); } _prev_timeout = P109_TIMEOUT_STATE_UNSET; break; @@ -461,9 +464,9 @@ void P109_data_struct::actionRight(struct EventStruct *event) { break; } case 2: { // manual on mode, timer dec - UserVar.setFloat(event->TaskIndex, 3, UserVar[event->BaseVarIndex + 3] + P109_BUTTON_DEBOUNCE_TIME_MS); + UserVar.setFloat(event->TaskIndex, 3, UserVar[event->BaseVarIndex + 3] + P109_CONFIG_STEP_TIMEOUT * 60); - if (UserVar[event->BaseVarIndex + 3] > 5400) { + if (UserVar[event->BaseVarIndex + 3] > P109_CONFIG_MAX_TIMEOUT * 60) { UserVar.setFloat(event->TaskIndex, 3, 60); } _prev_timeout = P109_TIMEOUT_STATE_UNSET; @@ -482,7 +485,7 @@ void P109_data_struct::actionMode(struct EventStruct *event) { break; } case 1: { // auto mode, next - setMode(F("m"), F("5")); + setMode(F("m"), toString(P109_CONFIG_TIMEOUT)); break; } case 2: { // manual on mode, next diff --git a/src/src/PluginStructs/P109_data_struct.h b/src/src/PluginStructs/P109_data_struct.h index 68b750586d..c34b6bc4dc 100644 --- a/src/src/PluginStructs/P109_data_struct.h +++ b/src/src/PluginStructs/P109_data_struct.h @@ -40,7 +40,6 @@ const char flameimg[] PROGMEM = { # define P109_TIMEOUT_STATE_UNSET 32768.0f # define P109_HEATING_STATE_UNSET 255 # define P109_MODE_STATE_UNSET 255 -# define P109_MODE_STATE_INITIAL 1 # define P109_BUTTON_DEBOUNCE_TIME_MS 300 # define P109_DEFAULT_SETPOINT_DELAY (5 + 1) // Seconds + 1 before the relay state is changed after the setpoint is changed # define P109_DELAY_BETWEEN_SAVE 30000 // 30 seconds @@ -50,8 +49,12 @@ const char flameimg[] PROGMEM = { # define P109_CONFIG_DISPLAYTYPE PCONFIG(2) # define P109_CONFIG_CONTRAST PCONFIG(3) # define P109_CONFIG_RELAYPIN PCONFIG(4) -# define P109_CONFIG_SETPOINT_DELAY PCONFIG(5) +# define P109_CONFIG_TIMEOUT PCONFIG(5) +# define P109_CONFIG_MAX_TIMEOUT PCONFIG(6) +# define P109_CONFIG_SETPOINT_DELAY PCONFIG(7) # define P109_CONFIG_HYSTERESIS PCONFIG_FLOAT(0) +# define P109_CONFIG_STEP_TIMEOUT PCONFIG_LONG(1) +# define P109_MODE_STATE_INITIAL PCONFIG_LONG(2) # define P109_SETPOINT_OFFSET 1 // 1 second offset, to allow changing unset (0) to default @@ -59,9 +62,16 @@ const char flameimg[] PROGMEM = { # define P109_FLAG_TASKNAME_IN_TITLE 0 # define P109_FLAG_ALTERNATE_HEADER 1 # define P109_FLAG_RELAY_INVERT 2 +# define P109_FLAG_BUTTON1_INT_PULL_UP 3 +# define P109_FLAG_BUTTON2_INT_PULL_UP 4 +# define P109_FLAG_BUTTON3_INT_PULL_UP 5 + # define P109_GET_TASKNAME_IN_TITLE bitRead(P109_FLAGS, P109_FLAG_TASKNAME_IN_TITLE) # define P109_GET_ALTERNATE_HEADER bitRead(P109_FLAGS, P109_FLAG_ALTERNATE_HEADER) # define P109_GET_RELAY_INVERT bitRead(P109_FLAGS, P109_FLAG_RELAY_INVERT) +# define P109_GET_BUTTON1_INT_PULL_UP bitRead(P109_FLAGS, P109_FLAG_BUTTON1_INT_PULL_UP) +# define P109_GET_BUTTON2_INT_PULL_UP bitRead(P109_FLAGS, P109_FLAG_BUTTON2_INT_PULL_UP) +# define P109_GET_BUTTON3_INT_PULL_UP bitRead(P109_FLAGS, P109_FLAG_BUTTON3_INT_PULL_UP) struct P109_data_struct : public PluginTaskData_base { P109_data_struct(); @@ -89,17 +99,19 @@ struct P109_data_struct : public PluginTaskData_base { float _prev_timeout = P109_TIMEOUT_STATE_UNSET; float _save_setpoint = P109_SETPOINT_STATE_UNSET; - int8_t _lastWiFiState = P109_WIFI_STATE_UNSET; - uint8_t _prev_heating = P109_HEATING_STATE_UNSET; - uint8_t _prev_mode = P109_MODE_STATE_UNSET; - uint8_t _taskIndex = 0; - uint8_t _varIndex = 0; - uint8_t _changed = 0; - uint8_t _saveneeded = 0; - uint8_t _setpointDelay = 0; - uint8_t _setpointTimeout = 0; - int8_t _relaypin = -1; - bool _relayInverted = false; + int8_t _lastWiFiState = P109_WIFI_STATE_UNSET; + uint8_t _prev_heating = P109_HEATING_STATE_UNSET; + uint8_t _prev_mode = P109_MODE_STATE_UNSET; + uint8_t _taskIndex = 0; + uint8_t _varIndex = 0; + uint8_t _changed = 0; + uint8_t _saveneeded = 0; + uint8_t _setpointDelay = 0; + uint8_t _setpointTimeout = 0; + int8_t _relaypin = -1; + bool _relayInverted = false; + bool _buttonIntPullup[3] = { true, true, true }; + uint8_t _timeout = 15; String _last_heater; String _title;