From 6b67591cc18f51e7de03c2bec8ec2a80e9123359 Mon Sep 17 00:00:00 2001 From: Siwat Sirichai Date: Mon, 20 May 2024 00:13:43 +0700 Subject: [PATCH 01/22] Update ESPMegaCommon.hpp --- ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp index a724426..377ba10 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp @@ -1,3 +1,3 @@ #pragma once -#define SDK_VESRION "2.6.1" \ No newline at end of file +#define SDK_VESRION "2.7.0" \ No newline at end of file From ea49576b206582d2a8bab9fab3fcb22239c33e6a Mon Sep 17 00:00:00 2001 From: Siwat Sirichai Date: Mon, 20 May 2024 00:44:18 +0700 Subject: [PATCH 02/22] global state request --- .gitignore | 1 + ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaIoT.cpp | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/.gitignore b/.gitignore index 9bea433..a965236 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .DS_Store +/ESPMegaPRO-OS-SDK diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaIoT.cpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaIoT.cpp index 80fd0d3..2b9c877 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaIoT.cpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaIoT.cpp @@ -56,6 +56,16 @@ void ESPMegaIoT::mqttCallback(char *topic, byte *payload, unsigned int length) { callback.second(topic_without_base, payload_buffer); } + // Check for global state request + if (!strcmp(topic_without_base,"requeststate")) { + for (int i = 0; i < 255; i++) + { + if (components[i] != NULL) + { + components[i]->publishReport(); + } + } + } // Call the respective card's mqtt callback // Note that after the base topic, there should be the card id // /base_topic/card_id/... From 3e7d3041f2ac8fce10f5bb6f1cc4af6288c845e2 Mon Sep 17 00:00:00 2001 From: Siwat Sirichai Date: Mon, 20 May 2024 00:53:09 +0700 Subject: [PATCH 03/22] mqtt summary request --- .../lib/ESPMegaPRO/ESPMegaIoT.cpp | 36 +++++++++++++++++++ .../lib/ESPMegaPRO/ESPMegaIoT.hpp | 3 ++ 2 files changed, 39 insertions(+) diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaIoT.cpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaIoT.cpp index 2b9c877..b11e46b 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaIoT.cpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaIoT.cpp @@ -66,6 +66,10 @@ void ESPMegaIoT::mqttCallback(char *topic, byte *payload, unsigned int length) } } } + // Check for global summary request + if (!strcmp(topic_without_base,"requestinfo")) { + this->publishSystemSummary(); + } // Call the respective card's mqtt callback // Note that after the base topic, there should be the card id // /base_topic/card_id/... @@ -844,3 +848,35 @@ String ESPMegaIoT::getMac() else return this->getETHMac(); } + +/** + * @brief Publish a json object containing the system summary + */ +void ESPMegaIoT::publishSystemSummary() { + char payload[1024]; + StaticJsonDocument<1024> doc; + JsonObject root = doc.to(); + root["ip"] = this->getIp().toString(); + root["mac"] = this->getMac(); + root["mqtt_connected"] = this->mqttConnected(); + root["network_connected"] = this->networkConnected(); + root["mqtt_server"] = this->mqtt_config.mqtt_server; + root["mqtt_port"] = this->mqtt_config.mqtt_port; + root["hostname"] = this->network_config.hostname; + root["firmware"] = SW_VERSION; + root["idf_version"] = esp_get_idf_version(); + root["sdk_version"] = SDK_VESRION; + root["board_model"] = BOARD_MODEL; + JsonArray cards = root.createNestedArray("cards"); + for (int i = 0; i < 255; i++) + { + if (components[i] != NULL) + { + JsonObject card = cards.createNestedObject(); + card["id"] = i; + card["type"] = components[i]->getType(); + } + } + serializeJson(doc, payload); + this->publishRelative("info", payload); +} \ No newline at end of file diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaIoT.hpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaIoT.hpp index c5467b2..d47f723 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaIoT.hpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaIoT.hpp @@ -16,6 +16,8 @@ #include #include #include +#include +#include // MQTT Connection Parameters #define TCP_TIMEOUT_SEC 5 @@ -115,6 +117,7 @@ public: void bindEthernetInterface(ETHClass *ethernetIface); bool networkConnected(); void bindFRAM(FRAM *fram); + void publishSystemSummary(); IoTComponent* getComponent(uint8_t card_id); IPAddress getETHIp(); From 2430b43f77546c768c23aeb77abee3a8062df37f Mon Sep 17 00:00:00 2001 From: Siwat Sirichai Date: Mon, 20 May 2024 01:25:25 +0700 Subject: [PATCH 04/22] info request --- .../lib/ESPMegaPRO/ESPMegaIoT.cpp | 45 +++++++++++++++---- .../lib/ESPMegaPRO/ESPMegaIoT.hpp | 2 + ESPMegaPRO-OS-SDK/src/main.cpp | 7 +-- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaIoT.cpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaIoT.cpp index b11e46b..51ffd56 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaIoT.cpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaIoT.cpp @@ -65,10 +65,12 @@ void ESPMegaIoT::mqttCallback(char *topic, byte *payload, unsigned int length) components[i]->publishReport(); } } + return; } // Check for global summary request if (!strcmp(topic_without_base,"requestinfo")) { this->publishSystemSummary(); + return; } // Call the respective card's mqtt callback // Note that after the base topic, there should be the card id @@ -393,6 +395,18 @@ void ESPMegaIoT::publish(const char *topic, const char *payload) mqtt.publish(topic, payload); } +/** + * @brief Publish a message to a topic + * + * @param topic The topic to publish to + * @param payload The payload to publish + * @param length The length of the payload + */ +void ESPMegaIoT::publish(const char *topic, const char *payload, unsigned int length) +{ + mqtt.publish(topic, (const uint8_t *)payload, length); +} + /** * @brief Register a callback for MQTT messages * @@ -416,7 +430,7 @@ void ESPMegaIoT::unregisterMqttCallback(uint16_t handler) } /** - * @brief Subscribe to all components's topics + * @brief Subscribe to all components's topics and all other topics */ void ESPMegaIoT::mqttSubscribe() { @@ -436,6 +450,9 @@ void ESPMegaIoT::mqttSubscribe() mqtt.loop(); } } + // Global topics + this->subscribeRelative("requeststate"); + this->subscribeRelative("requestinfo"); } /** @@ -531,6 +548,21 @@ void ESPMegaIoT::publishRelative(const char *topic, const char *payload) mqtt.loop(); } +/** + * @brief Publish a message relative to the base topic + * + * @param topic The topic to publish to + * @param payload The payload to publish + * @param length The length of the payload + */ +void ESPMegaIoT::publishRelative(const char *topic, const char *payload, unsigned int length) +{ + char absolute_topic[100]; + sprintf(absolute_topic, "%s/%s", this->mqtt_config.base_topic, topic); + mqtt.publish(absolute_topic, (const uint8_t *)payload, length); + mqtt.loop(); +} + /** * @brief Subscribe to a topic relative to the base topic * @@ -857,14 +889,7 @@ void ESPMegaIoT::publishSystemSummary() { StaticJsonDocument<1024> doc; JsonObject root = doc.to(); root["ip"] = this->getIp().toString(); - root["mac"] = this->getMac(); - root["mqtt_connected"] = this->mqttConnected(); - root["network_connected"] = this->networkConnected(); - root["mqtt_server"] = this->mqtt_config.mqtt_server; - root["mqtt_port"] = this->mqtt_config.mqtt_port; - root["hostname"] = this->network_config.hostname; root["firmware"] = SW_VERSION; - root["idf_version"] = esp_get_idf_version(); root["sdk_version"] = SDK_VESRION; root["board_model"] = BOARD_MODEL; JsonArray cards = root.createNestedArray("cards"); @@ -878,5 +903,7 @@ void ESPMegaIoT::publishSystemSummary() { } } serializeJson(doc, payload); - this->publishRelative("info", payload); + ESP_LOGD("ESPMegaIoT", "Publishing system summary: %s", payload); + mqtt.loop(); + this->publishRelative("info", payload, strlen(payload)); } \ No newline at end of file diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaIoT.hpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaIoT.hpp index d47f723..76498c0 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaIoT.hpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaIoT.hpp @@ -83,6 +83,7 @@ public: void publishCard(uint8_t card_id); // Publish topic appended with base topic void publishRelative(const char *topic, const char *payload); + void publishRelative(const char *topic, const char *payload, unsigned int length); // Subscribe topic appended with base topic void subscribeRelative(const char *topic); void subscribe(const char *topic); @@ -107,6 +108,7 @@ public: bool mqttConnected(); void disconnectFromMqtt(); void publish(const char *topic, const char *payload); + void publish(const char *topic, const char *payload, unsigned int length); uint16_t registerMqttCallback(std::function callback); void unregisterMqttCallback(uint16_t handler); uint16_t registerRelativeMqttCallback(std::function callback); diff --git a/ESPMegaPRO-OS-SDK/src/main.cpp b/ESPMegaPRO-OS-SDK/src/main.cpp index e8e43af..aa0bedf 100644 --- a/ESPMegaPRO-OS-SDK/src/main.cpp +++ b/ESPMegaPRO-OS-SDK/src/main.cpp @@ -15,13 +15,13 @@ // #define FRAM_DEBUG // #define MQTT_DEBUG #define WRITE_DEFAULT_NETCONF -//#define CLIMATE_CARD_ENABLE +#define CLIMATE_CARD_ENABLE #define MQTT_CARD_REGISTER #define DISPLAY_ENABLE #define WEB_SERVER_ENABLE #define LCD_OTA_ENABLE -//#define REMOTE_VARIABLE_ENABLE -//#define CT_ENABLE +// #define REMOTE_VARIABLE_ENABLE +// #define CT_ENABLE #define SMART_VARIABLE_ENABLE // Demo PLC firmware using the ESPMegaPRO OOP library @@ -236,6 +236,7 @@ void setup() ct.bindFRAM(&espmega.fram, 7000); ct.loadEnergy(); ct.setEnergyAutoSave(true); + espmega.iot->registerCard(3); #endif #ifdef SMART_VARIABLE_ENABLE ESP_LOGI("Initializer", "Initializing smart variable"); From 64d6c4fab3e2e8fefded0898ecc07421dcf64dd7 Mon Sep 17 00:00:00 2001 From: Siwat Sirichai Date: Mon, 20 May 2024 01:29:36 +0700 Subject: [PATCH 05/22] Update ESPMegaCommon.hpp --- ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp index 377ba10..59d64f4 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp @@ -1,3 +1,3 @@ #pragma once -#define SDK_VESRION "2.7.0" \ No newline at end of file +#define SDK_VESRION "2.8.0" \ No newline at end of file From b30cfde0b082593d321e426be3f82b174b417f29 Mon Sep 17 00:00:00 2001 From: Siwat Sirichai Date: Tue, 21 May 2024 23:50:21 +0700 Subject: [PATCH 06/22] working ntp without offset --- .../lib/ESPMegaPRO/ESPMegaCommon.hpp | 2 +- .../lib/ESPMegaPRO/ESPMegaProOS.cpp | 51 +++++++++++++++---- .../lib/ESPMegaPRO/ESPMegaProOS.hpp | 6 +++ ESPMegaPRO-OS-SDK/src/main.cpp | 15 +++++- 4 files changed, 60 insertions(+), 14 deletions(-) diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp index 59d64f4..ab46b85 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp @@ -1,3 +1,3 @@ #pragma once -#define SDK_VESRION "2.8.0" \ No newline at end of file +#define SDK_VESRION "2.9.0" \ No newline at end of file diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.cpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.cpp index 5db70e5..d1a9c41 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.cpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.cpp @@ -1,4 +1,5 @@ #include +#include "esp_sntp.h" // Reserve FRAM address 0 - 1000 for ESPMegaPRO Internal Use // (34 Bytes) Address 0-33 for Built-in Digital Output Card @@ -11,6 +12,7 @@ */ ESPMegaPRO::ESPMegaPRO() { + } /** @@ -102,6 +104,13 @@ void ESPMegaPRO::loop() if (iotEnabled) { iot->loop(); + static int64_t lastNTPUpdate = (esp_timer_get_time() / 1000) - NTP_UPDATE_INTERVAL_MS + NTP_INITIAL_SYNC_DELAY_MS; + if ((esp_timer_get_time() / 1000) - lastNTPUpdate > NTP_UPDATE_INTERVAL_MS) + { + ESP_LOGV("ESPMegaPRO", "Updating time from NTP"); + lastNTPUpdate = esp_timer_get_time() / 1000; + this->updateTimeFromNTP(); + } } if (internalDisplayEnabled) { @@ -153,19 +162,35 @@ bool ESPMegaPRO::installCard(uint8_t slot, ExpansionCard *card) bool ESPMegaPRO::updateTimeFromNTP() { struct tm timeinfo; - if (getLocalTime(&timeinfo)) + uint32_t start = esp_timer_get_time() / 1000; + time_t now; + time(&now); + localtime_r(&now, &timeinfo); + if (!(timeinfo.tm_year > (2016 - 1900))) { - rtctime_t rtctime = this->getTime(); - if (rtctime.hours != timeinfo.tm_hour || rtctime.minutes != timeinfo.tm_min || - rtctime.seconds != timeinfo.tm_sec || rtctime.day != timeinfo.tm_mday || - rtctime.month != timeinfo.tm_mon + 1 || rtctime.year != timeinfo.tm_year + 1900) - { - this->setTime(timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec, - timeinfo.tm_mday, timeinfo.tm_mon + 1, timeinfo.tm_year + 1900); - } - return true; + ESP_LOGI("ESPMegaPRO", "NTP is not ready yet!"); + return false; } - return false; + rtctime_t rtctime = this->getTime(); + if (rtctime.hours != timeinfo.tm_hour || rtctime.minutes != timeinfo.tm_min || + rtctime.seconds != timeinfo.tm_sec || rtctime.day != timeinfo.tm_mday || + rtctime.month != timeinfo.tm_mon + 1 || rtctime.year != timeinfo.tm_year + 1900) + { + this->setTime(timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec, + timeinfo.tm_mday, timeinfo.tm_mon + 1, timeinfo.tm_year + 1900); + } + ESP_LOGV("ESPMegaPRO", "Time updated from NTP: %s", asctime(&timeinfo)); + return true; +} + +#include + +void ESPMegaPRO::setUTCOffset(int offset) +{ + std::ostringstream oss; + oss << "UTC" << (offset >= 0 ? "+" : "") << offset; + setenv("TZ", oss.str().c_str(), 1); + tzset(); } /** @@ -222,6 +247,10 @@ void ESPMegaPRO::enableIotModule() this->iot->bindFRAM(&fram); this->iot->intr_begin(cards); iotEnabled = true; + sntp_setoperatingmode(SNTP_OPMODE_POLL); + sntp_setservername(0, this->iot->getMqttConfig()->mqtt_server); + sntp_setservername(1, "pool.ntp.org"); + sntp_init(); } /** diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.hpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.hpp index 4b6bd14..2721a58 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.hpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.hpp @@ -24,6 +24,11 @@ #define PWM_BANK_ADDRESS 0x5F #define RTC_ADDRESS 0x68 +// Constants +#define NTP_TIMEOUT_MS 5000 +#define NTP_UPDATE_INTERVAL_MS 60000 +#define NTP_INITIAL_SYNC_DELAY_MS 15000 + /** * @brief The ESPMegaPRO class is the main class for the ESPMegaPRO library. * @@ -47,6 +52,7 @@ class ESPMegaPRO { void enableIotModule(); void enableInternalDisplay(HardwareSerial *serial); void enableWebServer(uint16_t port); + void setUTCOffset(int offset); rtctime_t getTime(); void dumpFRAMtoSerial(uint16_t start, uint16_t end); void dumpFRAMtoSerialASCII(uint16_t start, uint16_t end); diff --git a/ESPMegaPRO-OS-SDK/src/main.cpp b/ESPMegaPRO-OS-SDK/src/main.cpp index aa0bedf..03572b6 100644 --- a/ESPMegaPRO-OS-SDK/src/main.cpp +++ b/ESPMegaPRO-OS-SDK/src/main.cpp @@ -14,15 +14,16 @@ // #define FRAM_DEBUG // #define MQTT_DEBUG +// #define RTC_DEBUG #define WRITE_DEFAULT_NETCONF #define CLIMATE_CARD_ENABLE #define MQTT_CARD_REGISTER -#define DISPLAY_ENABLE +// #define DISPLAY_ENABLE #define WEB_SERVER_ENABLE #define LCD_OTA_ENABLE // #define REMOTE_VARIABLE_ENABLE // #define CT_ENABLE -#define SMART_VARIABLE_ENABLE +// #define SMART_VARIABLE_ENABLE // Demo PLC firmware using the ESPMegaPRO OOP library @@ -162,6 +163,7 @@ void setup() { ESP_LOGI("Initializer", "Starting ESPMegaPRO OOP demo"); espmega.begin(); + espmega.setUTCOffset(7); ESP_LOGI("Initializer", "Enabling IOT module"); espmega.enableIotModule(); ESP_LOGI("Initializer", "Enabling Ethernet"); @@ -326,4 +328,13 @@ void loop() smartVar.setValue(last_smartvar_state ? "true" : "false"); } #endif +#ifdef RTC_DEBUG + static uint32_t last_time_print = 0; + if (millis() - last_time_print >= 1000) + { + last_time_print = millis(); + rtctime_t time = espmega.getTime(); + Serial.printf("Time: %02d:%02d:%02d %02d/%02d/%04d\n", time.hours, time.minutes, time.seconds, time.day, time.month, time.year); + } +#endif } \ No newline at end of file From b62ef700edd3fb1ee6bac13b22c9a8264670f89c Mon Sep 17 00:00:00 2001 From: Siwat Sirichai Date: Wed, 22 May 2024 00:06:12 +0700 Subject: [PATCH 07/22] working timezone config --- ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.cpp | 14 +++++++------- ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.hpp | 2 +- ESPMegaPRO-OS-SDK/src/main.cpp | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.cpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.cpp index d1a9c41..44b7f07 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.cpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.cpp @@ -183,14 +183,14 @@ bool ESPMegaPRO::updateTimeFromNTP() return true; } -#include - -void ESPMegaPRO::setUTCOffset(int offset) +/** + * @brief Sets the timezone for the internal RTC. + * + * @note This function takes POSIX timezone strings (e.g. "EST5EDT,M3.2.0,M11.1.0"). +*/ +void ESPMegaPRO::setTimezone(const char* offset) { - std::ostringstream oss; - oss << "UTC" << (offset >= 0 ? "+" : "") << offset; - setenv("TZ", oss.str().c_str(), 1); - tzset(); + setenv("TZ", offset, 1); } /** diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.hpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.hpp index 2721a58..f78bc86 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.hpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.hpp @@ -52,7 +52,7 @@ class ESPMegaPRO { void enableIotModule(); void enableInternalDisplay(HardwareSerial *serial); void enableWebServer(uint16_t port); - void setUTCOffset(int offset); + void setTimezone(const char* offset); rtctime_t getTime(); void dumpFRAMtoSerial(uint16_t start, uint16_t end); void dumpFRAMtoSerialASCII(uint16_t start, uint16_t end); diff --git a/ESPMegaPRO-OS-SDK/src/main.cpp b/ESPMegaPRO-OS-SDK/src/main.cpp index 03572b6..d73714b 100644 --- a/ESPMegaPRO-OS-SDK/src/main.cpp +++ b/ESPMegaPRO-OS-SDK/src/main.cpp @@ -163,7 +163,7 @@ void setup() { ESP_LOGI("Initializer", "Starting ESPMegaPRO OOP demo"); espmega.begin(); - espmega.setUTCOffset(7); + espmega.setTimezone("UTC-7"); ESP_LOGI("Initializer", "Enabling IOT module"); espmega.enableIotModule(); ESP_LOGI("Initializer", "Enabling Ethernet"); From d0ce4bf391f9a55574ea4dd0c897ee0546085c0e Mon Sep 17 00:00:00 2001 From: Siwat Sirichai Date: Fri, 21 Jun 2024 16:35:26 +0700 Subject: [PATCH 08/22] change debouce logic --- .../lib/ESPMegaPRO/DigitalInputCard.cpp | 45 ++++++++++++++----- .../lib/ESPMegaPRO/DigitalInputCard.hpp | 1 + 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.cpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.cpp index 86ad5a1..5103c9b 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.cpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.cpp @@ -137,25 +137,50 @@ void DigitalInputCard::handlePinChange(int pin, uint8_t ¤tBuffer, uint8_t // Handle Bank A if (((previousBuffer >> (7 - pin)) & 1) != ((currentBuffer >> (7 - pin)) & 1)) { - if (millis() - lastDebounceTime[pin] > debounceTime[pin]) - { + if (!pinChanged[pin]) { lastDebounceTime[pin] = millis(); - previousBuffer ^= (-((currentBuffer >> (7 - pin)) & 1) ^ previousBuffer) & (1UL << (7 - pin)); - for(const auto& callback : callbacks) - callback.second(virtualPin, ((currentBuffer >> (7 - pin)) & 1)); + pinChanged[pin] = true; + } else { + if (millis() - lastDebounceTime[pin] > debounceTime[pin]) + { + previousBuffer ^= (-((currentBuffer >> (7 - pin)) & 1) ^ previousBuffer) & (1UL << (7 - pin)); + for (const auto& callback : callbacks) + callback.second(virtualPin, ((currentBuffer >> (7 - pin)) & 1)); + pinChanged[pin] = false; + } } } // Handle Bank B if (((previousBuffer >> (15 - pin)) & 1) != ((currentBuffer >> (15 - pin)) & 1)) { - if (millis() - lastDebounceTime[pin] > debounceTime[pin]) - { + if (!pinChanged[pin]) { lastDebounceTime[pin] = millis(); - previousBuffer ^= (-((currentBuffer >> (15 - pin)) & 1) ^ previousBuffer) & (1UL << (15 - pin)); - for (const auto& callback : callbacks) - callback.second(virtualPin, ((currentBuffer >> (15 - pin)) & 1)); + pinChanged[pin] = true; + } else { + if (millis() - lastDebounceTime[pin] > debounceTime[pin]) + { + previousBuffer ^= (-((currentBuffer >> (15 - pin)) & 1) ^ previousBuffer) & (1UL << (15 - pin)); + for (const auto& callback : callbacks) + callback.second(virtualPin, ((currentBuffer >> (15 - pin)) & 1)); + pinChanged[pin] = false; + } } } + + + + // // Handle Bank B + // if (((previousBuffer >> (15 - pin)) & 1) != ((currentBuffer >> (15 - pin)) & 1)) + // { + // if (millis() - lastDebounceTime[pin] > debounceTime[pin]) + // { + // lastDebounceTime[pin] = millis(); + // previousBuffer ^= (-((currentBuffer >> (15 - pin)) & 1) ^ previousBuffer) & (1UL << (15 - pin)); + // for (const auto& callback : callbacks) + // callback.second(virtualPin, ((currentBuffer >> (15 - pin)) & 1)); + // } + // } + } /** diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.hpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.hpp index a140029..3ba7805 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.hpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.hpp @@ -54,6 +54,7 @@ class DigitalInputCard : public ExpansionCard { uint8_t previousInputBufferB; uint32_t debounceTime[16]; uint32_t lastDebounceTime[16]; + bool pinChanged[16]; // A map of the physical pin to the virtual pin uint8_t pinMap[16]; // A map of the virtual pin to the physical pin From 221d8e59f5318d2fe23b5b54d1a0595073b74697 Mon Sep 17 00:00:00 2001 From: Siwat Sirichai Date: Fri, 21 Jun 2024 20:57:53 +0700 Subject: [PATCH 09/22] Update ESPMegaCommon.hpp --- ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp index ab46b85..3c1fa1d 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp @@ -1,3 +1,3 @@ #pragma once -#define SDK_VESRION "2.9.0" \ No newline at end of file +#define SDK_VESRION "2.9.1" \ No newline at end of file From b778fb6a02de660f34b5bddcabbe2f56ee5a75ff Mon Sep 17 00:00:00 2001 From: Siwat Sirichai Date: Fri, 21 Jun 2024 21:02:11 +0700 Subject: [PATCH 10/22] Update DigitalInputCard.cpp --- .../lib/ESPMegaPRO/DigitalInputCard.cpp | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.cpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.cpp index 5103c9b..0cf87f0 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.cpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.cpp @@ -167,20 +167,6 @@ void DigitalInputCard::handlePinChange(int pin, uint8_t ¤tBuffer, uint8_t } } - - - // // Handle Bank B - // if (((previousBuffer >> (15 - pin)) & 1) != ((currentBuffer >> (15 - pin)) & 1)) - // { - // if (millis() - lastDebounceTime[pin] > debounceTime[pin]) - // { - // lastDebounceTime[pin] = millis(); - // previousBuffer ^= (-((currentBuffer >> (15 - pin)) & 1) ^ previousBuffer) & (1UL << (15 - pin)); - // for (const auto& callback : callbacks) - // callback.second(virtualPin, ((currentBuffer >> (15 - pin)) & 1)); - // } - // } - } /** From 4ea2122f6eecc344fe253f47e37cc966e77e95c8 Mon Sep 17 00:00:00 2001 From: Siwat Sirichai Date: Fri, 21 Jun 2024 21:34:51 +0700 Subject: [PATCH 11/22] allow input preload and state toggling --- .../lib/ESPMegaPRO/DigitalInputCard.cpp | 12 ++++++++++++ .../lib/ESPMegaPRO/DigitalInputCard.hpp | 2 ++ .../lib/ESPMegaPRO/DigitalOutputCard.cpp | 9 +++++++++ .../lib/ESPMegaPRO/DigitalOutputCard.hpp | 2 ++ ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp | 2 +- 5 files changed, 26 insertions(+), 1 deletion(-) diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.cpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.cpp index 0cf87f0..9ae678d 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.cpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.cpp @@ -310,4 +310,16 @@ void DigitalInputCard::loadPinMap(uint8_t pinMap[16]) uint8_t DigitalInputCard::getType() { return CARD_TYPE_DIGITAL_INPUT; +} + +/** + * @brief Preload the previous input buffer and the input buffer + * + * @note This function is useful if you want to preload the input buffers with a run-time value + */ +void DigitalInputCard::preloadInputBuffer() { + refreshInputBankA(); + refreshInputBankB(); + previousInputBufferA = inputBufferA; + previousInputBufferB = inputBufferB; } \ No newline at end of file diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.hpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.hpp index 3ba7805..f5587ba 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.hpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.hpp @@ -41,6 +41,8 @@ class DigitalInputCard : public ExpansionCard { void unregisterCallback(uint8_t handler); // Load a new pin map void loadPinMap(uint8_t pinMap[16]); + // Preload previousInputBuffer and inputBuffer + void preloadInputBuffer(); // Get type of card uint8_t getType(); private: diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalOutputCard.cpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalOutputCard.cpp index cefa8e8..d760dc1 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalOutputCard.cpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalOutputCard.cpp @@ -306,4 +306,13 @@ void DigitalOutputCard::saveStateToFRAM() { if(!framBinded) return; uint16_t packed = packStates(); this->fram->write16(framAddress, packed); +} + +/** + * @brief Toggle the state of the specified pin + * + * @param pin The pin to toggle + */ +void DigitalOutputCard::toggleState(uint8_t pin) { + this->setState(pin, !this->state_buffer[pin]); } \ No newline at end of file diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalOutputCard.hpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalOutputCard.hpp index a3ed97c..88ebbaa 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalOutputCard.hpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalOutputCard.hpp @@ -58,6 +58,8 @@ public: void setValue(uint8_t pin, uint16_t value); // Get the state of the specified pin bool getState(uint8_t pin); + // Toggle the state of the specified pin + void toggleState(uint8_t pin); // Get the pwm value of the specified pin uint16_t getValue(uint8_t pin); // Register a callback function that will be called when the state of a pin changes diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp index 3c1fa1d..655573d 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp @@ -1,3 +1,3 @@ #pragma once -#define SDK_VESRION "2.9.1" \ No newline at end of file +#define SDK_VESRION "2.9.2" \ No newline at end of file From 8aeb6ab30a357911c70e8d727236046fa6921ae6 Mon Sep 17 00:00:00 2001 From: Siwat Sirichai Date: Fri, 21 Jun 2024 23:11:08 +0700 Subject: [PATCH 12/22] improve debounce --- .../lib/ESPMegaPRO/DigitalInputCard.cpp | 152 ++++++++++++------ .../lib/ESPMegaPRO/ESPMegaCommon.hpp | 2 +- ESPMegaPRO-OS-SDK/src/main.cpp | 23 ++- 3 files changed, 119 insertions(+), 58 deletions(-) diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.cpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.cpp index 9ae678d..b68972a 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.cpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.cpp @@ -3,8 +3,8 @@ /** * @brief Create a new Digital Input Card object with the specified address * @note If you are using the ESPMegaI/O board, you should use the dip switch constructor - * - * @param address_a The ESPMegaI/O address of bank A + * + * @param address_a The ESPMegaI/O address of bank A * @param address_b The ESPMegaI/O address of bank B */ DigitalInputCard::DigitalInputCard(uint8_t address_a, uint8_t address_b) : callbacks() @@ -16,11 +16,11 @@ DigitalInputCard::DigitalInputCard(uint8_t address_a, uint8_t address_b) : callb /** * @brief Create a new Digital Input Card object with the specified position on the dip switch - * + * * @note The bit 0 are at the left of the dip switch - * + * * @warning There are 6 switches on the dip switch, 3 for bank A and 3 for bank B, They should be unique for each bank accross all the cards - * + * * @param bit0 The position of the first switch on the dip switch * @param bit1 The position of the second switch on the dip switch * @param bit2 The position of the third switch on the dip switch @@ -50,18 +50,20 @@ DigitalInputCard::DigitalInputCard(bool bit0, bool bit1, bool bit2, bool bit3, b /** * @brief Initialize the Digital Input Card - * + * * @return True if the initialization is successful, false otherwise */ bool DigitalInputCard::begin() { this->inputBankA = PCF8574(this->address_a); this->inputBankB = PCF8574(this->address_b); - if (!this->inputBankA.begin()) { + if (!this->inputBankA.begin()) + { ESP_LOGE("DigitalInputCard", "Input Card ERROR: Failed to install input bank A"); return false; } - if (!this->inputBankB.begin()) { + if (!this->inputBankB.begin()) + { ESP_LOGE("DigitalInputCard", "Input Card ERROR: Failed to install input bank B"); return false; } @@ -82,7 +84,7 @@ bool DigitalInputCard::begin() /** * @brief Read the input from the specified pin, always refresh the input buffers - * + * * @param pin The pin to read from * @return True if the pin is HIGH, false if the pin is LOW */ @@ -93,7 +95,7 @@ bool DigitalInputCard::digitalRead(uint8_t pin) /** * @brief Read the input from the specified pin, also refresh the input buffers if refresh is true - * + * * @param pin The pin to read from * @param refresh If true, the input buffers will be refreshed before reading the pin * @return True if the pin is HIGH, false if the pin is LOW @@ -123,9 +125,9 @@ bool DigitalInputCard::digitalRead(uint8_t pin, bool refresh) /** * @brief Check if the specified pin changed since the last call to this function - * + * * @note This function compares the current input buffer with the previous input buffer to detect changes - * + * * @param pin The pin to check * @param currentBuffer The current input buffer * @param previousBuffer The previous input buffer @@ -134,44 +136,89 @@ void DigitalInputCard::handlePinChange(int pin, uint8_t ¤tBuffer, uint8_t { // Get the index of the pin in the pin map uint8_t virtualPin = virtualPinMap[pin]; - // Handle Bank A - if (((previousBuffer >> (7 - pin)) & 1) != ((currentBuffer >> (7 - pin)) & 1)) + if (pin < 8) { - if (!pinChanged[pin]) { - lastDebounceTime[pin] = millis(); - pinChanged[pin] = true; - } else { - if (millis() - lastDebounceTime[pin] > debounceTime[pin]) + // Handle Bank A + if (((previousBuffer >> (7 - pin)) & 1) != ((currentBuffer >> (7 - pin)) & 1)) + { + // When the pin first change, store the time + if (!pinChanged[virtualPin]) { - previousBuffer ^= (-((currentBuffer >> (7 - pin)) & 1) ^ previousBuffer) & (1UL << (7 - pin)); - for (const auto& callback : callbacks) - callback.second(virtualPin, ((currentBuffer >> (7 - pin)) & 1)); - pinChanged[pin] = false; + ESP_LOGD("DigitalInputCard", "Pin %d changed", virtualPin); + pinChanged[virtualPin] = true; + lastDebounceTime[virtualPin] = millis(); + } + else + { + ESP_LOGD("DigitalInputCard", "Pin %d (%d>%d) debounce time: %d", virtualPin, ((previousBuffer >> (7 - pin)) & 1), ((currentBuffer >> (7 - pin)) & 1), millis() - lastDebounceTime[virtualPin]); + // If the pin was already changed, check if the debounce time has passed + if ((millis() - lastDebounceTime[virtualPin]) > debounceTime[virtualPin]) + { + ESP_LOGD("DigitalInputCard", "Pin %d triggered", virtualPin); + // Call the callback function + for (auto const &callback : callbacks) + { + callback.second(virtualPin, ((currentBuffer >> (7 - pin)) & 1)); + } + // Store the previous buffer at the specified pin (bitwise operation) + // new value : (currentBuffer >> (7 - pin)) & 1) + previousBuffer = (previousBuffer & ~(1 << (7 - pin))) | (((currentBuffer >> (7 - pin)) & 1) << (7 - pin)); + // Reset the pin changed flag + pinChanged[virtualPin] = false; + } } } - } - // Handle Bank B - if (((previousBuffer >> (15 - pin)) & 1) != ((currentBuffer >> (15 - pin)) & 1)) - { - if (!pinChanged[pin]) { - lastDebounceTime[pin] = millis(); - pinChanged[pin] = true; - } else { - if (millis() - lastDebounceTime[pin] > debounceTime[pin]) - { - previousBuffer ^= (-((currentBuffer >> (15 - pin)) & 1) ^ previousBuffer) & (1UL << (15 - pin)); - for (const auto& callback : callbacks) - callback.second(virtualPin, ((currentBuffer >> (15 - pin)) & 1)); - pinChanged[pin] = false; - } + else + { + // Pin bounce back to previous state, reset the debounce time + lastDebounceTime[virtualPin] = millis(); + pinChanged[virtualPin] = false; + } + } + else + { + // Handle Bank B + if (((previousBuffer >> (15 - pin)) & 1) != ((currentBuffer >> (15 - pin)) & 1)) + { + // When the pin first change, store the time + if (!pinChanged[virtualPin]) + { + ESP_LOGD("DigitalInputCard", "Pin %d changed", virtualPin); + pinChanged[virtualPin] = true; + lastDebounceTime[virtualPin] = millis(); + } + else + { + ESP_LOGD("DigitalInputCard", "Pin %d (%d>%d) debounce time: %d", virtualPin, ((previousBuffer >> (15 - pin)) & 1), ((currentBuffer >> (15 - pin)) & 1), millis() - lastDebounceTime[virtualPin]); + // If the pin was already changed, check if the debounce time has passed + if ((millis() - lastDebounceTime[virtualPin]) > debounceTime[virtualPin]) + { + ESP_LOGD("DigitalInputCard", "Pin %d triggered", virtualPin); + // Call the callback function + for (auto const &callback : callbacks) + { + callback.second(virtualPin, ((currentBuffer >> (15 - pin)) & 1)); + } + // Store the previous buffer at the specified pin (bitwise operation) + // new value : (currentBuffer >> (15 - pin)) & 1) + previousBuffer = (previousBuffer & ~(1 << (15 - pin))) | (((currentBuffer >> (15 - pin)) & 1) << (15 - pin)); + // Reset the pin changed flag + pinChanged[virtualPin] = false; + } + } + } + else + { + // Pin bounce back to previous state, reset the debounce time + lastDebounceTime[virtualPin] = millis(); + pinChanged[virtualPin] = false; } } - } /** - * @brief A loop to refresh the input buffers and check for pin changes - * + * @brief A loop to refresh the input buffers and check for pin changes + * * @note Although this function can be called in the main loop, it is recommended install the card in ESPMega to automatically manage the loop */ // Preform a loop to refresh the input buffers @@ -197,7 +244,7 @@ void DigitalInputCard::loop() /** * @brief Get the input buffer for bank A (the first 8 pins) - * + * * @return The input buffer for bank A where the first bit is the first pin and the last bit is the last pin */ uint8_t DigitalInputCard::getInputBufferA() @@ -213,7 +260,7 @@ uint8_t DigitalInputCard::getInputBufferA() /** * @brief Get the input buffer for bank B (the last 8 pins) - * + * * @return The input buffer for bank B where the first bit is the first pin and the last bit is the last pin */ uint8_t DigitalInputCard::getInputBufferB() @@ -229,7 +276,7 @@ uint8_t DigitalInputCard::getInputBufferB() /** * @brief Register a callback function to be called when a pin changes - * + * * @param callback The callback function to be called * @return The handler of the callback function */ @@ -257,11 +304,11 @@ void DigitalInputCard::refreshInputBankB() /** * @brief Set the debounce time for the specified pin - * + * * Debounce is the time in milliseconds that the pin should be stable before the callback function is called * This is useful to prevent false triggers when the input is noisy * An example of this is when the input is connected to a mechanical switch - * + * * @param pin The pin to set the debounce time for * @param debounceTime The debounce time in milliseconds */ @@ -273,7 +320,7 @@ void DigitalInputCard::setDebounceTime(uint8_t pin, uint32_t debounceTime) /** * @brief Unregister a callback function - * + * * @param handler The handler of the callback function to unregister */ void DigitalInputCard::unregisterCallback(uint8_t handler) @@ -283,12 +330,12 @@ void DigitalInputCard::unregisterCallback(uint8_t handler) /** * @brief Load the pin map for the card - * + * * A pin map is an array of 16 elements that maps the physical pins to virtual pins * The virtual pins are the pins that are used in the callback functions and are used for all the functions in this class * The physical pins are the pins on the Input IC, This can be found on the schematic of the ESPMegaI/O board * This function is useful if you want to change the number identification of the pins to match your project needs - * + * * @param pinMap The pin map to load */ void DigitalInputCard::loadPinMap(uint8_t pinMap[16]) @@ -304,7 +351,7 @@ void DigitalInputCard::loadPinMap(uint8_t pinMap[16]) /** * @brief Get the type of the card - * + * * @return The type of the card */ uint8_t DigitalInputCard::getType() @@ -314,10 +361,11 @@ uint8_t DigitalInputCard::getType() /** * @brief Preload the previous input buffer and the input buffer - * + * * @note This function is useful if you want to preload the input buffers with a run-time value */ -void DigitalInputCard::preloadInputBuffer() { +void DigitalInputCard::preloadInputBuffer() +{ refreshInputBankA(); refreshInputBankB(); previousInputBufferA = inputBufferA; diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp index 655573d..de99223 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp @@ -1,3 +1,3 @@ #pragma once -#define SDK_VESRION "2.9.2" \ No newline at end of file +#define SDK_VESRION "2.9.3" \ No newline at end of file diff --git a/ESPMegaPRO-OS-SDK/src/main.cpp b/ESPMegaPRO-OS-SDK/src/main.cpp index d73714b..98fd31d 100644 --- a/ESPMegaPRO-OS-SDK/src/main.cpp +++ b/ESPMegaPRO-OS-SDK/src/main.cpp @@ -12,15 +12,17 @@ #include #include +#define INPUT_DEBOUNCE_TIME_MS 1000 + // #define FRAM_DEBUG // #define MQTT_DEBUG // #define RTC_DEBUG -#define WRITE_DEFAULT_NETCONF -#define CLIMATE_CARD_ENABLE -#define MQTT_CARD_REGISTER +//#define WRITE_DEFAULT_NETCONF +//#define CLIMATE_CARD_ENABLE +//#define MQTT_CARD_REGISTER // #define DISPLAY_ENABLE -#define WEB_SERVER_ENABLE -#define LCD_OTA_ENABLE +//#define WEB_SERVER_ENABLE +//#define LCD_OTA_ENABLE // #define REMOTE_VARIABLE_ENABLE // #define CT_ENABLE // #define SMART_VARIABLE_ENABLE @@ -116,6 +118,7 @@ void input_change_callback(uint8_t pin, uint8_t value) Serial.print(pin); Serial.print(" "); Serial.println(value); + espmega.outputs.toggleState(pin); } void mqtt_callback(char *topic, char *payload) @@ -187,6 +190,16 @@ void setup() ESP_LOGI("Initializer", "Connecting to MQTT"); espmega.iot->connectToMqtt(); espmega.iot->registerMqttCallback(mqtt_callback); + // Set debounce time + for (uint8_t i = 0; i < 16; i++) + { + espmega.inputs.setDebounceTime(i, INPUT_DEBOUNCE_TIME_MS); + } + // Set all pin values to 4095 + for (uint8_t i = 0; i < 16; i++) + { + espmega.outputs.setValue(i, 4095); + } #ifdef MQTT_CARD_REGISTER ESP_LOGI("Initializer", "Registering cards 0"); espmega.iot->registerCard(0); From c2e45490b020f6b357510d2b1a8afb2b3eedfb1d Mon Sep 17 00:00:00 2001 From: Siwat Sirichai Date: Fri, 28 Jun 2024 22:16:44 +0700 Subject: [PATCH 13/22] energy load error handling --- ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/CurrentTransformerCard.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/CurrentTransformerCard.cpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/CurrentTransformerCard.cpp index f5ce161..d9f230c 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/CurrentTransformerCard.cpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/CurrentTransformerCard.cpp @@ -84,6 +84,9 @@ void CurrentTransformerCard::saveEnergy(){ } void CurrentTransformerCard::loadEnergy(){ this->fram->read(this->framAddress, (uint8_t*)&this->energy, sizeof(this->energy)); + if (this->energy < 0 || isnan(this->energy)) { + this->energy = 0; + } } void CurrentTransformerCard::setEnergyAutoSave(bool autoSave){ From 520fd76b91dad93040b5df87b6819d23603e8ec6 Mon Sep 17 00:00:00 2001 From: Siwat Sirichai Date: Fri, 28 Jun 2024 22:17:13 +0700 Subject: [PATCH 14/22] Update ESPMegaCommon.hpp --- ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp index de99223..3988dbc 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp @@ -1,3 +1,3 @@ #pragma once -#define SDK_VESRION "2.9.3" \ No newline at end of file +#define SDK_VESRION "2.9.4" \ No newline at end of file From 8ea85254a05c0213cf88248d541d13833be2e33b Mon Sep 17 00:00:00 2001 From: Siwat Sirichai Date: Mon, 7 Oct 2024 15:08:12 +0700 Subject: [PATCH 15/22] add uptime feature --- .../lib/ESPMegaPRO/ESPMegaCommon.hpp | 2 +- .../lib/ESPMegaPRO/ESPMegaWebServer.cpp | 1 + .../lib/ESPMegaPRO/html/ota.html | 19 +- ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ota_html.h | 898 ++++++++++-------- 4 files changed, 503 insertions(+), 417 deletions(-) diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp index 3988dbc..59e98d2 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp @@ -1,3 +1,3 @@ #pragma once -#define SDK_VESRION "2.9.4" \ No newline at end of file +#define SDK_VESRION "2.9.5" \ No newline at end of file diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaWebServer.cpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaWebServer.cpp index d4791b7..00f6b31 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaWebServer.cpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaWebServer.cpp @@ -482,6 +482,7 @@ void ESPMegaWebServer::getDeviceInfoHandler(AsyncWebServerRequest *request) { doc["software_version"] = SW_VERSION; doc["sdk_version"] = SDK_VESRION; doc["idf_version"] = IDF_VER; + doc["uptime"] = esp_timer_get_time() / 1000000; // Uptime in seconds char buffer[512]; serializeJson(doc, buffer); request->send(200, "application/json", buffer); diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/html/ota.html b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/html/ota.html index 51fc30a..a9fc9da 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/html/ota.html +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/html/ota.html @@ -14,6 +14,10 @@ MAC Address Loading ...

+

+ Uptime + Loading ... +

Model Loading ... @@ -60,7 +64,7 @@ SIWAT SYSTEM 2023