Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Start dimmer experiments #441

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 35 additions & 15 deletions src/brewvoid.h

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Integrated 2 new Brewmodes for Dimmer including and excluding scale. During brew pressure PID is calculating and giving the power

#if (BREWMODE == 3) // old Brew MODE
/**

  • @brief PreInfusion, Brew Normal
    */
    void brew() {
    if (OnlyPID == 0) {
    checkbrewswitch();
    unsigned long currentMillistemp = millis();

     if (brewcounter > kBrewIdle && brewcounter < kWaitBrewOff) {
         timeBrewed = currentMillistemp - startingTime;
     }
    
     if (brewswitch == LOW && brewcounter > kBrewIdle) {
         // abort function for state machine from every state
         brewcounter = kWaitBrewOff;
     }
    
     if (brewswitch == LOW && movingAverageInitialized == 0) {
         // check if brewswitch was turned off at least once, last time,
         brewswitchWasOFF = true;
     }
    
     totalbrewtime = ((preinfusion * 1000) + (preinfusionpause * 1000) +
         (brewtime * 1000));  // running every cycle, in case changes are done during brew
    
     // state machine for brew
     switch (brewcounter) {
         case 10:  // waiting step for brew switch turning on
             if (brewswitch == HIGH && backflushState == 10 && backflushON == 0 && brewswitchWasOFF) {
                 startingTime = millis();
                 brewcounter = kPreinfusion;
    
                 if (preinfusionpause == 0 || preinfusion == 0) {
                     brewcounter = kPreinfusion;
                 }
    
                 coldstart = false;  // force reset kaltstart if shot is pulled
             } else {
                 backflush();
             }
    
             break;
         case 20:  // preinfusioon
             Serial.println("Preinfusion");
             digitalWrite(PIN_VALVE, relayON);
             digitalWrite(PIN_PUMP, relayON);
             dimmer.setPower(PreinfusionDimmer);
             brewcounter = kBrewRunning;
    
             break;
    
    
         case 40:  // brew running
             Serial.println("Profiling started");
             digitalWrite(PIN_VALVE, relayON);
             digitalWrite(PIN_PUMP, relayON);
             pressurePID.SetMode(AUTOMATIC);
             pressurePID.Compute();
             dimmer.setPower(OutputDimmer);
             brewcounter = kWaitBrew;
    
             break;
    
         case 41:  // waiting time brew
             lastbrewTime = timeBrewed;
    
             if (timeBrewed > totalbrewtime) {
                 brewcounter = kBrewFinished;
             }
    
             break;
    
         case 42:  // brew finished
             Serial.println("Brew stopped");
             pressurePID.SetMode(MANUAL);
             dimmer.setPower(0);
             digitalWrite(PIN_VALVE, relayOFF);
             digitalWrite(PIN_PUMP, relayOFF);
             brewcounter = kWaitBrewOff;
             timeBrewed = 0;
    
             break;
    
         case 43:  // waiting for brewswitch off position
             if (brewswitch == LOW) {
                 pressurePID.SetMode(MANUAL);
                 dimmer.setPower(0);
                 digitalWrite(PIN_VALVE, relayOFF);
                 digitalWrite(PIN_PUMP, relayOFF);
                 
    
                 // disarmed button
                 currentMillistemp = 0;
                 brewDetected = 0;  // rearm brewdetection
                 brewcounter = kBrewIdle;
                 timeBrewed = 0;
             }
    
             break;
     }
    

    }
    }
    #endif

