Skip to content

Instantly share code, notes, and snippets.

@loginov-rocks
Created January 8, 2022 20:37
Show Gist options
  • Save loginov-rocks/ec6bf5b8a4b12d6aa5301c269be3f26c to your computer and use it in GitHub Desktop.
Save loginov-rocks/ec6bf5b8a4b12d6aa5301c269be3f26c to your computer and use it in GitHub Desktop.
DIY Connected Espresso Machine: Main Class and Indicators (Part 5) - Make Coffee Command, Implementation
#include "EspressoMachine.h"
void EspressoMachine::operateDone()
{
isDone = false;
if (getCommand() == EspressoMachineCommand::MakeCoffee)
{
if (makeCoffeeMillisLeft <= 0)
{
isDone = true;
}
}
else if (getBoilerTargetTemp() != BoilerTemp::Cold && getBoilerTemp() == getBoilerTargetTemp())
{
isDone = true;
}
digitalWrite(donePin, isDone);
}
void EspressoMachine::makeCoffeeOperate()
{
// Safety condition: switch components off if no milliseconds left to make coffee.
if (makeCoffeeMillisLeft <= 0)
{
pump.off();
boiler.setTargetTemp(BoilerTemp::Cold);
return;
}
// Water pouring has not started yet.
if (makeCoffeePourWaterStartMillis <= 0)
{
boiler.setTargetTemp(BoilerTemp::Boiling);
// A suitable temperature is achieved, start to pour water and remember when.
if (getBoilerTemp() == BoilerTemp::Boiling)
{
pump.on();
makeCoffeePourWaterStartMillis = millis();
}
return;
}
unsigned long _millis = millis();
// There are milliseconds left to make coffee, water pouring started, but the target time has not been achieved yet.
if (makeCoffeePourWaterStartMillis + makeCoffeeMillisLeft >= _millis)
{
// Temperature is not suitable, pause water pouring and remember milliseconds left.
if (getBoilerTemp() != BoilerTemp::Boiling)
{
pump.off();
makeCoffeeMillisLeft -= _millis - makeCoffeePourWaterStartMillis;
makeCoffeePourWaterStartMillis = 0;
}
return;
}
// Target time to make coffee achieved.
pump.off();
boiler.setTargetTemp(BoilerTemp::Cold);
makeCoffeeMillisLeft = 0;
makeCoffeePourWaterStartMillis = 0;
}
long EspressoMachine::getMakeCoffeeMillisLeft()
{
return makeCoffeeMillisLeft;
}
boolean EspressoMachine::command(EspressoMachineCommand command)
{
// Deny the "Make Coffee" command, use the overloaded method to pass arguments.
if (command == EspressoMachineCommand::MakeCoffee)
{
return false;
}
// Deny internal commands usage programmatically.
if (command == EspressoMachineCommand::ToggleBoil ||
command == EspressoMachineCommand::ToggleMakeSteam ||
command == EspressoMachineCommand::TogglePourWater)
{
return false;
}
// Deny external commands if the toggle is not in the "Off" position.
if (getToggleState() != ToggleState::Off)
{
return false;
}
// Drop helpers for the "Make Coffee" command.
makeCoffeeMillisLeft = 0;
makeCoffeePourWaterStartMillis = 0;
setCommand(command);
return true;
}
// Overload for the "Make Coffee" command to pass arguments.
boolean EspressoMachine::command(EspressoMachineCommand command, int seconds)
{
// Deny other commands.
if (command != EspressoMachineCommand::MakeCoffee)
{
return false;
}
// Seconds should be greater than null.
if (seconds <= 0)
{
return false;
}
// Deny external commands if the toggle is not in the "Off" position.
if (getToggleState() != ToggleState::Off)
{
return false;
}
// Set helpers for the "Make Coffee" command.
makeCoffeeMillisLeft = (long)seconds * 1000;
makeCoffeePourWaterStartMillis = 0;
setCommand(command);
return true;
}
void EspressoMachine::work()
{
// ...
switch (lastCommand)
{
// ...
case EspressoMachineCommand::MakeCoffee:
// Encapsulate related operations in a separate function.
makeCoffeeOperate();
break;
}
// ...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment