diff --git a/src/brewvoid.h b/src/brewvoid.h index 94abd801..9cc34fb3 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 FEATURE_PUMP_DIMMER == 0 + digitalWrite(PIN_PUMP, relayOn); + #else + setPower(power); + #endif +} + +void pumpOff() { + #if FEATURE_PUMP_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; @@ -335,7 +354,7 @@ void brew() { case kBrewFinished: // brew finished debugPrintln("Brew stopped"); digitalWrite(PIN_VALVE, relayOff); - digitalWrite(PIN_PUMP, relayOff); + pumpOff(); brewCounter = kWaitBrewOff; timeBrewed = 0; @@ -344,7 +363,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 +411,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 +428,7 @@ void brew() { case 20: // preinfusioon debugPrintln("Preinfusion"); digitalWrite(PIN_VALVE, relayOn); - digitalWrite(PIN_PUMP, relayOn); + pumpOn(); brewCounter = kWaitPreinfusion; break; @@ -423,7 +443,7 @@ void brew() { case 30: // preinfusion pause debugPrintln("preinfusion pause"); digitalWrite(PIN_VALVE, relayOn); - digitalWrite(PIN_PUMP, relayOff); + pumpOff(); brewCounter = kWaitPreinfusionPause; break; @@ -438,7 +458,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 +473,7 @@ void brew() { case 42: // brew finished debugPrintln("Brew stopped"); digitalWrite(PIN_VALVE, relayOff); - digitalWrite(PIN_PUMP, relayOff); + pumpOff(); brewCounter = kWaitBrewOff; break; @@ -461,7 +481,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..ea82a5e2 --- /dev/null +++ b/src/dimmer.h @@ -0,0 +1,58 @@ +#pragma once + +// used to debounce the interrupts +unsigned long lastZCInterrupt = 0; +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() { + unsigned long time = millis(); + if (time - lastZCInterrupt < 15) { + return; + } + lastZCInterrupt = time; + + // 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, RISING); +} \ 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, 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