From 8129c7bbfe55445aff395b9e24a3091b3e1b6bae Mon Sep 17 00:00:00 2001 From: Robin Dietzel Date: Thu, 12 Jan 2023 15:16:20 +0100 Subject: [PATCH] WIP: simple configuration storage and business logic --- Core/Inc/git_rev.h | 2 +- Core/Src/main.cpp | 197 ++++++++++++-------- Middlewares/floatpump/Inc/Config_Store.h | 21 ++- Middlewares/floatpump/Inc/PressureChannel.h | 1 + Middlewares/floatpump/Inc/RelayChannel.h | 2 + Middlewares/floatpump/Src/RelayChannel.cpp | 4 + 6 files changed, 149 insertions(+), 78 deletions(-) diff --git a/Core/Inc/git_rev.h b/Core/Inc/git_rev.h index 8dcdea0..851b2ec 100644 --- a/Core/Inc/git_rev.h +++ b/Core/Inc/git_rev.h @@ -7,6 +7,6 @@ // Auto generated header file containing the last git revision -#define GIT_HASH "59fdd3a" +#define GIT_HASH "a982c79" #endif //FLOATPUMP_GIT_REVISION_TEMPLATE_H \ No newline at end of file diff --git a/Core/Src/main.cpp b/Core/Src/main.cpp index b0b6821..06dc7f8 100644 --- a/Core/Src/main.cpp +++ b/Core/Src/main.cpp @@ -47,6 +47,36 @@ extern bool rot_button; using namespace floatpump; +void CheckTankConditions(Config_Store &cfg, io::PressureChannel &tankLevel, io::RelayChannel &tankPump) { + //Check if config says relay works inverted + tankPump.setInverted(cfg.TankPumpInvert.getValue()); + + //First check if Tank has enough water and disable pump if necessary + if(tankLevel.getPercent() < cfg.TankMinLevel.getValue()) { + tankPump.switchRelay(io::RelayChannel::state::OFF); + } else if(tankLevel.getPercent() > cfg.TankMinLevel.getValue() + cfg.TankHysteresis.getValue()) { + tankPump.switchRelay(io::RelayChannel::state::ON); + } +} + +void CheckRefillConditions(Config_Store &cfg, io::PressureChannel &tankLevel, io::GPIChannel &refillBlock, io::RelayChannel &refillPump) { + if(cfg.RefillEnable.getValue()) { + //Check whether refilling is necessary + if(tankLevel.getPercent() < cfg.RefillBelow.getValue()) { + if(cfg.RefillBlockEnable.getValue() && !refillBlock.getStateBool()) { + refillPump.switchRelay(io::RelayChannel::state::ON); + } else { + refillPump.switchRelay(io::RelayChannel::state::ON); + } + } else if (tankLevel.getPercent() > cfg.RefillBelow.getValue() + cfg.RefillHysteresis.getValue()) { + refillPump.switchRelay(io::RelayChannel::state::OFF); + } + } else { + refillPump.switchRelay(io::RelayChannel::state::OFF); + } +} + + int main(void) { Config_Store globalConfig; @@ -98,7 +128,7 @@ int main(void) { t_exCalibLow.linkConfig(&a_caliblow); t_exCalibHigh.linkConfig(&a_calibhigh); menu::Menu_Entry exCalibLow(t_exCalibLow, "Kal. Unt. Punkt"); - menu::Menu_Entry exCalibHigh(t_exCalibHigh, "Kal. Unt. Punkt"); + menu::Menu_Entry exCalibHigh(t_exCalibHigh, "Kal. Ob. Punkt"); menu::Menu_Entry_Type_Numeric t_CalibLow(0); menu::Menu_Entry_Type_Numeric t_CalibHigh(65535); @@ -162,91 +192,108 @@ int main(void) { menu::Menu_Controller controller(&mainmenu, display); static int old_pos = 0; + //Instantiate Input and Output modules + io::PressureChannel tankLevel0(&hadc1, MPWR0_GPIO_Port, MPWR0_Pin, 50); + io::GPIChannel refillBlocker0(GPI0_GPIO_Port, GPI0_Pin); + io::RelayChannel tankPump(OCHAN0_GPIO_Port, OCHAN0_Pin, true, io::RelayChannel::state::OFF); + io::RelayChannel refillPump(OCHAN1_GPIO_Port, OCHAN1_Pin, false, io::RelayChannel::state::OFF); + + uint32_t last_menu_retrigger = 0; + + bool f_store, f_restore = false; + menu::Menu_Entry_Type_Execute t_MStore; + menu::Menu_Entry_Type_Execute t_MRestore; + t_MStore.linkConfig(&f_store); + t_MRestore.linkConfig(&f_restore); + menu::Menu_Entry MStore(t_MStore, "Speichern"); + menu::Menu_Entry MRestore(t_MRestore, "Laden"); + + + mainmenu.addEntry(MStore); + mainmenu.addEntry(MRestore); + while (1) { - //render menu - controller.execute(); - if (rot_button) { + display.LCDSetCursor(0,0); + display.LCDSendCString(const_cast(std::string("Tank: " + std::to_string(tankLevel0.getPercent()) + " %").c_str())); + + display.LCDSetCursor(0, 1); + if(tankLevel0.getPercent() < globalConfig.TankMinLevel.getValue()) { + display.LCDSendCString(const_cast(std::string("Tank Wassermangel").c_str())); + } else { + display.LCDSendCString(const_cast(std::string("Tank Normal").c_str())); + } + + + + if(rot_button) { rot_button = false; - controller.pushEvent(menu::Menu_Controller::Event::Push); + last_menu_retrigger = HAL_GetTick(); + while(true) { + //Display menu until timeout + controller.execute(); + if (rot_button) { + rot_button = false; + controller.pushEvent(menu::Menu_Controller::Event::Push); + last_menu_retrigger = HAL_GetTick(); + } + + if (old_pos < rot_counter) { + controller.pushEvent(menu::Menu_Controller::Event::Increase); + old_pos = rot_counter; + last_menu_retrigger = HAL_GetTick(); + } else if (old_pos > rot_counter) { + controller.pushEvent(menu::Menu_Controller::Event::Decrease); + old_pos = rot_counter; + last_menu_retrigger = HAL_GetTick(); + } + HAL_Delay(100); + + //Execute Calibrations if necessary + if(a_caliblow) { + tankLevel0.calibrateLow(); + controller.execute(); + HAL_Delay(2000); + a_caliblow = false; + } else if (a_calibhigh) { + tankLevel0.calibrateHigh(); + controller.execute(); + HAL_Delay(2000); + a_calibhigh = false; + } + + //Store or restore if necessary + if(f_store) { + globalConfig.saveToFlash(); + f_store = false; + } else if (f_restore) { + globalConfig.loadFromFlash(); + f_restore = false; + } + + if(HAL_GetTick() > last_menu_retrigger + 10000) { + display.LCDClearDisplay(); + break; + } + } } - if (old_pos < rot_counter) { - controller.pushEvent(menu::Menu_Controller::Event::Increase); - old_pos = rot_counter; - } else if (old_pos > rot_counter) { - controller.pushEvent(menu::Menu_Controller::Event::Decrease); - old_pos = rot_counter; - } - HAL_Delay(100); + //Poll Sensors + tankLevel0.poll(); + refillBlocker0.poll(); + + //Check conditions + CheckTankConditions(globalConfig, tankLevel0, tankPump); + CheckRefillConditions(globalConfig, tankLevel0, refillBlocker0, refillPump); + HAL_Delay(1000); } -// Menu_Controller controller(&mainmenu, display); -// -// floatpump::io::PressureChannel channel(&hadc1, MPWR0_GPIO_Port, MPWR0_Pin); -// floatpump::io::RelayChannel relay(OCHAN0_GPIO_Port, OCHAN0_Pin, false); -// floatpump::io::GPIChannel swimmer(GPI0_GPIO_Port, GPI0_Pin, false); -// -// -// -// relay.setCooldown(10000); -// -// static int old_pos = 0; -// while (1) { -// -// //render menu -// controller.execute(); -// if (rot_button) { -// rot_button = false; -// controller.pushEvent(Menu_Controller::Event::Push); -// } -// -// if (old_pos < rot_counter) { -// controller.pushEvent(Menu_Controller::Event::Increase); -// old_pos = rot_counter; -// } else if (old_pos > rot_counter) { -// controller.pushEvent(Menu_Controller::Event::Decrease); -// old_pos = rot_counter; -// } -// HAL_Delay(100); -// -// -// if(l_calib) { -// relay.switchRelay(floatpump::io::RelayChannel::state::ON); -// } -// //channel.calibrateLow(); -// -// if(h_calib) { -// relay.switchRelay(floatpump::io::RelayChannel::state::OFF); -// } -// //channel.calibrateHigh(); -// -// l_calib = false; -// h_calib = false; -// -// curCooldown = relay.getRemainingCooldown(); -// -// prescaler++; -// -// -// swimmer.poll(); -// if(prescaler % 100 == 0) -// channel.poll(); -// -// current = channel.getRaw(); -// cur_perc = channel.getPercent(); -// inputTest = swimmer.getStateBool(); -// -// /*if(cur_perc > 50) { -// relay.switchRelay(floatpump::io::RelayChannel::state::ON); -// } else if(cur_perc < 45) { -// relay.switchRelay(floatpump::io::RelayChannel::state::OFF); -// }*/ -// } + } + void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; diff --git a/Middlewares/floatpump/Inc/Config_Store.h b/Middlewares/floatpump/Inc/Config_Store.h index a820974..1cdd618 100644 --- a/Middlewares/floatpump/Inc/Config_Store.h +++ b/Middlewares/floatpump/Inc/Config_Store.h @@ -6,6 +6,7 @@ #define FLOATPUMP_CONFIG_STORE_H #include +#include "stm32f4xx_hal.h" namespace floatpump { @@ -13,11 +14,27 @@ namespace floatpump { public: Config_Store(); - void saveToFlash(); + static uint32_t Flash_Write (uint32_t StartPageAddress, uint32_t Data, uint16_t n_words) { + static FLASH_EraseInitTypeDef EraseInitStruct; + uint32_t PAGEError; + int sofar=0; + + HAL_FLASH_Unlock(); + FLASH_Erase_Sector(FLASH_SECTOR_7, VOLTAGE_RANGE_1); + HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, StartPageAddress, Data); + HAL_FLASH_Lock(); + return 0; + } + + void saveToFlash() { + Flash_Write(0x08060000, this->RefillBelow.getValue(), 0); + }; void resetDefaults(); - void loadFromFlash(); + void loadFromFlash() { + this->RefillBelow.setValue(*(uint32_t *)0x08060000); + }; template class Config_Object { diff --git a/Middlewares/floatpump/Inc/PressureChannel.h b/Middlewares/floatpump/Inc/PressureChannel.h index 91cac40..0e2c58a 100644 --- a/Middlewares/floatpump/Inc/PressureChannel.h +++ b/Middlewares/floatpump/Inc/PressureChannel.h @@ -6,6 +6,7 @@ #define FLOATPUMP_PRESSURECHANNEL_H #include +#include #include "stm32f4xx_hal.h" namespace floatpump::io { diff --git a/Middlewares/floatpump/Inc/RelayChannel.h b/Middlewares/floatpump/Inc/RelayChannel.h index d6fa5d2..f97e752 100644 --- a/Middlewares/floatpump/Inc/RelayChannel.h +++ b/Middlewares/floatpump/Inc/RelayChannel.h @@ -20,6 +20,8 @@ namespace floatpump::io { void switchRelay(state st); + void setInverted(bool inv); + void setCooldown(uint16_t ms); [[nodiscard]] uint16_t getRemainingCooldown() const; diff --git a/Middlewares/floatpump/Src/RelayChannel.cpp b/Middlewares/floatpump/Src/RelayChannel.cpp index dd12888..bcfbb32 100644 --- a/Middlewares/floatpump/Src/RelayChannel.cpp +++ b/Middlewares/floatpump/Src/RelayChannel.cpp @@ -39,5 +39,9 @@ namespace floatpump { else return 0; } + + void RelayChannel::setInverted(bool inv) { + m_inverted = inv; + } } // floatpump } // io \ No newline at end of file