From 091dc183feda2634dab9f44acad6ee5333740a0f Mon Sep 17 00:00:00 2001 From: Siwat Sirichai Date: Sun, 31 Dec 2023 02:18:57 +0700 Subject: [PATCH] debug_fram --- .../lib/ESPMegaPRO/ClimateCard.cpp | 56 +++++++++++++------ .../lib/ESPMegaPRO/ESPMegaIoT.cpp | 48 +++++++++++++--- .../lib/ESPMegaPRO/ESPMegaIoT.hpp | 7 +++ .../lib/ESPMegaPRO/ESPMegaPRO_OOP.cpp | 6 ++ .../lib/ESPMegaPRO/InternalDisplay.cpp | 47 ++++++++-------- .../lib/ESPMegaPRO/InternalDisplay.hpp | 1 + ESPMegaPRO-firmware/src/main.cpp | 9 ++- 7 files changed, 126 insertions(+), 48 deletions(-) diff --git a/ESPMegaPRO-firmware/lib/ESPMegaPRO/ClimateCard.cpp b/ESPMegaPRO-firmware/lib/ESPMegaPRO/ClimateCard.cpp index 650a1bb..6172ec9 100644 --- a/ESPMegaPRO-firmware/lib/ESPMegaPRO/ClimateCard.cpp +++ b/ESPMegaPRO-firmware/lib/ESPMegaPRO/ClimateCard.cpp @@ -86,24 +86,37 @@ void ClimateCard::setFRAMAutoSave(bool autoSave) void ClimateCard::saveStateToFRAM() { - fram->writeObject(fram_address, this->state); + // fram->write8(fram_address, state.ac_temperature); + // fram->write8(fram_address + 1, state.ac_mode); + // fram->write8(fram_address + 2, state.ac_fan_speed); + fram->writeObject(fram_address, state); + Serial.println("Saved state to FRAM"); + Serial.write(0xFF); + Serial.write(0xFF); + Serial.write(0xFF); } void ClimateCard::loadStateFromFRAM() { - fram->readObject(fram_address, this->state); - // If temperature is out of range, set to its respective maximum or minimum - if (state.ac_temperature > ac.max_temperature) - state.ac_temperature = ac.max_temperature; - else if (state.ac_temperature < ac.min_temperature) - state.ac_temperature = ac.min_temperature; - // If mode is out of range, set to 0 - if (state.ac_mode > ac.modes) - state.ac_mode = 0; - // If fan speed is out of range, set to 0 - if (state.ac_fan_speed > ac.fan_speeds) - state.ac_fan_speed = 0; + // state.ac_temperature = fram->read8(fram_address); + // state.ac_mode = fram->read8(fram_address + 1); + // state.ac_fan_speed = fram->read8(fram_address + 2); + fram->readObject(fram_address, state); + // if (state.ac_temperature > ac.max_temperature) + // state.ac_temperature = ac.max_temperature; + // else if (state.ac_temperature < ac.min_temperature) + // state.ac_temperature = ac.min_temperature; + // // If mode is out of range, set to 0 + // if (state.ac_mode > ac.modes) + // state.ac_mode = 0; + // // If fan speed is out of range, set to 0 + // if (state.ac_fan_speed > ac.fan_speeds) + // state.ac_fan_speed = 0; updateAirConditioner(); + for (uint8_t i = 0; i < callbacks.size(); i++) + { + callbacks[i](this->state.ac_mode, this->state.ac_fan_speed, this->state.ac_temperature); + } } void ClimateCard::setTemperature(uint8_t temperature) @@ -137,6 +150,10 @@ void ClimateCard::setFanSpeed(uint8_t fan_speed) void ClimateCard::registerChangeCallback(std::function callback) { + Serial.print("Registering callback"); + Serial.write(0xFF); + Serial.write(0xFF); + Serial.write(0xFF); callbacks.push_back(callback); } @@ -199,10 +216,15 @@ void ClimateCard::updateAirConditioner() // rmt_write_items(RMT_TX_CHANNEL, items, itemCount, true); // rmt_wait_tx_done(RMT_TX_CHANNEL, portMAX_DELAY); // // Publish state - // for (uint8_t i = 0; i < callbacks.size(); i++) - // { - // callbacks[i](this->state.ac_mode, this->state.ac_fan_speed, this->state.ac_temperature); - // } + Serial.print("Callbacks: "); + Serial.println(callbacks.size()); + Serial.write(0xFF); + Serial.write(0xFF); + Serial.write(0xFF); + for (uint8_t i = 0; i < callbacks.size(); i++) + { + callbacks[i](this->state.ac_mode, this->state.ac_fan_speed, this->state.ac_temperature); + } } uint8_t ClimateCard::getSensorType() diff --git a/ESPMegaPRO-firmware/lib/ESPMegaPRO/ESPMegaIoT.cpp b/ESPMegaPRO-firmware/lib/ESPMegaPRO/ESPMegaIoT.cpp index 14d9e07..e4aee12 100644 --- a/ESPMegaPRO-firmware/lib/ESPMegaPRO/ESPMegaIoT.cpp +++ b/ESPMegaPRO-firmware/lib/ESPMegaPRO/ESPMegaIoT.cpp @@ -1,7 +1,5 @@ #include #include -#define NETWORK_CONFIG_ADDRESS 34 -#define MQTT_CONFIG_ADDRESS 34 + sizeof(NetworkConfig) ESPMegaIoT::ESPMegaIoT() : mqtt(tcpClient) { @@ -316,13 +314,34 @@ void ESPMegaIoT::setNetworkConfig(NetworkConfig network_config) void ESPMegaIoT::loadNetworkConfig() { // Load the network config from FRAM - fram->read(0, (uint8_t *)&network_config, sizeof(NetworkConfig)); + network_config.ip = fram->read32(FRAM_ADDRESS); + network_config.gateway = fram->read32(FRAM_ADDRESS + 4); + network_config.subnet = fram->read32(FRAM_ADDRESS + 8); + network_config.dns1 = fram->read32(FRAM_ADDRESS + 12); + network_config.dns2 = fram->read32(FRAM_ADDRESS + 16); + fram->read(FRAM_ADDRESS + 20, (uint8_t*)network_config.hostname, 32); + network_config.useStaticIp = fram->read8(FRAM_ADDRESS + 52); + network_config.useWifi = fram->read8(FRAM_ADDRESS + 53); + network_config.wifiUseAuth = fram->read8(FRAM_ADDRESS + 54); + fram->read(FRAM_ADDRESS + 55, (uint8_t*)network_config.ssid, 32); + fram->read(FRAM_ADDRESS + 87, (uint8_t*)network_config.password, 32); } void ESPMegaIoT::saveNetworkConfig() { // Save the network config to FRAM - fram->write(NETWORK_CONFIG_ADDRESS, (uint8_t *)&network_config, sizeof(NetworkConfig)); + fram->write32(FRAM_ADDRESS, network_config.ip); + fram->write32(FRAM_ADDRESS + 4, network_config.gateway); + fram->write32(FRAM_ADDRESS + 8, network_config.subnet); + fram->write32(FRAM_ADDRESS + 12, network_config.dns1); + fram->write32(FRAM_ADDRESS + 16, network_config.dns2); + fram->write(FRAM_ADDRESS + 20, (uint8_t*)network_config.hostname, 32); + fram->write8(FRAM_ADDRESS + 52, network_config.useStaticIp); + fram->write8(FRAM_ADDRESS + 53, network_config.useWifi); + fram->write8(FRAM_ADDRESS + 54, network_config.wifiUseAuth); + fram->write(FRAM_ADDRESS + 55, (uint8_t*)network_config.ssid, 32); + fram->write(FRAM_ADDRESS + 87, (uint8_t*)network_config.password, 32); + } void ESPMegaIoT::ethernetBegin() @@ -333,13 +352,23 @@ void ESPMegaIoT::ethernetBegin() void ESPMegaIoT::loadMqttConfig() { // Load the mqtt config from FRAM - fram->read(sizeof(NetworkConfig), (uint8_t *)&this->mqtt_config, sizeof(MqttConfig)); - // Populate the mqtt connection parameters + // We skip bytes 119-127 because they are reserved for the network config + mqtt_config.mqtt_port = fram->read16(FRAM_ADDRESS + 128); + fram->read(FRAM_ADDRESS + 130, (uint8_t*)mqtt_config.mqtt_server, 32); + fram->read(FRAM_ADDRESS + 162, (uint8_t*)mqtt_config.mqtt_user, 32); + fram->read(FRAM_ADDRESS + 194, (uint8_t*)mqtt_config.mqtt_password, 32); + mqtt_config.mqtt_useauth = fram->read8(FRAM_ADDRESS + 226); + fram->read(FRAM_ADDRESS + 227, (uint8_t*)mqtt_config.base_topic, 32); } void ESPMegaIoT::saveMqttConfig() { - fram->write(MQTT_CONFIG_ADDRESS, (uint8_t *)&mqtt_config, sizeof(MqttConfig)); + fram->write16(FRAM_ADDRESS + 128, mqtt_config.mqtt_port); + fram->write(FRAM_ADDRESS + 130, (uint8_t*)mqtt_config.mqtt_server, 32); + fram->write(FRAM_ADDRESS + 162, (uint8_t*)mqtt_config.mqtt_user, 32); + fram->write(FRAM_ADDRESS + 194, (uint8_t*)mqtt_config.mqtt_password, 32); + fram->write8(FRAM_ADDRESS + 226, mqtt_config.mqtt_useauth); + fram->write(FRAM_ADDRESS + 227, (uint8_t*)mqtt_config.base_topic, 32); } void ESPMegaIoT::connectToMqtt() @@ -407,4 +436,9 @@ bool ESPMegaIoT::networkConnected() return WiFi.status() == WL_CONNECTED; else return ethernetIface->linkUp(); +} + +void ESPMegaIoT::bindFRAM(FRAM *fram) +{ + this->fram = fram; } \ No newline at end of file diff --git a/ESPMegaPRO-firmware/lib/ESPMegaPRO/ESPMegaIoT.hpp b/ESPMegaPRO-firmware/lib/ESPMegaPRO/ESPMegaIoT.hpp index b6902b4..b0d8034 100644 --- a/ESPMegaPRO-firmware/lib/ESPMegaPRO/ESPMegaIoT.hpp +++ b/ESPMegaPRO-firmware/lib/ESPMegaPRO/ESPMegaIoT.hpp @@ -14,6 +14,12 @@ #include #include +// FRAM Address for ESPMegaPROIoT +// Starts from 34 +// Ends at 300 (inclusive) +// Total of 267 bytes +#define FRAM_ADDRESS 34 + struct NetworkConfig { IPAddress ip; @@ -81,6 +87,7 @@ public: void setBaseTopic(char *base_topic); void bindEthernetInterface(ETHClass *ethernetIface); bool networkConnected(); + void bindFRAM(FRAM *fram); IoTComponent* getComponent(uint8_t card_id); IPAddress getETHIp(); diff --git a/ESPMegaPRO-firmware/lib/ESPMegaPRO/ESPMegaPRO_OOP.cpp b/ESPMegaPRO-firmware/lib/ESPMegaPRO/ESPMegaPRO_OOP.cpp index b11830f..aed2c04 100644 --- a/ESPMegaPRO-firmware/lib/ESPMegaPRO/ESPMegaPRO_OOP.cpp +++ b/ESPMegaPRO-firmware/lib/ESPMegaPRO/ESPMegaPRO_OOP.cpp @@ -1,4 +1,9 @@ #include + +// Reserve FRAM address 0 - 1000 for ESPMegaPRO Internal Use +// (34 Bytes) Address 0-33 for Built-in Digital Output Card +// () Address 34-300 for ESPMegaPRO IoT Module + ESPMegaPRO::ESPMegaPRO() { } @@ -95,6 +100,7 @@ void ESPMegaPRO::setTime(int hours, int minutes, int seconds, int day, int month void ESPMegaPRO::enableIotModule() { if (iotEnabled) return; this->iot = new ESPMegaIoT(); + this->iot->bindFRAM(&fram); this->iot->intr_begin(cards); iotEnabled = true; } diff --git a/ESPMegaPRO-firmware/lib/ESPMegaPRO/InternalDisplay.cpp b/ESPMegaPRO-firmware/lib/ESPMegaPRO/InternalDisplay.cpp index d0c4cbc..faf3e11 100644 --- a/ESPMegaPRO-firmware/lib/ESPMegaPRO/InternalDisplay.cpp +++ b/ESPMegaPRO-firmware/lib/ESPMegaPRO/InternalDisplay.cpp @@ -2,39 +2,26 @@ void InternalDisplay::begin(ESPMegaIoT *iot, std::function getRtcTime) { - ESP_LOGD("InternalDisplay", "Assigning IoT Module and RTC Time Getter"); this->iot = iot; this->getRtcTime = getRtcTime; - ESP_LOGD("InternalDisplay", "Acquiring Network and MQTT Configs"); this->mqttConfig = this->iot->getMqttConfig(); this->networkConfig = this->iot->getNetworkConfig(); // Register callbacks - ESP_LOGD("InternalDisplay", "Registering Callbacks"); auto bindedPageChangeCallback = std::bind(&InternalDisplay::handlePageChange, this, std::placeholders::_1); this->registerPageChangeCallback(bindedPageChangeCallback); auto bindedTouchCallback = std::bind(&InternalDisplay::handleTouch, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); this->registerTouchCallback(bindedTouchCallback); - ESP_LOGD("InternalDisplay", "Binding Page Change Callback"); auto bindedInputStateChangeCallback = std::bind(&InternalDisplay::handleInputStateChange, this, std::placeholders::_1, std::placeholders::_2); - ESP_LOGD("InternalDisplay", "Binding Input State Change Callback"); auto bindedPwmStateChangeCallback = std::bind(&InternalDisplay::handlePwmStateChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); - ESP_LOGD("InternalDisplay", "Registering inputCard Callbacks"); this->inputCard->registerCallback(bindedInputStateChangeCallback); - ESP_LOGD("InternalDisplay", "Registering outputCard Callbacks"); this->outputCard->registerChangeCallback(bindedPwmStateChangeCallback); // Initialize the display - ESP_LOGD("InternalDisplay", "Initializing DisplayAdapter"); this->displayAdapter->begin(115200); - ESP_LOGD("InternalDisplay", "Setting DisplayAdapter Timeout"); this->displayAdapter->setTimeout(100); - ESP_LOGD("InternalDisplay", "Flushing DisplayAdapter"); this->displayAdapter->flush(); - ESP_LOGD("InternalDisplay", "Resetting Display"); this->reset(); delay(500); - ESP_LOGD("InternalDisplay", "Jumping to Page 1"); this->jumpToPage(1); - ESP_LOGD("InternalDisplay", "Display Initialization Complete"); } @@ -99,12 +86,7 @@ void InternalDisplay::updateStatusIcons(bool networkStatus, bool mqttStatus) { void InternalDisplay::updateClock() { rtctime_t time = this->getRtcTime(); - this->displayAdapter->print("time.txt="); - this->displayAdapter->print(time.hours%12); - this->displayAdapter->print(":"); - this->displayAdapter->print(time.minutes); - this->displayAdapter->print(" "); - this->displayAdapter->print(time.hours/12 ? "PM" : "AM"); + this->displayAdapter->printf("time.txt=\"%02d:%02d %s\"", time.hours%12, time.minutes, time.hours/12 ? "PM" : "AM"); this->sendStopBytes(); } @@ -134,6 +116,12 @@ void InternalDisplay::refreshPage(uint8_t page) { case INTERNAL_DISPLAY_PWM_ADJUSTMENT_PAGE: this->refreshPWMAdjustment(); break; + case INTERNAL_DISPLAY_NETWORK_CONFIG_PAGE: + this->refreshNetworkConfig(); + break; + case INTERNAL_DISPLAY_MQTT_CONFIG_PAGE: + this->refreshMQTTConfig(); + break; default: break; } @@ -269,6 +257,8 @@ void InternalDisplay::bindOutputCard(DigitalOutputCard *outputCard) { // fan_speed: [auto, low, medium, high] void InternalDisplay::bindClimateCard(ClimateCard *climateCard) { this->climateCard = climateCard; + auto bindedACStateChangeCallback = std::bind(&InternalDisplay::handleACStateChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); + this->climateCard->registerChangeCallback(bindedACStateChangeCallback); } void InternalDisplay::refreshPWMAdjustment() { @@ -379,8 +369,6 @@ void InternalDisplay::handleACTouch(uint8_t type, uint8_t component) { default: break; } - // Refresh the AC page - this->refreshAC(); } void InternalDisplay::handlePWMAdjustmentTouch(uint8_t type, uint8_t component) { @@ -468,9 +456,8 @@ void InternalDisplay::refreshMQTTConfig() { this->displayAdapter->print("\""); this->sendStopBytes(); // Refresh the mqtt port - this->displayAdapter->print("port_set.txt=\""); + this->displayAdapter->print("port_set.val="); this->displayAdapter->print(this->mqttConfig->mqtt_port); - this->displayAdapter->print("\""); this->sendStopBytes(); // Refresh the mqtt username this->displayAdapter->print("user_set.txt=\""); @@ -487,6 +474,10 @@ void InternalDisplay::refreshMQTTConfig() { this->displayAdapter->print(this->mqttConfig->base_topic); this->displayAdapter->print("\""); this->sendStopBytes(); + // Refresh the mqtt use auth + this->displayAdapter->print("use_auth.val="); + this->displayAdapter->print(this->mqttConfig->mqtt_useauth ? 1 : 0); + this->sendStopBytes(); } void InternalDisplay::sendIpToDisplay(IPAddress ip) { @@ -498,4 +489,14 @@ void InternalDisplay::sendIpToDisplay(IPAddress ip) { this->displayAdapter->print(ip[2]); this->displayAdapter->print("."); this->displayAdapter->print(ip[3]); +} + +void InternalDisplay::handleACStateChange(uint8_t mode, uint8_t fan_speed, uint8_t temperature) { + // If the climate card is binded to the display and the current page is the AC page + // then update the respective AC component + Serial.println("AC state changed"); + if (this->climateCard==nullptr || this->currentPage != INTERNAL_DISPLAY_AC_PAGE) return; + this->sendStopBytes(); + // Update the AC state + this->refreshAC(); } \ No newline at end of file diff --git a/ESPMegaPRO-firmware/lib/ESPMegaPRO/InternalDisplay.hpp b/ESPMegaPRO-firmware/lib/ESPMegaPRO/InternalDisplay.hpp index 559e11c..8b3b09d 100644 --- a/ESPMegaPRO-firmware/lib/ESPMegaPRO/InternalDisplay.hpp +++ b/ESPMegaPRO-firmware/lib/ESPMegaPRO/InternalDisplay.hpp @@ -84,6 +84,7 @@ class InternalDisplay : public ESPMegaDisplay { void setOutputBar(uint8_t pin, uint16_t value); void setOutputStateColor(uint8_t pin, bool state); void setInputMarker(uint8_t pin, bool state); + void handleACStateChange(uint8_t mode, uint8_t fan_speed, uint8_t temperature); void saveNetworkConfig(); void saveMQTTConfig(); void updateStatusIcons(bool networkStatus, bool mqttStatus); diff --git a/ESPMegaPRO-firmware/src/main.cpp b/ESPMegaPRO-firmware/src/main.cpp index 1dd0e57..226200c 100644 --- a/ESPMegaPRO-firmware/src/main.cpp +++ b/ESPMegaPRO-firmware/src/main.cpp @@ -68,6 +68,7 @@ void setup() { Serial.println("Setting network config"); espmega.iot->setNetworkConfig(config); espmega.iot->saveNetworkConfig(); + // espmega.iot->loadNetworkConfig(); Serial.println("Connecting to network"); espmega.iot->connectNetwork(); Serial.println("Begin MQTT Modules"); @@ -81,6 +82,7 @@ void setup() { Serial.println("Loading MQTT Config Struct to IoT Module"); espmega.iot->setMqttConfig(mqtt_config); espmega.iot->saveMqttConfig(); + // espmega.iot->loadMqttConfig(); Serial.println("Connecting to MQTT"); espmega.iot->connectToMqtt(); Serial.println("Registering Output Card"); @@ -91,13 +93,18 @@ void setup() { espmega.inputs.registerCallback(input_change_callback); Serial.println("Installing Climate Card"); espmega.installCard(2, &climateCard); - climateCard.bindFRAM(&espmega.fram, 2000); + climateCard.bindFRAM(&espmega.fram, 301); climateCard.loadStateFromFRAM(); climateCard.setFRAMAutoSave(true); Serial.println("Enabling Internal Display"); espmega.enableInternalDisplay(&Serial); espmega.display->bindClimateCard(&climateCard); Serial.println("Initialization Routine Complete"); + Serial.write(0xFF); + Serial.write(0xFF); + Serial.write(0xFF); + Serial.println(sizeof(MqttConfig)); + Serial.println(sizeof(NetworkConfig)); } void loop() {