diff --git a/lib/AmsConfiguration/include/AmsConfiguration.h b/lib/AmsConfiguration/include/AmsConfiguration.h index 3f8cfa1c..7acbd349 100644 --- a/lib/AmsConfiguration/include/AmsConfiguration.h +++ b/lib/AmsConfiguration/include/AmsConfiguration.h @@ -4,7 +4,7 @@ #include "Arduino.h" #define EEPROM_SIZE 1024*3 -#define EEPROM_CHECK_SUM 102 // Used to check if config is stored. Change if structure changes +#define EEPROM_CHECK_SUM 103 // Used to check if config is stored. Change if structure changes #define EEPROM_CLEARED_INDICATOR 0xFC #define EEPROM_CONFIG_ADDRESS 0 #define EEPROM_TEMP_CONFIG_ADDRESS 2048 @@ -142,7 +142,8 @@ struct GpioConfig { uint8_t vccBootLimit; uint16_t vccResistorGnd; uint16_t vccResistorVcc; -}; // 20 + bool hanPinPullup; +}; // 21 struct DomoticzConfig { uint16_t elidx; @@ -314,6 +315,7 @@ private: bool relocateConfig96(); // 2.1.14 bool relocateConfig100(); // 2.2-dev bool relocateConfig101(); // 2.2.0 through 2.2.8 + bool relocateConfig102(); // 2.2.9 void saveToFs(); bool loadFromFs(uint8_t version); diff --git a/lib/AmsConfiguration/src/AmsConfiguration.cpp b/lib/AmsConfiguration/src/AmsConfiguration.cpp index 22996b35..cbf69fd6 100644 --- a/lib/AmsConfiguration/src/AmsConfiguration.cpp +++ b/lib/AmsConfiguration/src/AmsConfiguration.cpp @@ -406,6 +406,7 @@ bool AmsConfiguration::setGpioConfig(GpioConfig& config) { GpioConfig existing; if(getGpioConfig(existing)) { meterChanged |= config.hanPin != existing.hanPin; + meterChanged |= config.hanPinPullup != existing.hanPinPullup; } /* This currently does not work, as it checks its own pin if(pinUsed(config.hanPin, config)) { @@ -457,6 +458,7 @@ bool AmsConfiguration::setGpioConfig(GpioConfig& config) { void AmsConfiguration::clearGpio(GpioConfig& config) { config.hanPin = 3; + config.hanPinPullup = true; config.apPin = 0xFF; config.ledPin = 0xFF; config.ledInverted = true; @@ -796,6 +798,14 @@ bool AmsConfiguration::hasConfig() { configVersion = 0; return false; } + case 102: + configVersion = -1; // Prevent loop + if(relocateConfig102()) { + configVersion = 103; + } else { + configVersion = 0; + return false; + } case EEPROM_CHECK_SUM: return true; default: @@ -1017,6 +1027,20 @@ bool AmsConfiguration::relocateConfig101() { return ret; } +bool AmsConfiguration::relocateConfig102() { + EEPROM.begin(EEPROM_SIZE); + + GpioConfig gpioConfig; + EEPROM.get(CONFIG_GPIO_START, gpioConfig); + gpioConfig.hanPinPullup = true; + EEPROM.put(CONFIG_GPIO_START, gpioConfig); + + EEPROM.put(EEPROM_CONFIG_ADDRESS, 103); + bool ret = EEPROM.commit(); + EEPROM.end(); + return ret; +} + bool AmsConfiguration::save() { EEPROM.begin(EEPROM_SIZE); EEPROM.put(EEPROM_CONFIG_ADDRESS, EEPROM_CHECK_SUM); @@ -1171,6 +1195,7 @@ void AmsConfiguration::print(Print* debugger) if(getGpioConfig(gpio)) { debugger->println("--GPIO configuration--"); debugger->printf("HAN pin: %i\r\n", gpio.hanPin); + debugger->printf("HAN pin pullup %s\r\n", gpio.hanPinPullup ? "Yes" : "No"); debugger->printf("LED pin: %i\r\n", gpio.ledPin); debugger->printf("LED inverted: %s\r\n", gpio.ledInverted ? "Yes" : "No"); debugger->printf("LED red pin: %i\r\n", gpio.ledPinRed); diff --git a/lib/SvelteUi/app/src/lib/BoardTypeSelectOptions.svelte b/lib/SvelteUi/app/src/lib/BoardTypeSelectOptions.svelte index 6fefe749..ca77d508 100644 --- a/lib/SvelteUi/app/src/lib/BoardTypeSelectOptions.svelte +++ b/lib/SvelteUi/app/src/lib/BoardTypeSelectOptions.svelte @@ -42,6 +42,9 @@ {/if} {#if chip == 'esp32c3'} + + + diff --git a/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte b/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte index 67142a6e..eb209915 100644 --- a/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte +++ b/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte @@ -88,7 +88,8 @@ i: 0, e: 0, v: 0, a: 0, r: 0, c: 0, t: 0, p: 0, d: 0, m: 0, s: 0 }, i: { - h: null, a: null, + h: { p: null, u: true }, + a: null, l: { p: null, i: false }, r: { r: null, g: null, b: null, i: false }, t: { d: null, a: null }, @@ -599,8 +600,8 @@
- HAN
- pullup
+
diff --git a/lib/SvelteUi/app/src/lib/Helpers.js b/lib/SvelteUi/app/src/lib/Helpers.js index af66697d..dbda0b0c 100644 --- a/lib/SvelteUi/app/src/lib/Helpers.js +++ b/lib/SvelteUi/app/src/lib/Helpers.js @@ -87,6 +87,8 @@ export function boardtype(c, b) { return "Custom hardware by Roar Fredriksen"; case 1: return "Kamstrup module by Egil Opsahl"; + case 8: + return "µHAN mosquito by dbeinder" case 3: return "Pow-K (UART0)"; case 4: diff --git a/lib/SvelteUi/app/src/lib/UartSelectOptions.svelte b/lib/SvelteUi/app/src/lib/UartSelectOptions.svelte index 29bf47e1..3b2897f5 100644 --- a/lib/SvelteUi/app/src/lib/UartSelectOptions.svelte +++ b/lib/SvelteUi/app/src/lib/UartSelectOptions.svelte @@ -1,13 +1,21 @@ +{#if chip == 'esp32c3'} + +{:else} +{/if} {#if chip == 'esp8266'} {/if} diff --git a/lib/SvelteUi/json/conf_gpio.json b/lib/SvelteUi/json/conf_gpio.json index c887d2f3..6a0bc0e9 100644 --- a/lib/SvelteUi/json/conf_gpio.json +++ b/lib/SvelteUi/json/conf_gpio.json @@ -1,5 +1,8 @@ "i": { - "h": %s, + "h": { + "p": %s, + "u": %s + }, "a": %s, "l": { "p": %s, diff --git a/lib/SvelteUi/src/AmsWebServer.cpp b/lib/SvelteUi/src/AmsWebServer.cpp index 0c1f1a7d..84636d52 100644 --- a/lib/SvelteUi/src/AmsWebServer.cpp +++ b/lib/SvelteUi/src/AmsWebServer.cpp @@ -913,6 +913,7 @@ void AmsWebServer::configurationJson() { server.sendContent(buf); snprintf_P(buf, BufferSize, CONF_GPIO_JSON, gpioConfig->hanPin == 0xff ? "null" : String(gpioConfig->hanPin, 10).c_str(), + gpioConfig->hanPinPullup ? "true" : "false", gpioConfig->apPin == 0xff ? "null" : String(gpioConfig->apPin, 10).c_str(), gpioConfig->ledPin == 0xff ? "null" : String(gpioConfig->ledPin, 10).c_str(), gpioConfig->ledInverted ? "true" : "false", @@ -1001,6 +1002,15 @@ void AmsWebServer::handleSave() { } #elif defined(CONFIG_IDF_TARGET_ESP32C3) switch(boardType) { + case 8: // dbeinder: HAN mosquito + gpioConfig->hanPin = 7; + gpioConfig->hanPinPullup = false; + gpioConfig->apPin = 9; + gpioConfig->ledRgbInverted = true; + gpioConfig->ledPinRed = 5; + gpioConfig->ledPinGreen = 6; + gpioConfig->ledPinBlue = 4; + break; case 71: // ESP32-C3-DevKitM-1 gpioConfig->apPin = 9; case 70: // Generic ESP32-C3 @@ -1137,6 +1147,7 @@ void AmsWebServer::handleSave() { meterConfig->baud = 2400; meterConfig->parity = 3; // 8N1 case 2: // spenceme + case 8: // dbeinder: HAN mosquito case 50: // Generic ESP32-S2 case 51: // Wemos S2 mini case 70: // Generic ESP32-C3 @@ -1329,7 +1340,8 @@ void AmsWebServer::handleSave() { if(server.hasArg(F("i")) && server.arg(F("i")) == F("true")) { if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf(PSTR("Received GPIO config")); - gpioConfig->hanPin = server.hasArg(F("ih")) && !server.arg(F("ih")).isEmpty() ? server.arg(F("ih")).toInt() : 3; + gpioConfig->hanPin = server.hasArg(F("ihp")) && !server.arg(F("ihp")).isEmpty() ? server.arg(F("ihp")).toInt() : 3; + gpioConfig->hanPinPullup = server.hasArg(F("ihu")) && server.arg(F("ihu")) == F("true"); gpioConfig->ledPin = server.hasArg(F("ilp")) && !server.arg(F("ilp")).isEmpty() ? server.arg(F("ilp")).toInt() : 0xFF; gpioConfig->ledInverted = server.hasArg(F("ili")) && server.arg(F("ili")) == F("true"); gpioConfig->ledPinRed = server.hasArg(F("irr")) && !server.arg(F("irr")).isEmpty() ? server.arg(F("irr")).toInt() : 0xFF; @@ -1996,6 +2008,7 @@ void AmsWebServer::configFileDownload() { GpioConfig gpio; config->getGpioConfig(gpio); if(gpio.hanPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioHanPin %d\n"), gpio.hanPin)); + if(gpio.hanPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioHanPinPullup %d\n"), gpio.hanPinPullup ? 1 : 0)); if(gpio.apPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioApPin %d\n"), gpio.apPin)); if(gpio.ledPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioLedPin %d\n"), gpio.ledPin)); if(gpio.ledPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioLedInverted %d\n"), gpio.ledInverted ? 1 : 0)); diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index 3e618c69..85f3cdab 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -564,7 +564,7 @@ void loop() { if(config.isMeterChanged()) { config.getMeterConfig(meterConfig); - setupHanPort(gpioConfig.hanPin, meterConfig.baud, meterConfig.parity, meterConfig.invert); + setupHanPort(gpioConfig, meterConfig.baud, meterConfig.parity, meterConfig.invert); config.ackMeterChanged(); delete gcmParser; gcmParser = NULL; @@ -607,7 +607,7 @@ void loop() { meterAutoIndex++; // Default is to try the first one in setup() debugI("Meter serial autodetect, swapping to: %d, %d, %s", bauds[meterAutoIndex], parities[meterAutoIndex], inverts[meterAutoIndex] ? "true" : "false"); if(meterAutoIndex >= 4) meterAutoIndex = 0; - setupHanPort(gpioConfig.hanPin, bauds[meterAutoIndex], parities[meterAutoIndex], inverts[meterAutoIndex]); + setupHanPort(gpioConfig, bauds[meterAutoIndex], parities[meterAutoIndex], inverts[meterAutoIndex]); meterAutodetectLastChange = now; } } else if(meterAutodetect) { @@ -617,7 +617,7 @@ void loop() { meterConfig.parity = parities[meterAutoIndex]; meterConfig.invert = inverts[meterAutoIndex]; config.setMeterConfig(meterConfig); - setupHanPort(gpioConfig.hanPin, meterConfig.baud, meterConfig.parity, meterConfig.invert); + setupHanPort(gpioConfig, meterConfig.baud, meterConfig.parity, meterConfig.invert); } } catch(const std::exception& e) { debugE("Exception in meter autodetect (%s)", e.what()); @@ -632,7 +632,9 @@ void loop() { #endif } -void setupHanPort(uint8_t pin, uint32_t baud, uint8_t parityOrdinal, bool invert) { +void setupHanPort(GpioConfig& gpioConfig, uint32_t baud, uint8_t parityOrdinal, bool invert) { + uint8_t pin = gpioConfig.hanPin; + if(Debug.isActive(RemoteDebug::INFO)) Debug.printf((char*) F("(setupHanPort) Setting up HAN on pin %d with baud %d and parity %d\n"), pin, baud, parityOrdinal); if(baud == 0) { @@ -644,6 +646,14 @@ void setupHanPort(uint8_t pin, uint32_t baud, uint8_t parityOrdinal, bool invert parityOrdinal = 3; // 8N1 } + SystemConfig sys; + config.getSystemConfig(sys); + switch(sys.boardType) { + case 8: // HAN mosquito: has inverting level shifter + invert = !invert; + break; + } + HardwareSerial *hwSerial = NULL; if(pin == 3 || pin == 113) { hwSerial = &Serial; @@ -743,6 +753,11 @@ void setupHanPort(uint8_t pin, uint32_t baud, uint8_t parityOrdinal, bool invert Serial.begin(115200); } + // The library automatically sets the pullup in Serial.begin() + if(!gpioConfig.hanPinPullup) { + pinMode(gpioConfig.hanPin, INPUT); + } + // Empty buffer before starting while (hanSerial->available() > 0) { hanSerial->read(); @@ -1621,6 +1636,9 @@ void configFileParse() { } else if(strncmp_P(buf, PSTR("gpioHanPin "), 11) == 0) { if(!lGpio) { config.getGpioConfig(gpio); lGpio = true; }; gpio.hanPin = String(buf+11).toInt(); + } else if(strncmp_P(buf, PSTR("gpioHanPinPullup "), 17) == 0) { + if(!lGpio) { config.getGpioConfig(gpio); lGpio = true; }; + gpio.hanPinPullup = String(buf+17).toInt() == 1; } else if(strncmp_P(buf, PSTR("gpioApPin "), 10) == 0) { if(!lGpio) { config.getGpioConfig(gpio); lGpio = true; }; gpio.apPin = String(buf+10).toInt();