From 7d39b7bafb16586f92d4cfa3a3cf2a8331d45e2c Mon Sep 17 00:00:00 2001 From: Fabian Sperrle Date: Sat, 20 Jan 2024 21:24:15 +0100 Subject: [PATCH 1/3] Start dimmer experiments --- src/brewvoid.h | 55 ++++++++++++++++++++++++++++++++++++-------------- src/dimmer.h | 50 +++++++++++++++++++++++++++++++++++++++++++++ src/main.cpp | 4 ++++ 3 files changed, 94 insertions(+), 15 deletions(-) create mode 100644 src/dimmer.h diff --git a/src/brewvoid.h b/src/brewvoid.h index 94abd801..9390377c 100644 --- a/src/brewvoid.h +++ b/src/brewvoid.h @@ -67,6 +67,24 @@ boolean brewPIDDisabled = false; // is PID disabled for delay #endif #endif +#include "dimmer.h" + +void pumpOn(int power = 100) { + #if DIMMER == 0 + digitalWrite(PIN_PUMP, relayOn); + #else + setPower(power); + #endif +} + +void pumpOff() { + #if DIMMER == 0 + digitalWrite(PIN_PUMP, relayOff); + #else + setPower(0); + #endif +} + /** * @brief Switch or trigger input for BREW SWITCH */ @@ -118,7 +136,7 @@ void checkbrewswitch() { debugPrintln("brewSwitchTriggerCase 20: Manual Trigger - flushing"); brewSwitchTriggerCase = 31; digitalWrite(PIN_VALVE, relayOn); - digitalWrite(PIN_PUMP, relayOn); + pumpOn(); } break; @@ -137,7 +155,7 @@ void checkbrewswitch() { brewSwitchTriggerCase = 40; debugPrintln("brewswitchTriggerCase 31: Manual Trigger - brewing stop"); digitalWrite(PIN_VALVE, relayOff); - digitalWrite(PIN_PUMP, relayOff); + pumpOff(); } break; @@ -193,7 +211,7 @@ void backflush() { case kBackflushFillingStart: debugPrintln("Backflush: Portafilter filling..."); digitalWrite(PIN_VALVE, relayOn); - digitalWrite(PIN_PUMP, relayOn); + pumpOn(); backflushState = kBackflushFilling; break; @@ -209,7 +227,7 @@ void backflush() { case kBackflushFlushingStart: debugPrintln("Backflush: Flushing to drip tray..."); digitalWrite(PIN_VALVE, relayOff); - digitalWrite(PIN_PUMP, relayOff); + pumpOff(); flushCycles++; backflushState = kBackflushFlushing; @@ -230,7 +248,7 @@ void backflush() { if (brewSwitch == LOW) { debugPrintln("Backflush: Finished!"); digitalWrite(PIN_VALVE, relayOff); - digitalWrite(PIN_PUMP, relayOff); + pumpOff(); flushCycles = 0; backflushState = kBackflushWaitBrewswitchOn; } @@ -271,6 +289,7 @@ void brew() { case kBrewIdle: // waiting step for brew switch turning on if (brewSwitch == HIGH && backflushState == 10 && backflushOn == 0 && brewSwitchWasOff) { startingTime = millis(); + resetDimmerCounter(); if (preinfusionPause == 0 || preinfusion == 0) { brewCounter = kBrewRunning; @@ -288,7 +307,7 @@ void brew() { case kPreinfusion: // preinfusioon debugPrintln("Preinfusion"); digitalWrite(PIN_VALVE, relayOn); - digitalWrite(PIN_PUMP, relayOn); + pumpOn(10); brewCounter = kWaitPreinfusion; break; @@ -303,7 +322,7 @@ void brew() { case kPreinfusionPause: // preinfusion pause debugPrintln("Preinfusion pause"); digitalWrite(PIN_VALVE, relayOn); - digitalWrite(PIN_PUMP, relayOff); + pumpOff(); brewCounter = kWaitPreinfusionPause; break; @@ -318,7 +337,7 @@ void brew() { case kBrewRunning: // brew running debugPrintln("Brew started"); digitalWrite(PIN_VALVE, relayOn); - digitalWrite(PIN_PUMP, relayOn); + pumpOn(); brewCounter = kWaitBrew; break; @@ -330,12 +349,17 @@ void brew() { brewCounter = kBrewFinished; } + // testPower += 1; + // testPower = testPower % 100; + pumpOn(5); + + break; case kBrewFinished: // brew finished debugPrintln("Brew stopped"); digitalWrite(PIN_VALVE, relayOff); - digitalWrite(PIN_PUMP, relayOff); + pumpOff(); brewCounter = kWaitBrewOff; timeBrewed = 0; @@ -344,7 +368,7 @@ void brew() { case kWaitBrewOff: // waiting for brewswitch off position if (brewSwitch == LOW) { digitalWrite(PIN_VALVE, relayOff); - digitalWrite(PIN_PUMP, relayOff); + pumpOff(); // disarmed button currentMillisTemp = 0; @@ -392,6 +416,7 @@ void brew() { if (brewSwitch == HIGH && backflushState == 10 && backflushOn == 0 && brewSwitchWasOff) { startingTime = millis(); brewCounter = kPreinfusion; + resetDimmerCounter(); if (preinfusionPause == 0 || preinfusion == 0) { brewCounter = kBrewRunning; @@ -408,7 +433,7 @@ void brew() { case 20: // preinfusioon debugPrintln("Preinfusion"); digitalWrite(PIN_VALVE, relayOn); - digitalWrite(PIN_PUMP, relayOn); + pumpOn(); brewCounter = kWaitPreinfusion; break; @@ -423,7 +448,7 @@ void brew() { case 30: // preinfusion pause debugPrintln("preinfusion pause"); digitalWrite(PIN_VALVE, relayOn); - digitalWrite(PIN_PUMP, relayOff); + pumpOff(); brewCounter = kWaitPreinfusionPause; break; @@ -438,7 +463,7 @@ void brew() { case 40: // brew running debugPrintln("Brew started"); digitalWrite(PIN_VALVE, relayOn); - digitalWrite(PIN_PUMP, relayOn); + pumpOn(10); brewCounter = kWaitBrew; break; @@ -453,7 +478,7 @@ void brew() { case 42: // brew finished debugPrintln("Brew stopped"); digitalWrite(PIN_VALVE, relayOff); - digitalWrite(PIN_PUMP, relayOff); + pumpOff(); brewCounter = kWaitBrewOff; break; @@ -461,7 +486,7 @@ void brew() { case 43: // waiting for brewswitch off position if (brewSwitch == LOW) { digitalWrite(PIN_VALVE, relayOff); - digitalWrite(PIN_PUMP, relayOff); + pumpOff(); // disarmed button currentMillisTemp = 0; diff --git a/src/dimmer.h b/src/dimmer.h new file mode 100644 index 00000000..386ad3e9 --- /dev/null +++ b/src/dimmer.h @@ -0,0 +1,50 @@ +#pragma once + +int currentPowerLevel = 0; +int power = 0; + +/** + * When starting a new shot, we have to reset the counter to clear any values left over from the last shot. +*/ +void resetDimmerCounter() { + currentPowerLevel = 0; +} + +/** + * Power must be set as a percentage (i.e. between 0 and 100, inclusive). +*/ +void setPower(int newPower) { + // Illeagal value range, turn pump off to be on the safe side. + if (newPower < 0 || newPower > 100) { + power = 0; + return; + } + debugPrintf("Setting new power %d\n", newPower); + power = newPower; +} + +/* +Idea: each time we get a ZC interrupt after a full sine wave, we increment the currentPowerLevel by the set power percentage. +If we have reached 100%, we turn on the pump. +This method should provide even distribution of "on" and "off" cycles without having to implement arrays or similar to keep track of previous on/off phases. +*/ +void handleZC() { + // increment power level by the set power level + currentPowerLevel += power; + + // if the power level has reached 100, we turn the pump on + if (currentPowerLevel >= 100) { + digitalWrite(PIN_PUMP, HIGH); + // Decrease power level by 100 to be ready for the next increments + currentPowerLevel -= 100; + } + // Power level is not yet 100 --> we wait for it to increase further and keep the pump off. + else { + digitalWrite(PIN_PUMP, LOW); + } +} + +void setupDimmer() { + pinMode(PIN_ZC, INPUT_PULLUP); + attachInterrupt(digitalPinToInterrupt(PIN_ZC), handleZC, FALLING); +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index da0c4d63..fcc162dd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1531,7 +1531,11 @@ void websiteSetup() { const char sysVersion[] = (STR(FW_VERSION) "." STR(FW_SUBVERSION) "." STR(FW_HOTFIX) " " FW_BRANCH " " AUTO_VERSION); +#include "dimmer.h" + void setup() { + setupDimmer(); + editableVars["PID_ON"] = { .displayName = "Enable PID Controller", .hasHelpText = false, From 87d8005164a3448e031405966ab25f39964ad8ba Mon Sep 17 00:00:00 2001 From: Fabian Sperrle Date: Sun, 21 Jan 2024 21:49:03 +0100 Subject: [PATCH 2/3] Add debounce to ZC interrupt for consitent interrupt timings --- src/brewvoid.h | 5 ----- src/dimmer.h | 10 +++++++++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/brewvoid.h b/src/brewvoid.h index 9390377c..a200fbc3 100644 --- a/src/brewvoid.h +++ b/src/brewvoid.h @@ -349,11 +349,6 @@ void brew() { brewCounter = kBrewFinished; } - // testPower += 1; - // testPower = testPower % 100; - pumpOn(5); - - break; case kBrewFinished: // brew finished diff --git a/src/dimmer.h b/src/dimmer.h index 386ad3e9..ea82a5e2 100644 --- a/src/dimmer.h +++ b/src/dimmer.h @@ -1,5 +1,7 @@ #pragma once +// used to debounce the interrupts +unsigned long lastZCInterrupt = 0; int currentPowerLevel = 0; int power = 0; @@ -29,6 +31,12 @@ If we have reached 100%, we turn on the pump. This method should provide even distribution of "on" and "off" cycles without having to implement arrays or similar to keep track of previous on/off phases. */ void handleZC() { + unsigned long time = millis(); + if (time - lastZCInterrupt < 15) { + return; + } + lastZCInterrupt = time; + // increment power level by the set power level currentPowerLevel += power; @@ -46,5 +54,5 @@ void handleZC() { void setupDimmer() { pinMode(PIN_ZC, INPUT_PULLUP); - attachInterrupt(digitalPinToInterrupt(PIN_ZC), handleZC, FALLING); + attachInterrupt(digitalPinToInterrupt(PIN_ZC), handleZC, RISING); } \ No newline at end of file From 17cd8c92dc0a9259aa41ec53a24c3ed9ed4b5ff9 Mon Sep 17 00:00:00 2001 From: Fabian Sperrle Date: Fri, 26 Jan 2024 23:21:52 +0100 Subject: [PATCH 3/3] Align with new FEATURE_ nomenclature --- src/brewvoid.h | 4 ++-- src/userConfig_sample.h | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/brewvoid.h b/src/brewvoid.h index a200fbc3..9cc34fb3 100644 --- a/src/brewvoid.h +++ b/src/brewvoid.h @@ -70,7 +70,7 @@ boolean brewPIDDisabled = false; // is PID disabled for delay #include "dimmer.h" void pumpOn(int power = 100) { - #if DIMMER == 0 + #if FEATURE_PUMP_DIMMER == 0 digitalWrite(PIN_PUMP, relayOn); #else setPower(power); @@ -78,7 +78,7 @@ void pumpOn(int power = 100) { } void pumpOff() { - #if DIMMER == 0 + #if FEATURE_PUMP_DIMMER == 0 digitalWrite(PIN_PUMP, relayOff); #else setPower(0); diff --git a/src/userConfig_sample.h b/src/userConfig_sample.h index a696212f..6d3633a5 100644 --- a/src/userConfig_sample.h +++ b/src/userConfig_sample.h @@ -76,6 +76,8 @@ enum MACHINE { #define FLUSHTIME 10000 // time in ms the 3-way valve is open -> backflush #define MAXFLUSHCYCLES 5 // number of cycles the backflush should run, 0 = disabled +#define FEATURE_PUMP_DIMMER 1 // 0 = no dimmer, standard relais; 1 = dimmer for pump control + // PlatformIO OTA #define OTA true // true = OTA activated, false = OTA deactivated #define OTAPASS "otapass" // Password for OTA updates