#if (BREWMODE == 4)
/**

  • @brief Scale brew mode
    */
    void brew() {
    if (OnlyPID == 0) {
    checkbrewswitch();
    unsigned long currentMillistemp = millis();

     if (brewswitch == LOW && brewcounter > kBrewIdle) {
         // abort function for state machine from every state
         brewcounter = kWaitBrewOff;
     }
    
     if (brewcounter > kBrewIdle && brewcounter < kWaitBrewOff) {
         timeBrewed = currentMillistemp - startingTime;
         weightBrew = weight - weightPreBrew;
     }
    
     if (brewswitch == LOW && movingAverageInitialized) {
         // check if brewswitch was turned off at least once, last time,
         brewswitchWasOFF = true;
     }
    
     totalBrewTime = ((preinfusion * 1000) + (brewtime * 1000));  
     // running every cycle, in case changes are done during brew
    
     // state machine for brew
     switch (brewcounter) {
         case kBrewIdle:  // waiting step for brew switch turning on
             if (brewswitch == HIGH && backflushState == 10 && backflushON == 0 && brewswitchWasOFF) {
                 startingTime = millis();
    
                 if (preinfusion == 0) {
                     brewcounter = kBrewRunning;
                 } else {
                     brewcounter = kPreinfusion;
                 }
    
                 coldstart = false;  // force reset kaltstart if shot is pulled
                 weightPreBrew = weight;
                 pressuresetPoint = 0;
             } else {
                 backflush();
             }
    
             break;
    
         case kPreinfusion:  // preinfusioon
             debugPrintln("Preinfusion");
             digitalWrite(PIN_VALVE, relayON);
             digitalWrite(PIN_PUMP, relayON);
             dimmer.setPower(PreinfusionDimmer);
             brewcounter = kWaitPreinfusion;
    
             break;
    
         case kWaitPreinfusion:  // waiting time preinfusion
             if (timeBrewed > (preinfusion * 1000)) {
                 brewcounter = kBrewRunning;
             }
    
             break;
             
         case kBrewRunning:  // brew running
             debugPrintln("Brew started");
             digitalWrite(PIN_VALVE, relayON);
             digitalWrite(PIN_PUMP, relayON);
             dimmer.setPower(OutputDimmer);
             pressurePID.Compute();
             brewcounter = kWaitBrew;
             break;
    
         case kWaitBrew:  // waiting time brew
             lastbrewTime = timeBrewed;
             dimmer.setPower(OutputDimmer);
             pressurePID.Compute();
             if (timeBrewed > totalBrewTime || (weightBrew > (weightSetpoint - scaleDelayValue))) {
                 brewcounter = kBrewFinished;
             }
    
             if (timeBrewed > totalBrewTime) {
                 brewcounter = kBrewFinished;
             }
    
             break;
    
         case kBrewFinished:  // brew finished
             debugPrintln("Brew stopped");
             dimmer.setPower(0);
             digitalWrite(PIN_VALVE, relayOFF);
             digitalWrite(PIN_PUMP, relayOFF);
             brewcounter = kWaitBrewOff;
             timeBrewed = 0;
    
             break;
    
         case kWaitBrewOff:  // waiting for brewswitch off position
             if (brewswitch == LOW) {
                 dimmer.setPower(0);
                 digitalWrite(PIN_VALVE, relayOFF);
                 digitalWrite(PIN_PUMP, relayOFF);
    
                 // disarmed button bezugsZeitAlt = bezugsZeit;
                 currentMillistemp = 0;
                 brewDetected = 0;  // rearm brewdetection
                 brewcounter = kBrewIdle;
                 timeBrewed = 0;
                 pressuresetPoint = 0;
                 
             }
    
             weightBrew = weight - weightPreBrew;  // always calculate weight to show on display
    
             break;
     }
    

    }
    }

Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -118,7 +136,7 @@ void checkbrewswitch() {
debugPrintln("brewSwitchTriggerCase 20: Manual Trigger - flushing");
brewSwitchTriggerCase = 31;
digitalWrite(PIN_VALVE, relayOn);
digitalWrite(PIN_PUMP, relayOn);
pumpOn();
}
break;

Expand All @@ -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;

Expand Down Expand Up @@ -193,7 +211,7 @@ void backflush() {
case kBackflushFillingStart:
debugPrintln("Backflush: Portafilter filling...");
digitalWrite(PIN_VALVE, relayOn);
digitalWrite(PIN_PUMP, relayOn);
pumpOn();
backflushState = kBackflushFilling;

break;
Expand All @@ -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;

Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
Expand All @@ -288,7 +307,7 @@ void brew() {
case kPreinfusion: // preinfusioon
debugPrintln("Preinfusion");
digitalWrite(PIN_VALVE, relayOn);
digitalWrite(PIN_PUMP, relayOn);
pumpOn(10);
brewCounter = kWaitPreinfusion;

break;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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;

Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -408,7 +428,7 @@ void brew() {
case 20: // preinfusioon
debugPrintln("Preinfusion");
digitalWrite(PIN_VALVE, relayOn);
digitalWrite(PIN_PUMP, relayOn);
pumpOn();
brewCounter = kWaitPreinfusion;

break;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -453,15 +473,15 @@ void brew() {
case 42: // brew finished
debugPrintln("Brew stopped");
digitalWrite(PIN_VALVE, relayOff);
digitalWrite(PIN_PUMP, relayOff);
pumpOff();
brewCounter = kWaitBrewOff;

break;

case 43: // waiting for brewswitch off position
if (brewSwitch == LOW) {
digitalWrite(PIN_VALVE, relayOff);
digitalWrite(PIN_PUMP, relayOff);
pumpOff();

// disarmed button
currentMillisTemp = 0;
Expand Down
58 changes: 58 additions & 0 deletions src/dimmer.h
Original file line number Diff line number Diff line change
@@ -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);
}
4 changes: 4 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions src/userConfig_sample.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading