Commit abf959fa authored by João Lino's avatar João Lino

menus sorted

menus sorted
parent d5ea03fd
...@@ -118,6 +118,7 @@ typedef struct menuData_ { ...@@ -118,6 +118,7 @@ typedef struct menuData_ {
int _position; int _position;
int _selection; int _selection;
bool _repaint; bool _repaint;
void (*_selectionFunction)(void);
} MenuData; } MenuData;
#endif #endif
...@@ -17,6 +17,14 @@ ...@@ -17,6 +17,14 @@
#include "CustomDataStructures.h" #include "CustomDataStructures.h"
#include "debug.h" #include "debug.h"
// ++++++++++++++++++++++++ FUNCTIONS (used in configuration) +++++++++++++++++++++++++++++++++
void runMainMenuSelection();
void runStartFromStageSelection();
void runBeerProfileSelection();
void runStageSelection();
void runMaltSelection();
void runSettingsSelection();
#include "config.h" #include "config.h"
#include "Melody.h" #include "Melody.h"
...@@ -38,13 +46,9 @@ void xWelcomeUser(); ...@@ -38,13 +46,9 @@ void xWelcomeUser();
void runMenu(); void runMenu();
void runSettingsSelection(); void runMenuProcessor( MenuData *data );
void runMaltSelection(); void runStageSelection_Generic( unsigned long * selectedStageTime, int *selectedStageTemperature);
void runStageSelection();
void runBeerProfileSelection();
void xStartStage( unsigned long *stageTime, int *stageTemperature, eCookingStages nextStage, bool bPurgePump, bool bSetFinalYield, bool bSetTime, bool bSetTemperature ); void xStartStage( unsigned long *stageTime, int *stageTemperature, eCookingStages nextStage, bool bPurgePump, bool bSetFinalYield, bool bSetTime, bool bSetTemperature );
...@@ -52,10 +56,6 @@ void xStartStageHeadless( eCookingStages nextStage, bool bPurgePump ); ...@@ -52,10 +56,6 @@ void xStartStageHeadless( eCookingStages nextStage, bool bPurgePump );
void xStartStageInteractive( unsigned long *stageTime, int *stageTemperature, eCookingStages nextStage ); void xStartStageInteractive( unsigned long *stageTime, int *stageTemperature, eCookingStages nextStage );
void runStartFromStageSelection();
void runMainMenuSelection();
void xCountTheTime( int temperatureRange, boolean bAverageUpDown ); void xCountTheTime( int temperatureRange, boolean bAverageUpDown );
bool isTimeLeft(); bool isTimeLeft();
......
...@@ -18,25 +18,12 @@ eBeerProfile beerProfile; ...@@ -18,25 +18,12 @@ eBeerProfile beerProfile;
eMenuType eMenuType; eMenuType eMenuType;
MenuData mdMainMenu = { ._title = MENU_MAIN_TITLE, ._dialog = MENU_MAIN_DIALOG, ._position = MENU_MAIN_INIT_POSITION, ._selection = MENU_MAIN_INIT_SELECTION, ._repaint = MENU_MAIN_INIT_REPAINT }; MenuData mdMainMenu = { ._title = MENU_MAIN_TITLE, ._dialog = MENU_MAIN_DIALOG, ._position = MENU_MAIN_INIT_POSITION, ._selection = MENU_MAIN_INIT_SELECTION, ._repaint = MENU_MAIN_INIT_REPAINT, ._selectionFunction = MENU_MAIN_FUNCTION };
MenuData mdStartFromStageMenu = { ._title = MENU_START_TITLE, ._dialog = MENU_START_DIALOG, ._position = MENU_START_INIT_POSITION, ._selection = MENU_START_INIT_SELECTION, ._repaint = MENU_START_INIT_REPAINT }; MenuData mdBeerProfileMenu = { ._title = MENU_PROFILE_TITLE, ._dialog = MENU_PROFILE_DIALOG, ._position = MENU_PROFILE_INIT_POSITION, ._selection = MENU_PROFILE_INIT_SELECTION, ._repaint = MENU_PROFILE_INIT_REPAINT, ._selectionFunction = MENU_PROFILE_FUNCTION };
MenuData mdBeerProfileMenu = { ._title = MENU_PROFILE_TITLE, ._dialog = MENU_PROFILE_DIALOG, ._position = MENU_PROFILE_INIT_POSITION, ._selection = MENU_PROFILE_INIT_SELECTION, ._repaint = MENU_PROFILE_INIT_REPAINT }; MenuData mdStageMenu = { ._title = MENU_STAGE_TITLE, ._dialog = MENU_STAGE_DIALOG, ._position = MENU_STAGE_INIT_POSITION, ._selection = MENU_STAGE_INIT_SELECTION, ._repaint = MENU_STAGE_INIT_REPAINT, ._selectionFunction = MENU_STAGE_FUNCTION };
MenuData mdStageMenu = { ._title = MENU_STAGE_TITLE, ._dialog = MENU_STAGE_DIALOG, ._position = MENU_STAGE_INIT_POSITION, ._selection = MENU_STAGE_INIT_SELECTION, ._repaint = MENU_STAGE_INIT_REPAINT }; MenuData mdMaltMenu = { ._title = MENU_MALT_TITLE, ._dialog = MENU_MALT_DIALOG, ._position = MENU_MALT_INIT_POSITION, ._selection = MENU_MALT_INIT_SELECTION, ._repaint = MENU_MALT_INIT_REPAINT, ._selectionFunction = MENU_MALT_FUNCTION };
MenuData mdMaltMenu = { ._title = MENU_MALT_TITLE, ._dialog = MENU_MALT_DIALOG, ._position = MENU_MALT_INIT_POSITION, ._selection = MENU_MALT_INIT_SELECTION, ._repaint = MENU_MALT_INIT_REPAINT }; MenuData mdSettingsMenu = { ._title = MENU_SETTINGS_TITLE, ._dialog = MENU_SETTINGS_DIALOG, ._position = MENU_SETTINGS_INIT_POSITION, ._selection = MENU_SETTINGS_INIT_SELECTION, ._repaint = MENU_SETTINGS_INIT_REPAINT, ._selectionFunction = MENU_SETTINGS_FUNCTION };
MenuData mdSettingsMenu = { ._title = MENU_SETTINGS_TITLE, ._dialog = MENU_SETTINGS_DIALOG, ._position = MENU_SETTINGS_INIT_POSITION, ._selection = MENU_SETTINGS_INIT_SELECTION, ._repaint = MENU_SETTINGS_INIT_REPAINT }; MenuData mdStartFromStageMenu = { ._title = MENU_START_TITLE, ._dialog = MENU_START_DIALOG, ._position = MENU_START_INIT_POSITION, ._selection = MENU_START_INIT_SELECTION, ._repaint = MENU_START_INIT_REPAINT, ._selectionFunction = MENU_START_FUNCTION };
//eMainMenuOptions eMainMenuPosition;
//eMainMenuOptions eMainMenuSelection;
eStageMenuOptions eStartFromStageMenuPosition;
eStageMenuOptions eStartFromStageMenuSelection;
eBeerProfileMenuOptions eBeerProfileMenuPosition;
eBeerProfileMenuOptions eBeerProfileMenuSelection;
eStageMenuOptions eStageMenuPosition;
eStageMenuOptions eStageMenuSelection;
eMaltMenuOptions eMaltMenuPosition;
eMaltMenuOptions eMaltMenuSelection;
eSettingsMenuOptions eSettingsMenuPosition;
eSettingsMenuOptions eSettingsMenuSelection;
// ++++++++++++++++++++++++ Global Variables ++++++++++++++++++++++++ // ++++++++++++++++++++++++ Global Variables ++++++++++++++++++++++++
boolean cooking; boolean cooking;
...@@ -147,10 +134,10 @@ void isr () { // Interrupt service routine is executed when a HIGH to LOW tr ...@@ -147,10 +134,10 @@ void isr () { // Interrupt service routine is executed when a HIGH to LOW tr
rotaryEncoderVirtualPosition = rotaryEncoderVirtualPosition - rotaryEncoderSingleStep; rotaryEncoderVirtualPosition = rotaryEncoderVirtualPosition - rotaryEncoderSingleStep;
} }
if (rotaryEncoderVirtualPosition > rotaryEncoderMaxPosition) { if (rotaryEncoderVirtualPosition > rotaryEncoderMaxPosition) {
rotaryEncoderVirtualPosition = rotaryEncoderMinPosition; rotaryEncoderVirtualPosition = rotaryEncoderMaxPosition;
} }
if (rotaryEncoderVirtualPosition < rotaryEncoderMinPosition) { if (rotaryEncoderVirtualPosition < rotaryEncoderMinPosition) {
rotaryEncoderVirtualPosition = rotaryEncoderMaxPosition; rotaryEncoderVirtualPosition = rotaryEncoderMinPosition;
} }
break; break;
...@@ -301,17 +288,6 @@ void setup() { ...@@ -301,17 +288,6 @@ void setup() {
// ++++++++++++++++++++++++ State Machine ++++++++++++++++++++++++ // ++++++++++++++++++++++++ State Machine ++++++++++++++++++++++++
eMenuType = eMenuType_Main; eMenuType = eMenuType_Main;
//eMainMenuPosition = MENU_MAIN_INIT_POSITION;
//eMainMenuSelection = MENU_MAIN_INIT_SELECTION;
eBeerProfileMenuPosition = eBeerProfileMenu_Basic;
eBeerProfileMenuSelection = eBeerProfileMenu_NULL;
eStageMenuPosition = eStageMenu_Startpoint;
eStageMenuSelection = eStageMenu_NULL;
eMaltMenuPosition = eMaltMenu_CastleMalting_Chteau_Pilsen_2RS;
eMaltMenuSelection = eMaltMenu_NULL;
eSettingsMenuPosition = eSettingsMenu_PT100_Element;
eSettingsMenuSelection = eSettingsMenu_NULL;
cookingStage = eCookingStage_Startpoint; cookingStage = eCookingStage_Startpoint;
beerProfile = eBeerProfile_Basic; beerProfile = eBeerProfile_Basic;
// ++++++++++++++++++++++++ Global Variables ++++++++++++++++++++++++ // ++++++++++++++++++++++++ Global Variables ++++++++++++++++++++++++
...@@ -394,634 +370,620 @@ void loop() { ...@@ -394,634 +370,620 @@ void loop() {
// ######################### FUNCTIONS ######################## // ######################### FUNCTIONS ########################
void runMenu() {
#ifdef DEBUG_OFF
boolean debug_go = repaint;
if (debug_go) {
debugPrintFunction("runMenu");
debugPrintVar("repaint", repaint);
debugPrintVar("eMenuType", eMenuType);
debugPrintVar("rotaryEncoderVirtualPosition", rotaryEncoderVirtualPosition);
}
#endif
switch (eMenuType) {
case eMenuType_Main: {
//eMainMenuPosition = static_cast<eMainMenuOptions>(rotaryEncoderVirtualPosition);
mdMainMenu._position = rotaryEncoderVirtualPosition;
mdMainMenu._repaint = repaint;
repaint = displayGenericMenu( &lcd, &mdMainMenu );
//repaint = displayMainMenu( &lcd, eMainMenuPosition, repaint );
if ( gotButtonPress( ROTARY_ENCODER_SW_PIN ) ) {
mdMainMenu._selection = mdMainMenu._position;
//eMainMenuSelection = eMainMenuPosition;
}
runMainMenuSelection(); void xCountTheTime( int temperatureMarginRange, boolean bMaximumOfUpDown ) {
unsigned long now = millis();
break; // Get current maximum sensed temperaure
} double temperatureCount = 0;
case eMenuType_StartFromStage: { if ( bMaximumOfUpDown ) {
eStartFromStageMenuPosition = static_cast<eStageMenuOptions>(rotaryEncoderVirtualPosition); float tup = upPT100.getCurrentTemperature();
float tdown = downPT100.getCurrentTemperature();
if (tup > tdown) {
temperatureCount = tdown;
}
else {
temperatureCount = tup;
}
} else {
temperatureCount = basePT100.getCurrentTemperature();
}
repaint = displayStageMenu( &lcd, eStartFromStageMenuPosition, repaint ); // Ignote time ticks if temperature is not within the acceptable margin for this stage
unsigned long elapsedTime = now - clockLastUpdate;
if ( temperatureCount < (cookTemperature - temperatureMarginRange) ) {
clockIgnore += elapsedTime;
}
if ( gotButtonPress( ROTARY_ENCODER_SW_PIN ) ) { // Calculate the remaining time on the clock
eStartFromStageMenuSelection = eStartFromStageMenuPosition; clockCounter = cookTime * 1000 - (elapsedTime - clockIgnore);
}
runStartFromStageSelection(); // Don't let clock get bellow 0
if ( clockCounter < 0 ) {
clockCounter = 0;
}
break; clockLastUpdate = now;
}
case eMenuType_BeerProfile: {
eBeerProfileMenuPosition = static_cast<eBeerProfileMenuOptions>(rotaryEncoderVirtualPosition);
repaint = displayBeerProfileMenu( &lcd, eBeerProfileMenuPosition, repaint ); #ifdef DEBUG_OFF
debugPrintFunction("xCountTheTime");
debugPrintVar("millis()", now);
debugPrintVar("cookTime", cookTime);
debugPrintVar("clockStartTime", clockStartTime);
debugPrintVar("clockIgnore", clockIgnore);
debugPrintVar("clockCounter", clockCounter);
#endif
}
if ( gotButtonPress( ROTARY_ENCODER_SW_PIN ) ) { bool isTimeLeft() {
eBeerProfileMenuSelection = eBeerProfileMenuPosition; if ( clockCounter > 0 ) {
} return true;
}
return false;
}
runBeerProfileSelection(); //HEATING_ELEMENT_MAX_WATTAGE / HEATING_ELEMENT_AC_FREQUENCY_HZ
double ulWattToWindowTime( double ulAppliedWatts ) {
double ulPulsesRequired = ulAppliedWatts / dWattPerPulse;
return (double)iWindowSize / 1000.0 * ulPulsesRequired * 1000.0 / HEATING_ELEMENT_AC_FREQUENCY_HZ;
}
break; bool xRegulateTemperature( boolean bMaximumOfUpDown ) {
} double difference = 0;
case eMenuType_Stage: { bool overTemperature = false;
eStageMenuPosition = static_cast<eStageMenuOptions>(rotaryEncoderVirtualPosition); double wattage = 0.0;
repaint = displayStageMenu( &lcd, eStageMenuPosition, repaint ); float tup = upPT100.getCurrentTemperature();
float tdown = downPT100.getCurrentTemperature();
float tbase = basePT100.getCurrentTemperature();
if ( gotButtonPress( ROTARY_ENCODER_SW_PIN ) ) { if ( bMaximumOfUpDown ) {
eStageMenuSelection = eStageMenuPosition; if (tup > tdown) {
} difference = cookTemperature - tup;
}
else {
difference = cookTemperature - tdown;
}
runStageSelection(); if (tbase > cookTemperature && (tbase >= (PUMP_TEMPERATURE_MAX_OPERATION - 2.0) || difference >= 5.0)) {
difference = cookTemperature - tbase;
}
break; if ( (tbase < cookTemperature) && (difference < (cookTemperature - tbase)) ) {
} difference = cookTemperature - tbase;
case eMenuType_Malt: { }
eMaltMenuPosition = static_cast<eMaltMenuOptions>(rotaryEncoderVirtualPosition); } else {
difference = cookTemperature - tbase;
}
repaint = displayMaltMenu( &lcd, eMaltMenuPosition, repaint ); // Deviation between the cook temperature set and the cook temperature measured
if ( difference < 0.0 ) {
difference = difference * (-1.0);
overTemperature = true;
}
if ( gotButtonPress( ROTARY_ENCODER_SW_PIN ) ) { // Calculate applied wattage, based on the distance from the target temperature
eMaltMenuSelection = eMaltMenuPosition; if ( overTemperature ) {
// turn it off
wattage = 0.0;
} else {
//if(difference <= 0.1) {
// turn it off
// wattage = 0.0;
//} else {
if (difference <= 0.5) {
// pulse lightly at 500 watt
if (cookTemperature > 99.0) {
wattage = 2000.0;
}
else {
if (cookTemperature > 70.0) {
wattage = 1000.0;
}
else {
wattage = 500.0;
} }
runMaltSelection();
break;
} }
case eMenuType_Settings: { } else {
eSettingsMenuPosition = static_cast<eSettingsMenuOptions>(rotaryEncoderVirtualPosition); if (difference <= 1.0) {
// pulse moderately at 1000 watt
repaint = displaySettingsMenu( &lcd, eSettingsMenuPosition, repaint ); if (cookTemperature > 99.0) {
wattage = 2000.0;
}
else {
wattage = 1000.0;
}
if ( gotButtonPress( ROTARY_ENCODER_SW_PIN ) ) { } else {
eSettingsMenuSelection = eSettingsMenuPosition; if (difference <= 3.0) {
// pulse hardly at 2000 watt
wattage = 2000.0;
} else {
//pulse constantly at HEATING_ELEMENT_MAX_WATTAGE watt
wattage = HEATING_ELEMENT_MAX_WATTAGE;
} }
}
}
//}
}
runSettingsSelection(); // Update the recorded time for the begining of the window, if the previous window has passed
while ((millis() - windowStartTime) > iWindowSize) { // Check if it's time to vary the pulse width modulation and if so do it by shifting the "Relay in ON" Window
windowStartTime += iWindowSize;
}
break; // Apply wattage to the element at the right time
} if ( ulWattToWindowTime( wattage ) > (millis() - windowStartTime) ) {
digitalWrite(HEATING_ELEMENT_OUTPUT_PIN, HIGH);
bStatusElement = true;
} else {
digitalWrite(HEATING_ELEMENT_OUTPUT_PIN, LOW);
bStatusElement = false;
} }
#ifdef DEBUG_OFF #ifdef DEBUG_OFF
if (debug_go) { //debugPrintFunction("xRegulateTemperature");
debugPrintVar("repaint", repaint); debugPrintVar("difference", difference);
} //debugPrintVar("overTemperature", overTemperature);
debugPrintVar("wattage", wattage);
//debugPrintVar("ulWattToWindowTime( wattage )", ulWattToWindowTime( wattage ) );
//debugPrintVar("millis()", millis());
//debugPrintVar("windowStartTime", windowStartTime);
//debugPrintVar("test", ulWattToWindowTime( wattage ) > (millis() - windowStartTime) );
#endif #endif
} }
void runSettingsSelection() { void xPurgePump() {
switch (eSettingsMenuSelection) { for (int i = 0; i < 2; i++) {
case eSettingsMenu_Pump: { analogWrite(PUMP_PIN, PUMP_SPEED_MAX_MOSFET); // analogWrite values from 0 to 255
// Stuff delay(1000);
if ( xSetGenericValue( iPumpSpeed ? 0 : 1, 0, 1, "pump", "bool" ) ) { analogWrite(PUMP_PIN, PUMP_SPEED_STOP_MOSFET); // analogWrite values from 0 to 255
iPumpSpeed = PUMP_SPEED_MAX_MOSFET; delay(1500);
} else { }
iPumpSpeed = PUMP_SPEED_STOP_MOSFET; }
}
analogWrite(PUMP_PIN, iPumpSpeed);
backToStatus();
break;
}
case eSettingsMenu_PT100_Element: {
// Stuff
backToStatus();
break;
}
case eSettingsMenu_PT100_Up: {
// Stuff
backToStatus();
break;
}
case eSettingsMenu_PT100_Down: {
// Stuff
backToStatus(); bool xRegulatePumpSpeed() {
// analogWrite(PUMP_PIN, iPumpSpeed); // analogWrite values from 0 to 255
break; if (basePT100.getCurrentTemperature() > PUMP_TEMPERATURE_MAX_OPERATION) {
} analogWrite(PUMP_PIN, PUMP_SPEED_STOP_MOSFET); // analogWrite values from 0 to 255
case eSettingsMenu_Back: {
eMenuType = eMenuType_Main;
repaint = true;
// reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep basePT100.setPumpStatus( false );
//xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenuPosition, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 ); upPT100.setPumpStatus( false );
xSetupRotaryEncoder( eRotaryEncoderMode_Menu, mdMainMenu._position, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 ); downPT100.setPumpStatus( false );
}
else {
analogWrite(PUMP_PIN, iPumpSpeed); // analogWrite values from 0 to 255
break; basePT100.setPumpStatus( true );
} upPT100.setPumpStatus( true );
default: { downPT100.setPumpStatus( true );
}
} }
}
eSettingsMenuSelection = eSettingsMenu_NULL; void xWarnClockEnded() {
sing(MELODY_SUPER_MARIO_START, PIEZO_PIN);
} }
void runMaltSelection() { void xWarnCookEnded() {
switch (eMaltMenuSelection) { sing(MELODY_UNDERWORLD_SHORT, PIEZO_PIN);
case eMaltMenu_CastleMalting_Chteau_Pilsen_2RS: { }
// Stuff
backToStatus(); void xPrepareForStage( int stageTime, int stageTemperature, int stagePumpSpeed, eCookingStages stage ) {
#ifdef DEBUG_OFF
debugPrintFunction("xPrepareForStage");
debugPrintVar("cookingStage", stage);
#endif
break; // Reset the clock
} unsigned long now = millis();
case eMaltMenu_CastleMalting_Wheat_Blanc: { clockStartTime = now;
// Stuff clockLastUpdate = now;
clockIgnore = 0;
backToStatus();
break;
}
case eMaltMenu_Back: {
eMenuType = eMenuType_Main;
repaint = true;
// reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep
//xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenuPosition, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 );
xSetupRotaryEncoder( eRotaryEncoderMode_Menu, mdMainMenu._position, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 );
break;
}
default: {
}
}
eMaltMenuSelection = eMaltMenu_NULL; iPumpSpeed = stagePumpSpeed; // Set the pump speed
cookingStage = stage; // Set Stage
cookTime = stageTime; // Set the clock
cookTemperature = stageTemperature; // Set the target temperature
} }
void runStageSelection() { void xSetupStage(eCookingStages nextStage) {
switch (eStageMenuSelection) { #ifdef DEBUG_OFF
case eStageMenu_Startpoint: { debugPrintFunction("xSetupStage");
startpointTime = getTimer( startpointTime ); debugPrintVar("cookingStage", nextStage);
#endif
startpointTemperature = xSetGenericValue( startpointTemperature, TEMPERATURE_MIN_VALUE, TEMPERATURE_MAX_VALUE, "temperature", "*C" ); // Operate the machine according to the current mode
switch (nextStage) {
case eCookingStage_Startpoint: {
switch (beerProfile) {
case eBeerProfile_Trigo: {
float wheatAmount = 0.05 * ((float) finalYield);
float pilsnerAmount = 0.2 * ((float) finalYield);
String say = "Cruch ";
say += String(wheatAmount);
say += String("Kg of Wheat and ");
say += String(pilsnerAmount);
say += String("Kg of Pilsner Malt into a pot.");
backToStatus(); xWaitForAction("Malt", say);
repaint = true;
break;
}
case eBeerProfile_IPA: {
float caramelAmount = 0.013157895 * ((float) finalYield);
float wheatAmount = 0.060526316 * ((float) finalYield);
float pilsnerAmount = 0.115789474 * ((float) finalYield);
float munichAmount = 0.028947368 * ((float) finalYield);
String say = "Cruch ";
say += String(caramelAmount);
say += String("Kg of Caramel 120, ");
say += String(wheatAmount);
say += String("Kg of Wheat, ");
say += String(pilsnerAmount);
say += String("Kg of Pilsner, ");
say += String(munichAmount);
say += String("Kg of Munich into a pot.");
break; xWaitForAction("Malt", say);
} repaint = true;
case eStageMenu_BetaGlucanase: { break;
betaGlucanaseTime = getTimer( betaGlucanaseTime ); }
default: {
betaGlucanaseTemperature = xSetGenericValue( betaGlucanaseTemperature, TEMPERATURE_MIN_VALUE, TEMPERATURE_MAX_VALUE, "temperature", "*C" ); }
}
backToStatus(); // Make sure there is water
xWaitForAction("Water", "Make sure there is water in the machine before start cooking.");
repaint = true;
xPrepareForStage( startpointTime, startpointTemperature, PUMP_SPEED_MAX_MOSFET, eCookingStage_Startpoint );
break; break;
} }
case eStageMenu_Debranching: { case eCookingStage_BetaGlucanase: {
debranchingTime = getTimer( debranchingTime ); switch (beerProfile) {
case eBeerProfile_Trigo: {
debranchingTemperature = xSetGenericValue( debranchingTemperature, TEMPERATURE_MIN_VALUE, TEMPERATURE_MAX_VALUE, "temperature", "*C" ); float wheatAmount = 0.05 * ((float) finalYield);
float pilsnerAmount = 0.2 * ((float) finalYield);
String say = "Put ";
say += String(wheatAmount);
say += String("Kg of Wheat and ");
say += String(pilsnerAmount);
say += String("Kg of Pilsner Malt in.");
backToStatus(); xWaitForAction("Malt", say);
repaint = true;
break;
}
case eBeerProfile_IPA: {
float caramelAmount = 0.013157895 * ((float) finalYield);
float wheatAmount = 0.060526316 * ((float) finalYield);
float pilsnerAmount = 0.115789474 * ((float) finalYield);
float munichAmount = 0.028947368 * ((float) finalYield);
String say = "Cruch ";
say += String(caramelAmount);
say += String("Kg of Caramel 120, ");
say += String(wheatAmount);
say += String("Kg of Wheat, ");
say += String(pilsnerAmount);
say += String("Kg of Pilsner, ");
say += String(munichAmount);
say += String("Kg of Munich into a pot.");
xWaitForAction("Malt", say);
repaint = true;
break;
}
default: {}
}
xPrepareForStage( betaGlucanaseTime, betaGlucanaseTemperature, PUMP_SPEED_MAX_MOSFET, eCookingStage_BetaGlucanase );
break; break;
} }
case eStageMenu_Proteolytic: { case eCookingStage_Debranching: {
proteolyticTime = getTimer( proteolyticTime ); xPrepareForStage( debranchingTime, debranchingTemperature, PUMP_SPEED_MAX_MOSFET, eCookingStage_Debranching );
proteolyticTemperature = xSetGenericValue( proteolyticTemperature, TEMPERATURE_MIN_VALUE, TEMPERATURE_MAX_VALUE, "temperature", "*C" );
backToStatus();
break; break;
} }
case eStageMenu_BetaAmylase: { case eCookingStage_Proteolytic: {
betaAmylaseTime = getTimer( betaAmylaseTime ); xPrepareForStage( proteolyticTime, proteolyticTemperature, PUMP_SPEED_MAX_MOSFET, eCookingStage_Proteolytic );
betaAmylaseTemperature = xSetGenericValue( betaAmylaseTemperature, TEMPERATURE_MIN_VALUE, TEMPERATURE_MAX_VALUE, "temperature", "*C" );
backToStatus();
break; break;
} }
case eStageMenu_AlphaAmylase: { case eCookingStage_BetaAmylase: {
alphaAmylaseTime = getTimer( alphaAmylaseTime ); xPrepareForStage( betaAmylaseTime, betaAmylaseTemperature, PUMP_SPEED_MAX_MOSFET, eCookingStage_BetaAmylase );
alphaAmylaseTemperature = xSetGenericValue( alphaAmylaseTemperature, TEMPERATURE_MIN_VALUE, TEMPERATURE_MAX_VALUE, "temperature", "*C" );
backToStatus();
break; break;
} }
case eStageMenu_Mashout: { case eCookingStage_AlphaAmylase: {
mashoutTime = getTimer( mashoutTime ); xPrepareForStage( alphaAmylaseTime, alphaAmylaseTemperature, PUMP_SPEED_MAX_MOSFET, eCookingStage_AlphaAmylase );
mashoutTemperature = xSetGenericValue( mashoutTemperature, TEMPERATURE_MIN_VALUE, TEMPERATURE_MAX_VALUE, "temperature", "*C" );
backToStatus();
break; break;
} }
case eStageMenu_Recirculation: { case eCookingStage_Mashout: {
recirculationTime = getTimer( recirculationTime ); xPrepareForStage( mashoutTime, mashoutTemperature, PUMP_SPEED_MAX_MOSFET, eCookingStage_Mashout );
recirculationTemperature = xSetGenericValue( recirculationTemperature, TEMPERATURE_MIN_VALUE, TEMPERATURE_MAX_VALUE, "temperature", "*C" );
backToStatus();
break; break;
} }
case eStageMenu_Sparge: { case eCookingStage_Recirculation: {
spargeTime = getTimer( spargeTime ); xWaitForAction("Sparge Water", "Start heating your sparge water.");
repaint = true;
spargeTemperature = xSetGenericValue( spargeTemperature, TEMPERATURE_MIN_VALUE, TEMPERATURE_MAX_VALUE, "temperature", "*C" ); xPrepareForStage( recirculationTime, recirculationTemperature, PUMP_SPEED_MAX_MOSFET, eCookingStage_Recirculation );
backToStatus();
break; break;
} }
case eStageMenu_Boil: { case eCookingStage_Sparge: {
boilTime = getTimer( boilTime ); xWaitForAction("Sparge Water", "Start pouring the sparge water.");
repaint = true;
boilTemperature = xSetGenericValue( boilTemperature, TEMPERATURE_MIN_VALUE, TEMPERATURE_MAX_VALUE, "temperature", "*C" ); xPrepareForStage( spargeTime, spargeTemperature, PUMP_SPEED_MAX_MOSFET, eCookingStage_Sparge );
backToStatus();
break; break;
} }
case eStageMenu_Cooling: { case eCookingStage_Boil: {
coolingTime = getTimer( coolingTime ); switch (beerProfile) {
case eBeerProfile_Trigo: {
coolingTemperature = xSetGenericValue( coolingTemperature, TEMPERATURE_MIN_VALUE, TEMPERATURE_MAX_VALUE, "temperature", "*C" ); String say = "Get ";
backToStatus(); float hopAmount = 0.8 * ((float) finalYield);
say += String(hopAmount);
break; say += String("g of Magnum 9.4\% and Styrian Golding 5\% ready.");
}
case eStageMenu_Back: {
eMenuType = eMenuType_Main;
repaint = true;
// reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep xWaitForAction("Hops", say);
//xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenuPosition, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 );
xSetupRotaryEncoder( eRotaryEncoderMode_Menu, mdMainMenu._position, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 );
break; break;
} }
default: { case eBeerProfile_IPA: {
} String say = "Get ";
}
eStageMenuSelection = eStageMenu_NULL; float hopAmount = 0.8 * ((float) finalYield);
} say += String(hopAmount);
void runBeerProfileSelection() { say += String("g of Chinook, Cascade and Styrian Golding ready.");
switch (eBeerProfileMenuSelection) {
case eBeerProfileMenu_Basic: {
beerProfile = eBeerProfile_Basic;
startpointTime = PROFILE_BASIC_STARTPOINT_TIME;
betaGlucanaseTime = PROFILE_BASIC_BETAGLUCANASE_TIME;
debranchingTime = PROFILE_BASIC_DEBRANCHING_TIME;
proteolyticTime = PROFILE_BASIC_PROTEOLYTIC_TIME;
betaAmylaseTime = PROFILE_BASIC_BETAAMYLASE_TIME;
alphaAmylaseTime = PROFILE_BASIC_ALPHAAMYLASE_TIME;
mashoutTime = PROFILE_BASIC_MASHOUT_TIME;
recirculationTime = PROFILE_BASIC_RECIRCULATION_TIME;
spargeTime = PROFILE_BASIC_SPARGE_TIME;
boilTime = PROFILE_BASIC_BOIL_TIME;
coolingTime = PROFILE_BASIC_COOLING_TIME;
startpointTemperature = PROFILE_BASIC_STARTPOINT_TEMPERATURE;
betaGlucanaseTemperature = PROFILE_BASIC_BETAGLUCANASE_TEMPERATURE;
debranchingTemperature = PROFILE_BASIC_DEBRANCHING_TEMPERATURE;
proteolyticTemperature = PROFILE_BASIC_PROTEOLYTIC_TEMPERATURE;
betaAmylaseTemperature = PROFILE_BASIC_BETAAMYLASE_TEMPERATURE;
alphaAmylaseTemperature = PROFILE_BASIC_ALPHAAMYLASE_TEMPERATURE;
mashoutTemperature = PROFILE_BASIC_MASHOUT_TEMPERATURE;
recirculationTemperature = PROFILE_BASIC_RECIRCULATION_TEMPERATURE;
spargeTemperature = PROFILE_BASIC_SPARGE_TEMPERATURE;
boilTemperature = PROFILE_BASIC_BOIL_TEMPERATURE;
coolingTemperature = PROFILE_BASIC_COOLING_TEMPERATURE;
backToStatus(); xWaitForAction("Hops", say);
break; break;
} }
case eBeerProfileMenu_Trigo: { default: {
beerProfile = eBeerProfile_Trigo; xWaitForAction("Hops", "Add the hops in the right order, at the right time.");
startpointTime = PROFILE_TRIGO_STARTPOINT_TIME;
betaGlucanaseTime = PROFILE_TRIGO_BETAGLUCANASE_TIME;
debranchingTime = PROFILE_TRIGO_DEBRANCHING_TIME;
proteolyticTime = PROFILE_TRIGO_PROTEOLYTIC_TIME;
betaAmylaseTime = PROFILE_TRIGO_BETAAMYLASE_TIME;
alphaAmylaseTime = PROFILE_TRIGO_ALPHAAMYLASE_TIME;
mashoutTime = PROFILE_TRIGO_MASHOUT_TIME;
recirculationTime = PROFILE_TRIGO_RECIRCULATION_TIME;
spargeTime = PROFILE_TRIGO_SPARGE_TIME;
boilTime = PROFILE_TRIGO_BOIL_TIME;
coolingTime = PROFILE_TRIGO_COOLING_TIME;
startpointTemperature = PROFILE_TRIGO_STARTPOINT_TEMPERATURE;
betaGlucanaseTemperature = PROFILE_TRIGO_BETAGLUCANASE_TEMPERATURE;
debranchingTemperature = PROFILE_TRIGO_DEBRANCHING_TEMPERATURE;
proteolyticTemperature = PROFILE_TRIGO_PROTEOLYTIC_TEMPERATURE;
betaAmylaseTemperature = PROFILE_TRIGO_BETAAMYLASE_TEMPERATURE;
alphaAmylaseTemperature = PROFILE_TRIGO_ALPHAAMYLASE_TEMPERATURE;
mashoutTemperature = PROFILE_TRIGO_MASHOUT_TEMPERATURE;
recirculationTemperature = PROFILE_TRIGO_RECIRCULATION_TEMPERATURE;
spargeTemperature = PROFILE_TRIGO_SPARGE_TEMPERATURE;
boilTemperature = PROFILE_TRIGO_BOIL_TEMPERATURE;
coolingTemperature = PROFILE_TRIGO_COOLING_TEMPERATURE;
backToStatus(); }
}
break; repaint = true;
}
case eBeerProfileMenu_IPA: {
beerProfile = eBeerProfile_IPA;
startpointTime = PROFILE_IPA_STARTPOINT_TIME;
betaGlucanaseTime = PROFILE_IPA_BETAGLUCANASE_TIME;
debranchingTime = PROFILE_IPA_DEBRANCHING_TIME;
proteolyticTime = PROFILE_IPA_PROTEOLYTIC_TIME;
betaAmylaseTime = PROFILE_IPA_BETAAMYLASE_TIME;
alphaAmylaseTime = PROFILE_IPA_ALPHAAMYLASE_TIME;
mashoutTime = PROFILE_IPA_MASHOUT_TIME;
recirculationTime = PROFILE_IPA_RECIRCULATION_TIME;
spargeTime = PROFILE_IPA_SPARGE_TIME;
boilTime = PROFILE_IPA_BOIL_TIME;
coolingTime = PROFILE_IPA_COOLING_TIME;
startpointTemperature = PROFILE_IPA_STARTPOINT_TEMPERATURE;
betaGlucanaseTemperature = PROFILE_IPA_BETAGLUCANASE_TEMPERATURE;
debranchingTemperature = PROFILE_IPA_DEBRANCHING_TEMPERATURE;
proteolyticTemperature = PROFILE_IPA_PROTEOLYTIC_TEMPERATURE;
betaAmylaseTemperature = PROFILE_IPA_BETAAMYLASE_TEMPERATURE;
alphaAmylaseTemperature = PROFILE_IPA_ALPHAAMYLASE_TEMPERATURE;
mashoutTemperature = PROFILE_IPA_MASHOUT_TEMPERATURE;
recirculationTemperature = PROFILE_IPA_RECIRCULATION_TEMPERATURE;
spargeTemperature = PROFILE_IPA_SPARGE_TEMPERATURE;
boilTemperature = PROFILE_IPA_BOIL_TEMPERATURE;
coolingTemperature = PROFILE_IPA_COOLING_TEMPERATURE;
backToStatus(); // A basic operation for a basic stage
xPrepareForStage( boilTime, boilTemperature, PUMP_SPEED_MAX_MOSFET, eCookingStage_Boil );
break; break;
} }
case eBeerProfileMenu_Belga: { case eCookingStage_Cooling: {
beerProfile = eBeerProfile_Belga; // Make sure there is water
xWaitForAction("Coil", "Add the coil and connect it to the main water supply.");
startpointTime = PROFILE_BELGA_STARTPOINT_TIME;
betaGlucanaseTime = PROFILE_BELGA_BETAGLUCANASE_TIME;
debranchingTime = PROFILE_BELGA_DEBRANCHING_TIME;
proteolyticTime = PROFILE_BELGA_PROTEOLYTIC_TIME;
betaAmylaseTime = PROFILE_BELGA_BETAAMYLASE_TIME;
alphaAmylaseTime = PROFILE_BELGA_ALPHAAMYLASE_TIME;
mashoutTime = PROFILE_BELGA_MASHOUT_TIME;
recirculationTime = PROFILE_BELGA_RECIRCULATION_TIME;
spargeTime = PROFILE_BELGA_SPARGE_TIME;
boilTime = PROFILE_BELGA_BOIL_TIME;
coolingTime = PROFILE_BELGA_COOLING_TIME;
startpointTemperature = PROFILE_BELGA_STARTPOINT_TEMPERATURE;
betaGlucanaseTemperature = PROFILE_BELGA_BETAGLUCANASE_TEMPERATURE;
debranchingTemperature = PROFILE_BELGA_DEBRANCHING_TEMPERATURE;
proteolyticTemperature = PROFILE_BELGA_PROTEOLYTIC_TEMPERATURE;
betaAmylaseTemperature = PROFILE_BELGA_BETAAMYLASE_TEMPERATURE;
alphaAmylaseTemperature = PROFILE_BELGA_ALPHAAMYLASE_TEMPERATURE;
mashoutTemperature = PROFILE_BELGA_MASHOUT_TEMPERATURE;
recirculationTemperature = PROFILE_BELGA_RECIRCULATION_TEMPERATURE;
spargeTemperature = PROFILE_BELGA_SPARGE_TEMPERATURE;
boilTemperature = PROFILE_BELGA_BOIL_TEMPERATURE;
coolingTemperature = PROFILE_BELGA_COOLING_TEMPERATURE;
backToStatus(); repaint = true;
// A basic operation for a basic stage
xPrepareForStage( coolingTime, coolingTemperature, PUMP_SPEED_MAX_MOSFET, eCookingStage_Cooling );
break; break;
} }
case eBeerProfileMenu_Red: { case eCookingStage_Clean: {
beerProfile = eBeerProfile_Red; // Make sure there is water
xWaitForAction("Water", "Add 13 liters.");
startpointTime = PROFILE_RED_STARTPOINT_TIME;
betaGlucanaseTime = PROFILE_RED_BETAGLUCANASE_TIME;
debranchingTime = PROFILE_RED_DEBRANCHING_TIME;
proteolyticTime = PROFILE_RED_PROTEOLYTIC_TIME;
betaAmylaseTime = PROFILE_RED_BETAAMYLASE_TIME;
alphaAmylaseTime = PROFILE_RED_ALPHAAMYLASE_TIME;
mashoutTime = PROFILE_RED_MASHOUT_TIME;
recirculationTime = PROFILE_RED_RECIRCULATION_TIME;
spargeTime = PROFILE_RED_SPARGE_TIME;
boilTime = PROFILE_RED_BOIL_TIME;
coolingTime = PROFILE_RED_COOLING_TIME;
startpointTemperature = PROFILE_RED_STARTPOINT_TEMPERATURE;
betaGlucanaseTemperature = PROFILE_RED_BETAGLUCANASE_TEMPERATURE;
debranchingTemperature = PROFILE_RED_DEBRANCHING_TEMPERATURE;
proteolyticTemperature = PROFILE_RED_PROTEOLYTIC_TEMPERATURE;
betaAmylaseTemperature = PROFILE_RED_BETAAMYLASE_TEMPERATURE;
alphaAmylaseTemperature = PROFILE_RED_ALPHAAMYLASE_TEMPERATURE;
mashoutTemperature = PROFILE_RED_MASHOUT_TEMPERATURE;
recirculationTemperature = PROFILE_RED_RECIRCULATION_TEMPERATURE;
spargeTemperature = PROFILE_RED_SPARGE_TEMPERATURE;
boilTemperature = PROFILE_RED_BOIL_TEMPERATURE;
coolingTemperature = PROFILE_RED_COOLING_TEMPERATURE;
backToStatus(); // Make sure there is water
xWaitForAction("Star San HB", "Add 0.89oz/26ml.");
break; repaint = true;
}
case eBeerProfileMenu_APA: {
beerProfile = eBeerProfile_APA;
startpointTime = PROFILE_APA_STARTPOINT_TIME;
betaGlucanaseTime = PROFILE_APA_BETAGLUCANASE_TIME;
debranchingTime = PROFILE_APA_DEBRANCHING_TIME;
proteolyticTime = PROFILE_APA_PROTEOLYTIC_TIME;
betaAmylaseTime = PROFILE_APA_BETAAMYLASE_TIME;
alphaAmylaseTime = PROFILE_APA_ALPHAAMYLASE_TIME;
mashoutTime = PROFILE_APA_MASHOUT_TIME;
recirculationTime = PROFILE_APA_RECIRCULATION_TIME;
spargeTime = PROFILE_APA_SPARGE_TIME;
boilTime = PROFILE_APA_BOIL_TIME;
coolingTime = PROFILE_APA_COOLING_TIME;
startpointTemperature = PROFILE_APA_STARTPOINT_TEMPERATURE;
betaGlucanaseTemperature = PROFILE_APA_BETAGLUCANASE_TEMPERATURE;
debranchingTemperature = PROFILE_APA_DEBRANCHING_TEMPERATURE;
proteolyticTemperature = PROFILE_APA_PROTEOLYTIC_TEMPERATURE;
betaAmylaseTemperature = PROFILE_APA_BETAAMYLASE_TEMPERATURE;
alphaAmylaseTemperature = PROFILE_APA_ALPHAAMYLASE_TEMPERATURE;
mashoutTemperature = PROFILE_APA_MASHOUT_TEMPERATURE;
recirculationTemperature = PROFILE_APA_RECIRCULATION_TEMPERATURE;
spargeTemperature = PROFILE_APA_SPARGE_TEMPERATURE;
boilTemperature = PROFILE_APA_BOIL_TEMPERATURE;
coolingTemperature = PROFILE_APA_COOLING_TEMPERATURE;
backToStatus(); // A basic operation for a basic stage
xPrepareForStage( cleaningTime, cleaningTemperature, PUMP_SPEED_MAX_MOSFET, eCookingStage_Clean );
break; break;
} }
case eBeerProfileMenu_Custom: { case eCookingStage_Purge: {
beerProfile = eBeerProfile_Custom; // A basic operation for a basic stage
xPrepareForStage( 0, 0, PUMP_SPEED_MAX_MOSFET, eCookingStage_Purge );
startpointTime = PROFILE_CUSTOM_STARTPOINT_TIME;
betaGlucanaseTime = PROFILE_CUSTOM_BETAGLUCANASE_TIME;
debranchingTime = PROFILE_CUSTOM_DEBRANCHING_TIME;
proteolyticTime = PROFILE_CUSTOM_PROTEOLYTIC_TIME;
betaAmylaseTime = PROFILE_CUSTOM_BETAAMYLASE_TIME;
alphaAmylaseTime = PROFILE_CUSTOM_ALPHAAMYLASE_TIME;
mashoutTime = PROFILE_CUSTOM_MASHOUT_TIME;
recirculationTime = PROFILE_CUSTOM_RECIRCULATION_TIME;
spargeTime = PROFILE_CUSTOM_SPARGE_TIME;
boilTime = PROFILE_CUSTOM_BOIL_TIME;
coolingTime = PROFILE_CUSTOM_COOLING_TIME;
startpointTemperature = PROFILE_CUSTOM_STARTPOINT_TEMPERATURE;
betaGlucanaseTemperature = PROFILE_CUSTOM_BETAGLUCANASE_TEMPERATURE;
debranchingTemperature = PROFILE_CUSTOM_DEBRANCHING_TEMPERATURE;
proteolyticTemperature = PROFILE_CUSTOM_PROTEOLYTIC_TEMPERATURE;
betaAmylaseTemperature = PROFILE_CUSTOM_BETAAMYLASE_TEMPERATURE;
alphaAmylaseTemperature = PROFILE_CUSTOM_ALPHAAMYLASE_TEMPERATURE;
mashoutTemperature = PROFILE_CUSTOM_MASHOUT_TEMPERATURE;
recirculationTemperature = PROFILE_CUSTOM_RECIRCULATION_TEMPERATURE;
spargeTemperature = PROFILE_CUSTOM_SPARGE_TEMPERATURE;
boilTemperature = PROFILE_CUSTOM_BOIL_TEMPERATURE;
coolingTemperature = PROFILE_CUSTOM_COOLING_TEMPERATURE;
backToStatus(); xRegulatePumpSpeed();
break; break;
} }
case eBeerProfileMenu_Back: { case eCookingStage_Done: {
eMenuType = eMenuType_Main; // A basic operation for a basic stage
repaint = true; xPrepareForStage( 0, 0, PUMP_SPEED_STOP_MOSFET, eCookingStage_Done );
// reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep
//xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenuPosition, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 );
xSetupRotaryEncoder( eRotaryEncoderMode_Menu, mdMainMenu._position, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 );
break; break;
} }
default: {
}
} }
eBeerProfileMenuSelection = eBeerProfileMenu_NULL;
} }
void xStartStage( unsigned long *stageTime, int *stageTemperature, eCookingStages nextStage, bool bPurgePump, bool bSetFinalYield, bool bSetTime, bool bSetTemperature ) { void xTransitionIntoStage(eCookingStages nextStage) {
xSafeHardwarePowerOff(); // Stop anything that might be still going on // Turn off all hardware that can damage itself if the machine is not cooking
xSafeHardwarePowerOff();
if (bSetFinalYield) { // Warn the user a stage has ended
finalYield = xSetFinalYield( finalYield ); xWarnClockEnded();
// Reset global stage variables
xSetupStage( nextStage );
}
void xBasicStageOperation( int iStageTime, int iStageTemperature, int iStageTemperatureRange, eCookingStages nextStage, boolean bMaximumOfUpDown ) {
// Account for time spent at the target temperature | Input 1: range in ºC within which the target temperature is considered to be reached
#ifdef DEBUG_OFF
xCountTheTime( iStageTemperatureRange, false );
#else
xCountTheTime( iStageTemperatureRange, bMaximumOfUpDown );
#endif
if ( isTimeLeft() ) {
// Do temperature control
xRegulateTemperature( bMaximumOfUpDown );
// Do flow control
xRegulatePumpSpeed();
} else {
#ifdef DEBUG_OFF
debugPrintFunction("xBasicStageOperation");
debugPrintVar("clockCounter", clockCounter);
#endif
// Continue to the next stage, there is nothing to do, in this stage
xTransitionIntoStage( nextStage );
return;
} }
if (bSetTime) {
(*stageTime) = getTimer( clockCounter / 1000, (*stageTime) ); return;
}
void xManageMachineSystems() {
#ifdef DEBUG
Serial.print(millis());
Serial.print(",");
if (cooking) {
Serial.print("1");
} }
if (bSetTemperature) { else {
(*stageTemperature) = xSetTemperature( (*stageTemperature) ); Serial.print("0");
} }
if (bPurgePump) { Serial.print(",");
xPurgePump(); Serial.print(cookTemperature);
Serial.print(",");
if (bStatusElement) {
Serial.print("1");
}
else {
Serial.print("0");
} }
Serial.print(",");
#endif
startBrewing(); // Measure temperature, for effect
xSetupStage( nextStage ); basePT100.measure(false);
backToStatus(); upPT100.measure(false);
} downPT100.measure(true);
void xStartStageHeadless( eCookingStages nextStage, bool bPurgePump ) { // If cooking is done, return (this is a nice place to double check safety and ensure the cooking parts aren't on.
xStartStage( NULL, NULL, nextStage, bPurgePump, false, false, false ); if (!cooking) {
} xSafeHardwarePowerOff();
void xStartStageInteractive( unsigned long *stageTime, int *stageTemperature, eCookingStages nextStage ) { return;
xStartStage( stageTime, stageTemperature, nextStage, true, true, true, true ); }
}
void runStartFromStageSelection() { // Operate the machine according to the current mode
switch (eStartFromStageMenuSelection) { switch (cookingStage) {
case eStageMenu_Startpoint: { case eCookingStage_Startpoint: {
xStartStageInteractive( &startpointTime, &startpointTemperature, eCookingStage_Startpoint ); xBasicStageOperation( startpointTime, startpointTemperature, 0, eCookingStage_BetaGlucanase, false);
break; break;
} }
case eStageMenu_BetaGlucanase: { case eCookingStage_BetaGlucanase: {
xStartStageInteractive( &betaGlucanaseTime, &betaGlucanaseTemperature, eCookingStage_BetaGlucanase ); xBasicStageOperation( betaGlucanaseTime, betaGlucanaseTemperature, 3, eCookingStage_Debranching, true );
break; break;
} }
case eStageMenu_Debranching: { case eCookingStage_Debranching: {
xStartStageInteractive( &debranchingTime, &debranchingTemperature, eCookingStage_Debranching ); xBasicStageOperation( debranchingTime, debranchingTemperature, 3, eCookingStage_Proteolytic, true );
break; break;
} }
case eStageMenu_Proteolytic: { case eCookingStage_Proteolytic: {
xStartStageInteractive( &proteolyticTime, &proteolyticTemperature, eCookingStage_Proteolytic ); xBasicStageOperation( proteolyticTime, proteolyticTemperature, 3, eCookingStage_BetaAmylase, true );
break; break;
} }
case eStageMenu_BetaAmylase: { case eCookingStage_BetaAmylase: {
xStartStageInteractive( &betaAmylaseTime, &betaAmylaseTemperature, eCookingStage_BetaAmylase ); xBasicStageOperation( betaAmylaseTime, betaAmylaseTemperature, 4, eCookingStage_AlphaAmylase, true );
break; break;
} }
case eStageMenu_AlphaAmylase: { case eCookingStage_AlphaAmylase: {
xStartStageInteractive( &alphaAmylaseTime, &alphaAmylaseTemperature, eCookingStage_AlphaAmylase ); xBasicStageOperation( alphaAmylaseTime, alphaAmylaseTemperature, 2, eCookingStage_Mashout, true );
break; break;
} }
case eStageMenu_Mashout: { case eCookingStage_Mashout: {
xStartStageInteractive( &mashoutTime, &mashoutTemperature, eCookingStage_Mashout ); xBasicStageOperation( mashoutTime, mashoutTemperature, 1, eCookingStage_Recirculation, true );
break; break;
} }
case eStageMenu_Recirculation: { case eCookingStage_Recirculation: {
xStartStageInteractive( &recirculationTime, &recirculationTemperature, eCookingStage_Recirculation ); xBasicStageOperation( recirculationTime, recirculationTemperature, 1, eCookingStage_Sparge, true );
break; break;
} }
case eStageMenu_Sparge: { case eCookingStage_Sparge: {
xStartStageInteractive( &spargeTime, &spargeTemperature, eCookingStage_Sparge ); xBasicStageOperation( spargeTime, spargeTemperature, 3, eCookingStage_Boil, false );
break; break;
} }
case eStageMenu_Boil: { case eCookingStage_Boil: {
xStartStageInteractive( &boilTime, &boilTemperature, eCookingStage_Boil ); xBasicStageOperation( boilTime, boilTemperature, 2, eCookingStage_Cooling, false );
break; break;
} }
case eStageMenu_Cooling: { case eCookingStage_Cooling: {
xStartStageInteractive( &coolingTime, &coolingTemperature, eCookingStage_Cooling ); xBasicStageOperation( coolingTime, coolingTemperature, 0, eCookingStage_Done, false );
break; break;
} }
case eStageMenu_Back: { case eCookingStage_Clean: {
resetMenu( true ); xBasicStageOperation( cleaningTime, cleaningTemperature, 0, eCookingStage_Done, false );
break; break;
} }
default: { case eCookingStage_Purge: {
} iPumpSpeed = PUMP_SPEED_MAX_MOSFET;
xRegulatePumpSpeed();
break;
}
case eCookingStage_Done: {
stopBrewing(); // Update cooking state
repaint = true; // Ask for screen refresh
xWarnCookEnded(); // Warn the user that the cooking is done
break;
}
}
}
// ##################################################### Menus ###################################################################
// *************************** MENU BASE *********************************
void runMenu() {
#ifdef DEBUG_OFF
boolean debug_go = repaint;
if (debug_go) {
debugPrintFunction("runMenu");
debugPrintVar("repaint", repaint);
debugPrintVar("eMenuType", eMenuType);
debugPrintVar("rotaryEncoderVirtualPosition", rotaryEncoderVirtualPosition);
}
#endif
switch (eMenuType) {
case eMenuType_Main: {
runMenuProcessor( &mdMainMenu );
break;
}
case eMenuType_BeerProfile: {
runMenuProcessor( &mdBeerProfileMenu );
break;
}
case eMenuType_Stage: {
runMenuProcessor( &mdStageMenu );
break;
}
case eMenuType_Malt: {
runMenuProcessor( &mdMaltMenu );
break;
}
case eMenuType_Settings: {
runMenuProcessor( &mdSettingsMenu );
break;
}
case eMenuType_StartFromStage: {
runMenuProcessor( &mdStartFromStageMenu );
break;
}
}
#ifdef DEBUG_OFF
if (debug_go) {
debugPrintVar("repaint", repaint);
} }
eStartFromStageMenuSelection = eStageMenu_NULL; #endif
} }
// ************************ MENU SELECTIONS ******************************
void runMainMenuSelection() { void runMainMenuSelection() {
switch (mdMainMenu._selection) { switch (mdMainMenu._selection) {
//switch (eMainMenuSelection) { //switch (eMainMenuSelection) {
...@@ -1032,7 +994,7 @@ void runMainMenuSelection() { ...@@ -1032,7 +994,7 @@ void runMainMenuSelection() {
case eMainMenu_GO_FROM_STAGE: { case eMainMenu_GO_FROM_STAGE: {
eMenuType = eMenuType_StartFromStage; eMenuType = eMenuType_StartFromStage;
repaint = true; repaint = true;
xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eBeerProfileMenuPosition, MENU_SIZE_PROFILES_MENU - 1, 1, 1, 0 ); xSetupRotaryEncoder( eRotaryEncoderMode_Menu, mdBeerProfileMenu._position, MENU_SIZE_PROFILES_MENU - 1, 1, 1, 0 );
break; break;
} }
case eMainMenu_STOP: { case eMainMenu_STOP: {
...@@ -1048,19 +1010,19 @@ void runMainMenuSelection() { ...@@ -1048,19 +1010,19 @@ void runMainMenuSelection() {
case eMainMenu_BeerProfile: { case eMainMenu_BeerProfile: {
eMenuType = eMenuType_BeerProfile; eMenuType = eMenuType_BeerProfile;
repaint = true; repaint = true;
xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eBeerProfileMenuPosition, MENU_SIZE_PROFILES_MENU - 1, 1, 1, 0 ); xSetupRotaryEncoder( eRotaryEncoderMode_Menu, mdBeerProfileMenu._position, MENU_SIZE_PROFILES_MENU - 1, 1, 1, 0 );
break; break;
} }
case eMainMenu_Stage: { case eMainMenu_Stage: {
eMenuType = eMenuType_Stage; eMenuType = eMenuType_Stage;
repaint = true; repaint = true;
xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eStageMenuPosition, MENU_SIZE_STAGE_MENU - 1, 1, 1, 0 ); xSetupRotaryEncoder( eRotaryEncoderMode_Menu, mdStageMenu._position, MENU_SIZE_STAGE_MENU - 1, 1, 1, 0 );
break; break;
} }
case eMainMenu_Malt: { case eMainMenu_Malt: {
eMenuType = eMenuType_Malt; eMenuType = eMenuType_Malt;
repaint = true; repaint = true;
xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMaltMenuPosition, MENU_SIZE_MALT_MENU - 1, 1, 1, 0 ); xSetupRotaryEncoder( eRotaryEncoderMode_Menu, mdMaltMenu._position, MENU_SIZE_MALT_MENU - 1, 1, 1, 0 );
break; break;
} }
case eMainMenu_Hops: { case eMainMenu_Hops: {
...@@ -1078,7 +1040,7 @@ void runMainMenuSelection() { ...@@ -1078,7 +1040,7 @@ void runMainMenuSelection() {
case eMainMenu_Settings: { case eMainMenu_Settings: {
eMenuType = eMenuType_Settings; eMenuType = eMenuType_Settings;
repaint = true; repaint = true;
xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eSettingsMenuPosition, MENU_SIZE_SETTINGS_MENU - 1, 1, 1, 0 ); xSetupRotaryEncoder( eRotaryEncoderMode_Menu, mdSettingsMenu._position, MENU_SIZE_SETTINGS_MENU - 1, 1, 1, 0 );
break; break;
} }
case eMainMenu_Back: { case eMainMenu_Back: {
...@@ -1089,604 +1051,429 @@ void runMainMenuSelection() { ...@@ -1089,604 +1051,429 @@ void runMainMenuSelection() {
} }
} }
mdMainMenu._selection = eMainMenu_NULL; mdMainMenu._selection = eMainMenu_NULL;
//eMainMenuSelection = eMainMenu_NULL;
} }
void xCountTheTime( int temperatureMarginRange, boolean bMaximumOfUpDown ) {
unsigned long now = millis();
// Get current maximum sensed temperaure void runStartFromStageSelection() {
double temperatureCount = 0; switch (mdStartFromStageMenu._selection) {
if ( bMaximumOfUpDown ) { case eStageMenu_Startpoint: {
float tup = upPT100.getCurrentTemperature(); xStartStageInteractive( &startpointTime, &startpointTemperature, eCookingStage_Startpoint );
float tdown = downPT100.getCurrentTemperature(); break;
if (tup > tdown) { }
temperatureCount = tdown; case eStageMenu_BetaGlucanase: {
} xStartStageInteractive( &betaGlucanaseTime, &betaGlucanaseTemperature, eCookingStage_BetaGlucanase );
else { break;
temperatureCount = tup; }
} case eStageMenu_Debranching: {
} else { xStartStageInteractive( &debranchingTime, &debranchingTemperature, eCookingStage_Debranching );
temperatureCount = basePT100.getCurrentTemperature(); break;
}
case eStageMenu_Proteolytic: {
xStartStageInteractive( &proteolyticTime, &proteolyticTemperature, eCookingStage_Proteolytic );
break;
}
case eStageMenu_BetaAmylase: {
xStartStageInteractive( &betaAmylaseTime, &betaAmylaseTemperature, eCookingStage_BetaAmylase );
break;
}
case eStageMenu_AlphaAmylase: {
xStartStageInteractive( &alphaAmylaseTime, &alphaAmylaseTemperature, eCookingStage_AlphaAmylase );
break;
}
case eStageMenu_Mashout: {
xStartStageInteractive( &mashoutTime, &mashoutTemperature, eCookingStage_Mashout );
break;
}
case eStageMenu_Recirculation: {
xStartStageInteractive( &recirculationTime, &recirculationTemperature, eCookingStage_Recirculation );
break;
}
case eStageMenu_Sparge: {
xStartStageInteractive( &spargeTime, &spargeTemperature, eCookingStage_Sparge );
break;
}
case eStageMenu_Boil: {
xStartStageInteractive( &boilTime, &boilTemperature, eCookingStage_Boil );
break;
}
case eStageMenu_Cooling: {
xStartStageInteractive( &coolingTime, &coolingTemperature, eCookingStage_Cooling );
break;
}
case eStageMenu_Back: {
resetMenu( true );
break;
}
default: {
}
} }
mdStartFromStageMenu._selection = eStageMenu_NULL;
}
// Ignote time ticks if temperature is not within the acceptable margin for this stage void runBeerProfileSelection() {
unsigned long elapsedTime = now - clockLastUpdate; switch (mdBeerProfileMenu._selection) {
if ( temperatureCount < (cookTemperature - temperatureMarginRange) ) { case eBeerProfileMenu_Basic: {
clockIgnore += elapsedTime; beerProfile = eBeerProfile_Basic;
} startpointTime = PROFILE_BASIC_STARTPOINT_TIME;
betaGlucanaseTime = PROFILE_BASIC_BETAGLUCANASE_TIME;
// Calculate the remaining time on the clock debranchingTime = PROFILE_BASIC_DEBRANCHING_TIME;
clockCounter = cookTime * 1000 - (elapsedTime - clockIgnore); proteolyticTime = PROFILE_BASIC_PROTEOLYTIC_TIME;
betaAmylaseTime = PROFILE_BASIC_BETAAMYLASE_TIME;
// Don't let clock get bellow 0 alphaAmylaseTime = PROFILE_BASIC_ALPHAAMYLASE_TIME;
if ( clockCounter < 0 ) { mashoutTime = PROFILE_BASIC_MASHOUT_TIME;
clockCounter = 0; recirculationTime = PROFILE_BASIC_RECIRCULATION_TIME;
} spargeTime = PROFILE_BASIC_SPARGE_TIME;
boilTime = PROFILE_BASIC_BOIL_TIME;
clockLastUpdate = now; coolingTime = PROFILE_BASIC_COOLING_TIME;
startpointTemperature = PROFILE_BASIC_STARTPOINT_TEMPERATURE;
#ifdef DEBUG_OFF betaGlucanaseTemperature = PROFILE_BASIC_BETAGLUCANASE_TEMPERATURE;
debugPrintFunction("xCountTheTime"); debranchingTemperature = PROFILE_BASIC_DEBRANCHING_TEMPERATURE;
debugPrintVar("millis()", now); proteolyticTemperature = PROFILE_BASIC_PROTEOLYTIC_TEMPERATURE;
debugPrintVar("cookTime", cookTime); betaAmylaseTemperature = PROFILE_BASIC_BETAAMYLASE_TEMPERATURE;
debugPrintVar("clockStartTime", clockStartTime); alphaAmylaseTemperature = PROFILE_BASIC_ALPHAAMYLASE_TEMPERATURE;
debugPrintVar("clockIgnore", clockIgnore); mashoutTemperature = PROFILE_BASIC_MASHOUT_TEMPERATURE;
debugPrintVar("clockCounter", clockCounter); recirculationTemperature = PROFILE_BASIC_RECIRCULATION_TEMPERATURE;
#endif spargeTemperature = PROFILE_BASIC_SPARGE_TEMPERATURE;
} boilTemperature = PROFILE_BASIC_BOIL_TEMPERATURE;
coolingTemperature = PROFILE_BASIC_COOLING_TEMPERATURE;
bool isTimeLeft() {
if ( clockCounter > 0 ) { backToStatus();
return true; break;
}
case eBeerProfileMenu_Trigo: {
beerProfile = eBeerProfile_Trigo;
startpointTime = PROFILE_TRIGO_STARTPOINT_TIME;
betaGlucanaseTime = PROFILE_TRIGO_BETAGLUCANASE_TIME;
debranchingTime = PROFILE_TRIGO_DEBRANCHING_TIME;
proteolyticTime = PROFILE_TRIGO_PROTEOLYTIC_TIME;
betaAmylaseTime = PROFILE_TRIGO_BETAAMYLASE_TIME;
alphaAmylaseTime = PROFILE_TRIGO_ALPHAAMYLASE_TIME;
mashoutTime = PROFILE_TRIGO_MASHOUT_TIME;
recirculationTime = PROFILE_TRIGO_RECIRCULATION_TIME;
spargeTime = PROFILE_TRIGO_SPARGE_TIME;
boilTime = PROFILE_TRIGO_BOIL_TIME;
coolingTime = PROFILE_TRIGO_COOLING_TIME;
startpointTemperature = PROFILE_TRIGO_STARTPOINT_TEMPERATURE;
betaGlucanaseTemperature = PROFILE_TRIGO_BETAGLUCANASE_TEMPERATURE;
debranchingTemperature = PROFILE_TRIGO_DEBRANCHING_TEMPERATURE;
proteolyticTemperature = PROFILE_TRIGO_PROTEOLYTIC_TEMPERATURE;
betaAmylaseTemperature = PROFILE_TRIGO_BETAAMYLASE_TEMPERATURE;
alphaAmylaseTemperature = PROFILE_TRIGO_ALPHAAMYLASE_TEMPERATURE;
mashoutTemperature = PROFILE_TRIGO_MASHOUT_TEMPERATURE;
recirculationTemperature = PROFILE_TRIGO_RECIRCULATION_TEMPERATURE;
spargeTemperature = PROFILE_TRIGO_SPARGE_TEMPERATURE;
boilTemperature = PROFILE_TRIGO_BOIL_TEMPERATURE;
coolingTemperature = PROFILE_TRIGO_COOLING_TEMPERATURE;
backToStatus();
break;
}
case eBeerProfileMenu_IPA: {
beerProfile = eBeerProfile_IPA;
startpointTime = PROFILE_IPA_STARTPOINT_TIME;
betaGlucanaseTime = PROFILE_IPA_BETAGLUCANASE_TIME;
debranchingTime = PROFILE_IPA_DEBRANCHING_TIME;
proteolyticTime = PROFILE_IPA_PROTEOLYTIC_TIME;
betaAmylaseTime = PROFILE_IPA_BETAAMYLASE_TIME;
alphaAmylaseTime = PROFILE_IPA_ALPHAAMYLASE_TIME;
mashoutTime = PROFILE_IPA_MASHOUT_TIME;
recirculationTime = PROFILE_IPA_RECIRCULATION_TIME;
spargeTime = PROFILE_IPA_SPARGE_TIME;
boilTime = PROFILE_IPA_BOIL_TIME;
coolingTime = PROFILE_IPA_COOLING_TIME;
startpointTemperature = PROFILE_IPA_STARTPOINT_TEMPERATURE;
betaGlucanaseTemperature = PROFILE_IPA_BETAGLUCANASE_TEMPERATURE;
debranchingTemperature = PROFILE_IPA_DEBRANCHING_TEMPERATURE;
proteolyticTemperature = PROFILE_IPA_PROTEOLYTIC_TEMPERATURE;
betaAmylaseTemperature = PROFILE_IPA_BETAAMYLASE_TEMPERATURE;
alphaAmylaseTemperature = PROFILE_IPA_ALPHAAMYLASE_TEMPERATURE;
mashoutTemperature = PROFILE_IPA_MASHOUT_TEMPERATURE;
recirculationTemperature = PROFILE_IPA_RECIRCULATION_TEMPERATURE;
spargeTemperature = PROFILE_IPA_SPARGE_TEMPERATURE;
boilTemperature = PROFILE_IPA_BOIL_TEMPERATURE;
coolingTemperature = PROFILE_IPA_COOLING_TEMPERATURE;
backToStatus();
break;
}
case eBeerProfileMenu_Belga: {
beerProfile = eBeerProfile_Belga;
startpointTime = PROFILE_BELGA_STARTPOINT_TIME;
betaGlucanaseTime = PROFILE_BELGA_BETAGLUCANASE_TIME;
debranchingTime = PROFILE_BELGA_DEBRANCHING_TIME;
proteolyticTime = PROFILE_BELGA_PROTEOLYTIC_TIME;
betaAmylaseTime = PROFILE_BELGA_BETAAMYLASE_TIME;
alphaAmylaseTime = PROFILE_BELGA_ALPHAAMYLASE_TIME;
mashoutTime = PROFILE_BELGA_MASHOUT_TIME;
recirculationTime = PROFILE_BELGA_RECIRCULATION_TIME;
spargeTime = PROFILE_BELGA_SPARGE_TIME;
boilTime = PROFILE_BELGA_BOIL_TIME;
coolingTime = PROFILE_BELGA_COOLING_TIME;
startpointTemperature = PROFILE_BELGA_STARTPOINT_TEMPERATURE;
betaGlucanaseTemperature = PROFILE_BELGA_BETAGLUCANASE_TEMPERATURE;
debranchingTemperature = PROFILE_BELGA_DEBRANCHING_TEMPERATURE;
proteolyticTemperature = PROFILE_BELGA_PROTEOLYTIC_TEMPERATURE;
betaAmylaseTemperature = PROFILE_BELGA_BETAAMYLASE_TEMPERATURE;
alphaAmylaseTemperature = PROFILE_BELGA_ALPHAAMYLASE_TEMPERATURE;
mashoutTemperature = PROFILE_BELGA_MASHOUT_TEMPERATURE;
recirculationTemperature = PROFILE_BELGA_RECIRCULATION_TEMPERATURE;
spargeTemperature = PROFILE_BELGA_SPARGE_TEMPERATURE;
boilTemperature = PROFILE_BELGA_BOIL_TEMPERATURE;
coolingTemperature = PROFILE_BELGA_COOLING_TEMPERATURE;
backToStatus();
break;
}
case eBeerProfileMenu_Red: {
beerProfile = eBeerProfile_Red;
startpointTime = PROFILE_RED_STARTPOINT_TIME;
betaGlucanaseTime = PROFILE_RED_BETAGLUCANASE_TIME;
debranchingTime = PROFILE_RED_DEBRANCHING_TIME;
proteolyticTime = PROFILE_RED_PROTEOLYTIC_TIME;
betaAmylaseTime = PROFILE_RED_BETAAMYLASE_TIME;
alphaAmylaseTime = PROFILE_RED_ALPHAAMYLASE_TIME;
mashoutTime = PROFILE_RED_MASHOUT_TIME;
recirculationTime = PROFILE_RED_RECIRCULATION_TIME;
spargeTime = PROFILE_RED_SPARGE_TIME;
boilTime = PROFILE_RED_BOIL_TIME;
coolingTime = PROFILE_RED_COOLING_TIME;
startpointTemperature = PROFILE_RED_STARTPOINT_TEMPERATURE;
betaGlucanaseTemperature = PROFILE_RED_BETAGLUCANASE_TEMPERATURE;
debranchingTemperature = PROFILE_RED_DEBRANCHING_TEMPERATURE;
proteolyticTemperature = PROFILE_RED_PROTEOLYTIC_TEMPERATURE;
betaAmylaseTemperature = PROFILE_RED_BETAAMYLASE_TEMPERATURE;
alphaAmylaseTemperature = PROFILE_RED_ALPHAAMYLASE_TEMPERATURE;
mashoutTemperature = PROFILE_RED_MASHOUT_TEMPERATURE;
recirculationTemperature = PROFILE_RED_RECIRCULATION_TEMPERATURE;
spargeTemperature = PROFILE_RED_SPARGE_TEMPERATURE;
boilTemperature = PROFILE_RED_BOIL_TEMPERATURE;
coolingTemperature = PROFILE_RED_COOLING_TEMPERATURE;
backToStatus();
break;
}
case eBeerProfileMenu_APA: {
beerProfile = eBeerProfile_APA;
startpointTime = PROFILE_APA_STARTPOINT_TIME;
betaGlucanaseTime = PROFILE_APA_BETAGLUCANASE_TIME;
debranchingTime = PROFILE_APA_DEBRANCHING_TIME;
proteolyticTime = PROFILE_APA_PROTEOLYTIC_TIME;
betaAmylaseTime = PROFILE_APA_BETAAMYLASE_TIME;
alphaAmylaseTime = PROFILE_APA_ALPHAAMYLASE_TIME;
mashoutTime = PROFILE_APA_MASHOUT_TIME;
recirculationTime = PROFILE_APA_RECIRCULATION_TIME;
spargeTime = PROFILE_APA_SPARGE_TIME;
boilTime = PROFILE_APA_BOIL_TIME;
coolingTime = PROFILE_APA_COOLING_TIME;
startpointTemperature = PROFILE_APA_STARTPOINT_TEMPERATURE;
betaGlucanaseTemperature = PROFILE_APA_BETAGLUCANASE_TEMPERATURE;
debranchingTemperature = PROFILE_APA_DEBRANCHING_TEMPERATURE;
proteolyticTemperature = PROFILE_APA_PROTEOLYTIC_TEMPERATURE;
betaAmylaseTemperature = PROFILE_APA_BETAAMYLASE_TEMPERATURE;
alphaAmylaseTemperature = PROFILE_APA_ALPHAAMYLASE_TEMPERATURE;
mashoutTemperature = PROFILE_APA_MASHOUT_TEMPERATURE;
recirculationTemperature = PROFILE_APA_RECIRCULATION_TEMPERATURE;
spargeTemperature = PROFILE_APA_SPARGE_TEMPERATURE;
boilTemperature = PROFILE_APA_BOIL_TEMPERATURE;
coolingTemperature = PROFILE_APA_COOLING_TEMPERATURE;
backToStatus();
break;
}
case eBeerProfileMenu_Custom: {
beerProfile = eBeerProfile_Custom;
startpointTime = PROFILE_CUSTOM_STARTPOINT_TIME;
betaGlucanaseTime = PROFILE_CUSTOM_BETAGLUCANASE_TIME;
debranchingTime = PROFILE_CUSTOM_DEBRANCHING_TIME;
proteolyticTime = PROFILE_CUSTOM_PROTEOLYTIC_TIME;
betaAmylaseTime = PROFILE_CUSTOM_BETAAMYLASE_TIME;
alphaAmylaseTime = PROFILE_CUSTOM_ALPHAAMYLASE_TIME;
mashoutTime = PROFILE_CUSTOM_MASHOUT_TIME;
recirculationTime = PROFILE_CUSTOM_RECIRCULATION_TIME;
spargeTime = PROFILE_CUSTOM_SPARGE_TIME;
boilTime = PROFILE_CUSTOM_BOIL_TIME;
coolingTime = PROFILE_CUSTOM_COOLING_TIME;
startpointTemperature = PROFILE_CUSTOM_STARTPOINT_TEMPERATURE;
betaGlucanaseTemperature = PROFILE_CUSTOM_BETAGLUCANASE_TEMPERATURE;
debranchingTemperature = PROFILE_CUSTOM_DEBRANCHING_TEMPERATURE;
proteolyticTemperature = PROFILE_CUSTOM_PROTEOLYTIC_TEMPERATURE;
betaAmylaseTemperature = PROFILE_CUSTOM_BETAAMYLASE_TEMPERATURE;
alphaAmylaseTemperature = PROFILE_CUSTOM_ALPHAAMYLASE_TEMPERATURE;
mashoutTemperature = PROFILE_CUSTOM_MASHOUT_TEMPERATURE;
recirculationTemperature = PROFILE_CUSTOM_RECIRCULATION_TEMPERATURE;
spargeTemperature = PROFILE_CUSTOM_SPARGE_TEMPERATURE;
boilTemperature = PROFILE_CUSTOM_BOIL_TEMPERATURE;
coolingTemperature = PROFILE_CUSTOM_COOLING_TEMPERATURE;
backToStatus();
break;
}
case eBeerProfileMenu_Back: {
resetMenu( true );
break;
}
default: {}
} }
return false; mdBeerProfileMenu._selection = eBeerProfileMenu_NULL;
}
//HEATING_ELEMENT_MAX_WATTAGE / HEATING_ELEMENT_AC_FREQUENCY_HZ
double ulWattToWindowTime( double ulAppliedWatts ) {
double ulPulsesRequired = ulAppliedWatts / dWattPerPulse;
return (double)iWindowSize / 1000.0 * ulPulsesRequired * 1000.0 / HEATING_ELEMENT_AC_FREQUENCY_HZ;
} }
bool xRegulateTemperature( boolean bMaximumOfUpDown ) { void runStageSelection() {
double difference = 0; switch (mdStageMenu._selection) {
bool overTemperature = false; case eStageMenu_Startpoint: {
double wattage = 0.0; runStageSelection_Generic( &startpointTime, &startpointTemperature );
break;
float tup = upPT100.getCurrentTemperature();
float tdown = downPT100.getCurrentTemperature();
float tbase = basePT100.getCurrentTemperature();
if ( bMaximumOfUpDown ) {
if (tup > tdown) {
difference = cookTemperature - tup;
} }
else { case eStageMenu_BetaGlucanase: {
difference = cookTemperature - tdown; runStageSelection_Generic( &betaGlucanaseTime, &betaGlucanaseTemperature );
break;
} }
case eStageMenu_Debranching: {
if (tbase > cookTemperature && (tbase >= (PUMP_TEMPERATURE_MAX_OPERATION - 2.0) || difference >= 5.0)) { runStageSelection_Generic( &debranchingTime, &debranchingTemperature );
difference = cookTemperature - tbase; break;
} }
case eStageMenu_Proteolytic: {
if ( (tbase < cookTemperature) && (difference < (cookTemperature - tbase)) ) { runStageSelection_Generic( &proteolyticTime, &proteolyticTemperature );
difference = cookTemperature - tbase; break;
} }
} else { case eStageMenu_BetaAmylase: {
difference = cookTemperature - tbase; runStageSelection_Generic( &betaAmylaseTime, &betaAmylaseTemperature );
} break;
}
// Deviation between the cook temperature set and the cook temperature measured case eStageMenu_AlphaAmylase: {
if ( difference < 0.0 ) { runStageSelection_Generic( &alphaAmylaseTime, &alphaAmylaseTemperature );
difference = difference * (-1.0); break;
overTemperature = true; }
case eStageMenu_Mashout: {
runStageSelection_Generic( &mashoutTime, &mashoutTemperature );
break;
}
case eStageMenu_Recirculation: {
runStageSelection_Generic( &recirculationTime, &recirculationTemperature );
break;
}
case eStageMenu_Sparge: {
runStageSelection_Generic( &spargeTime, &spargeTemperature );
break;
}
case eStageMenu_Boil: {
runStageSelection_Generic( &boilTime, &boilTemperature );
break;
}
case eStageMenu_Cooling: {
runStageSelection_Generic( &coolingTime, &coolingTemperature );
break;
}
case eStageMenu_Back: {
resetMenu( true );
break;
}
default: {}
} }
mdStageMenu._selection = eStageMenu_NULL;
}
// Calculate applied wattage, based on the distance from the target temperature void runSettingsSelection() {
if ( overTemperature ) { switch (mdSettingsMenu._selection) {
// turn it off case eSettingsMenu_Pump: {
wattage = 0.0; // Stuff
} else { if ( xSetGenericValue( iPumpSpeed ? 0 : 1, 0, 1, "pump", "bool" ) ) {
//if(difference <= 0.1) { iPumpSpeed = PUMP_SPEED_MAX_MOSFET;
// turn it off
// wattage = 0.0;
//} else {
if (difference <= 0.5) {
// pulse lightly at 500 watt
if (cookTemperature > 99.0) {
wattage = 2000.0;
}
else {
if (cookTemperature > 70.0) {
wattage = 1000.0;
}
else {
wattage = 500.0;
}
}
} else {
if (difference <= 1.0) {
// pulse moderately at 1000 watt
if (cookTemperature > 99.0) {
wattage = 2000.0;
}
else {
wattage = 1000.0;
}
} else {
if (difference <= 3.0) {
// pulse hardly at 2000 watt
wattage = 2000.0;
} else { } else {
//pulse constantly at HEATING_ELEMENT_MAX_WATTAGE watt iPumpSpeed = PUMP_SPEED_STOP_MOSFET;
wattage = HEATING_ELEMENT_MAX_WATTAGE;
} }
analogWrite(PUMP_PIN, iPumpSpeed);
backToStatus();
break;
}
case eSettingsMenu_PT100_Element: {
backToStatus();
break;
}
case eSettingsMenu_PT100_Up: {
backToStatus();
break;
}
case eSettingsMenu_PT100_Down: {
backToStatus();
break;
} }
case eSettingsMenu_Back: {
resetMenu( true );
break;
} }
//} default: {}
}
// Update the recorded time for the begining of the window, if the previous window has passed
while ((millis() - windowStartTime) > iWindowSize) { // Check if it's time to vary the pulse width modulation and if so do it by shifting the "Relay in ON" Window
windowStartTime += iWindowSize;
}
// Apply wattage to the element at the right time
if ( ulWattToWindowTime( wattage ) > (millis() - windowStartTime) ) {
digitalWrite(HEATING_ELEMENT_OUTPUT_PIN, HIGH);
bStatusElement = true;
} else {
digitalWrite(HEATING_ELEMENT_OUTPUT_PIN, LOW);
bStatusElement = false;
} }
mdSettingsMenu._selection = eSettingsMenu_NULL;
#ifdef DEBUG_OFF
//debugPrintFunction("xRegulateTemperature");
debugPrintVar("difference", difference);
//debugPrintVar("overTemperature", overTemperature);
debugPrintVar("wattage", wattage);
//debugPrintVar("ulWattToWindowTime( wattage )", ulWattToWindowTime( wattage ) );
//debugPrintVar("millis()", millis());
//debugPrintVar("windowStartTime", windowStartTime);
//debugPrintVar("test", ulWattToWindowTime( wattage ) > (millis() - windowStartTime) );
#endif
} }
void xPurgePump() { void runMaltSelection() {
for (int i = 0; i < 2; i++) { switch (mdMaltMenu._selection) {
analogWrite(PUMP_PIN, PUMP_SPEED_MAX_MOSFET); // analogWrite values from 0 to 255 case eMaltMenu_CastleMalting_Chteau_Pilsen_2RS: {
delay(1000); backToStatus();
analogWrite(PUMP_PIN, PUMP_SPEED_STOP_MOSFET); // analogWrite values from 0 to 255 break;
delay(1500); }
case eMaltMenu_CastleMalting_Wheat_Blanc: {
backToStatus();
break;
}
case eMaltMenu_Back: {
resetMenu( true );
break;
}
default: {}
} }
mdMaltMenu._selection = eMaltMenu_NULL;
} }
bool xRegulatePumpSpeed() { // ************************ MENU HELPERS ******************************
// analogWrite(PUMP_PIN, iPumpSpeed); // analogWrite values from 0 to 255 void runMenuProcessor( MenuData *data ) {
data->_position = rotaryEncoderVirtualPosition; // Read position
if (basePT100.getCurrentTemperature() > PUMP_TEMPERATURE_MAX_OPERATION) { data->_repaint = repaint; // Request repaint
analogWrite(PUMP_PIN, PUMP_SPEED_STOP_MOSFET); // analogWrite values from 0 to 255 repaint = displayGenericMenu( &lcd, data ); // Display menu
basePT100.setPumpStatus( false ); if ( gotButtonPress( ROTARY_ENCODER_SW_PIN ) ) { // Read selection
upPT100.setPumpStatus( false ); data->_selection = data->_position;
downPT100.setPumpStatus( false );
} }
else {
analogWrite(PUMP_PIN, iPumpSpeed); // analogWrite values from 0 to 255 (data->_selectionFunction)(); // Run selection function
}
basePT100.setPumpStatus( true ); void runStageSelection_Generic( unsigned long * selectedStageTime, int *selectedStageTemperature) {
upPT100.setPumpStatus( true ); (*selectedStageTime) = getTimer( (*selectedStageTime) );
downPT100.setPumpStatus( true ); (*selectedStageTemperature) = xSetGenericValue( (*selectedStageTemperature), TEMPERATURE_MIN_VALUE, TEMPERATURE_MAX_VALUE, MENU_GLOBAL_STR_TEMPERATURE, MENU_GLOBAL_STR_CELSIUS );
} backToStatus();
} }
void xWarnClockEnded() { void xStartStageHeadless( eCookingStages nextStage, bool bPurgePump ) {
sing(MELODY_SUPER_MARIO_START, PIEZO_PIN); xStartStage( NULL, NULL, nextStage, bPurgePump, false, false, false );
} }
void xWarnCookEnded() { void xStartStageInteractive( unsigned long *stageTime, int *stageTemperature, eCookingStages nextStage ) {
sing(MELODY_UNDERWORLD_SHORT, PIEZO_PIN); xStartStage( stageTime, stageTemperature, nextStage, true, true, true, true );
} }
void xPrepareForStage( int stageTime, int stageTemperature, int stagePumpSpeed, eCookingStages stage ) { void xStartStage( unsigned long *stageTime, int *stageTemperature, eCookingStages nextStage, bool bPurgePump, bool bSetFinalYield, bool bSetTime, bool bSetTemperature ) {
#ifdef DEBUG_OFF xSafeHardwarePowerOff(); // Stop anything that might be still going on
debugPrintFunction("xPrepareForStage");
debugPrintVar("cookingStage", stage);
#endif
// Reset the clock if (bSetFinalYield) {
unsigned long now = millis(); finalYield = xSetFinalYield( finalYield );
clockStartTime = now;
clockLastUpdate = now;
clockIgnore = 0;
iPumpSpeed = stagePumpSpeed; // Set the pump speed
cookingStage = stage; // Set Stage
cookTime = stageTime; // Set the clock
cookTemperature = stageTemperature; // Set the target temperature
}
void xSetupStage(eCookingStages nextStage) {
#ifdef DEBUG_OFF
debugPrintFunction("xSetupStage");
debugPrintVar("cookingStage", nextStage);
#endif
// Operate the machine according to the current mode
switch (nextStage) {
case eCookingStage_Startpoint: {
switch (beerProfile) {
case eBeerProfile_Trigo: {
float wheatAmount = 0.05 * ((float) finalYield);
float pilsnerAmount = 0.2 * ((float) finalYield);
String say = "Cruch ";
say += String(wheatAmount);
say += String("Kg of Wheat and ");
say += String(pilsnerAmount);
say += String("Kg of Pilsner Malt into a pot.");
xWaitForAction("Malt", say);
repaint = true;
break;
}
case eBeerProfile_IPA: {
float caramelAmount = 0.013157895 * ((float) finalYield);
float wheatAmount = 0.060526316 * ((float) finalYield);
float pilsnerAmount = 0.115789474 * ((float) finalYield);
float munichAmount = 0.028947368 * ((float) finalYield);
String say = "Cruch ";
say += String(caramelAmount);
say += String("Kg of Caramel 120, ");
say += String(wheatAmount);
say += String("Kg of Wheat, ");
say += String(pilsnerAmount);
say += String("Kg of Pilsner, ");
say += String(munichAmount);
say += String("Kg of Munich into a pot.");
xWaitForAction("Malt", say);
repaint = true;
break;
}
default: {
}
}
// Make sure there is water
xWaitForAction("Water", "Make sure there is water in the machine before start cooking.");
repaint = true;
xPrepareForStage( startpointTime, startpointTemperature, PUMP_SPEED_MAX_MOSFET, eCookingStage_Startpoint );
break;
}
case eCookingStage_BetaGlucanase: {
switch (beerProfile) {
case eBeerProfile_Trigo: {
float wheatAmount = 0.05 * ((float) finalYield);
float pilsnerAmount = 0.2 * ((float) finalYield);
String say = "Put ";
say += String(wheatAmount);
say += String("Kg of Wheat and ");
say += String(pilsnerAmount);
say += String("Kg of Pilsner Malt in.");
xWaitForAction("Malt", say);
repaint = true;
break;
}
case eBeerProfile_IPA: {
float caramelAmount = 0.013157895 * ((float) finalYield);
float wheatAmount = 0.060526316 * ((float) finalYield);
float pilsnerAmount = 0.115789474 * ((float) finalYield);
float munichAmount = 0.028947368 * ((float) finalYield);
String say = "Cruch ";
say += String(caramelAmount);
say += String("Kg of Caramel 120, ");
say += String(wheatAmount);
say += String("Kg of Wheat, ");
say += String(pilsnerAmount);
say += String("Kg of Pilsner, ");
say += String(munichAmount);
say += String("Kg of Munich into a pot.");
xWaitForAction("Malt", say);
repaint = true;
break;
}
default: {}
}
xPrepareForStage( betaGlucanaseTime, betaGlucanaseTemperature, PUMP_SPEED_MAX_MOSFET, eCookingStage_BetaGlucanase );
break;
}
case eCookingStage_Debranching: {
xPrepareForStage( debranchingTime, debranchingTemperature, PUMP_SPEED_MAX_MOSFET, eCookingStage_Debranching );
break;
}
case eCookingStage_Proteolytic: {
xPrepareForStage( proteolyticTime, proteolyticTemperature, PUMP_SPEED_MAX_MOSFET, eCookingStage_Proteolytic );
break;
}
case eCookingStage_BetaAmylase: {
xPrepareForStage( betaAmylaseTime, betaAmylaseTemperature, PUMP_SPEED_MAX_MOSFET, eCookingStage_BetaAmylase );
break;
}
case eCookingStage_AlphaAmylase: {
xPrepareForStage( alphaAmylaseTime, alphaAmylaseTemperature, PUMP_SPEED_MAX_MOSFET, eCookingStage_AlphaAmylase );
break;
}
case eCookingStage_Mashout: {
xPrepareForStage( mashoutTime, mashoutTemperature, PUMP_SPEED_MAX_MOSFET, eCookingStage_Mashout );
break;
}
case eCookingStage_Recirculation: {
xWaitForAction("Sparge Water", "Start heating your sparge water.");
repaint = true;
xPrepareForStage( recirculationTime, recirculationTemperature, PUMP_SPEED_MAX_MOSFET, eCookingStage_Recirculation );
break;
}
case eCookingStage_Sparge: {
xWaitForAction("Sparge Water", "Start pouring the sparge water.");
repaint = true;
xPrepareForStage( spargeTime, spargeTemperature, PUMP_SPEED_MAX_MOSFET, eCookingStage_Sparge );
break;
}
case eCookingStage_Boil: {
switch (beerProfile) {
case eBeerProfile_Trigo: {
String say = "Get ";
float hopAmount = 0.8 * ((float) finalYield);
say += String(hopAmount);
say += String("g of Magnum 9.4\% and Styrian Golding 5\% ready.");
xWaitForAction("Hops", say);
break;
}
case eBeerProfile_IPA: {
String say = "Get ";
float hopAmount = 0.8 * ((float) finalYield);
say += String(hopAmount);
say += String("g of Chinook, Cascade and Styrian Golding ready.");
xWaitForAction("Hops", say);
break;
}
default: {
xWaitForAction("Hops", "Add the hops in the right order, at the right time.");
}
}
repaint = true;
// A basic operation for a basic stage
xPrepareForStage( boilTime, boilTemperature, PUMP_SPEED_MAX_MOSFET, eCookingStage_Boil );
break;
}
case eCookingStage_Cooling: {
// Make sure there is water
xWaitForAction("Coil", "Add the coil and connect it to the main water supply.");
repaint = true;
// A basic operation for a basic stage
xPrepareForStage( coolingTime, coolingTemperature, PUMP_SPEED_MAX_MOSFET, eCookingStage_Cooling );
break;
}
case eCookingStage_Clean: {
// Make sure there is water
xWaitForAction("Water", "Add 13 liters.");
// Make sure there is water
xWaitForAction("Star San HB", "Add 0.89oz/26ml.");
repaint = true;
// A basic operation for a basic stage
xPrepareForStage( cleaningTime, cleaningTemperature, PUMP_SPEED_MAX_MOSFET, eCookingStage_Clean );
break;
}
case eCookingStage_Purge: {
// A basic operation for a basic stage
xPrepareForStage( 0, 0, PUMP_SPEED_MAX_MOSFET, eCookingStage_Purge );
xRegulatePumpSpeed();
break;
}
case eCookingStage_Done: {
// A basic operation for a basic stage
xPrepareForStage( 0, 0, PUMP_SPEED_STOP_MOSFET, eCookingStage_Done );
break;
}
}
}
void xTransitionIntoStage(eCookingStages nextStage) {
// Turn off all hardware that can damage itself if the machine is not cooking
xSafeHardwarePowerOff();
// Warn the user a stage has ended
xWarnClockEnded();
// Reset global stage variables
xSetupStage( nextStage );
}
void xBasicStageOperation( int iStageTime, int iStageTemperature, int iStageTemperatureRange, eCookingStages nextStage, boolean bMaximumOfUpDown ) {
// Account for time spent at the target temperature | Input 1: range in ºC within which the target temperature is considered to be reached
#ifdef DEBUG_OFF
xCountTheTime( iStageTemperatureRange, false );
#else
xCountTheTime( iStageTemperatureRange, bMaximumOfUpDown );
#endif
if ( isTimeLeft() ) {
// Do temperature control
xRegulateTemperature( bMaximumOfUpDown );
// Do flow control
xRegulatePumpSpeed();
} else {
#ifdef DEBUG_OFF
debugPrintFunction("xBasicStageOperation");
debugPrintVar("clockCounter", clockCounter);
#endif
// Continue to the next stage, there is nothing to do, in this stage
xTransitionIntoStage( nextStage );
return;
}
return;
}
void xManageMachineSystems() {
#ifdef DEBUG
Serial.print(millis());
Serial.print(",");
if (cooking) {
Serial.print("1");
}
else {
Serial.print("0");
} }
Serial.print(","); if (bSetTime) {
Serial.print(cookTemperature); (*stageTime) = getTimer( clockCounter / 1000, (*stageTime) );
Serial.print(",");
if (bStatusElement) {
Serial.print("1");
} }
else { if (bSetTemperature) {
Serial.print("0"); (*stageTemperature) = xSetTemperature( (*stageTemperature) );
} }
Serial.print(","); if (bPurgePump) {
#endif xPurgePump();
// Measure temperature, for effect
basePT100.measure(false);
upPT100.measure(false);
downPT100.measure(true);
// If cooking is done, return (this is a nice place to double check safety and ensure the cooking parts aren't on.
if (!cooking) {
xSafeHardwarePowerOff();
return;
} }
// Operate the machine according to the current mode startBrewing();
switch (cookingStage) { xSetupStage( nextStage );
case eCookingStage_Startpoint: { backToStatus();
// A basic operation for a basic stage
xBasicStageOperation( startpointTime, startpointTemperature, 0, eCookingStage_BetaGlucanase, false);
break;
}
case eCookingStage_BetaGlucanase: {
// A basic operation for a basic stage
xBasicStageOperation( betaGlucanaseTime, betaGlucanaseTemperature, 3, eCookingStage_Debranching, true );
break;
}
case eCookingStage_Debranching: {
// A basic operation for a basic stage
xBasicStageOperation( debranchingTime, debranchingTemperature, 3, eCookingStage_Proteolytic, true );
break;
}
case eCookingStage_Proteolytic: {
// A basic operation for a basic stage
xBasicStageOperation( proteolyticTime, proteolyticTemperature, 3, eCookingStage_BetaAmylase, true );
break;
}
case eCookingStage_BetaAmylase: {
// A basic operation for a basic stage
xBasicStageOperation( betaAmylaseTime, betaAmylaseTemperature, 4, eCookingStage_AlphaAmylase, true );
break;
}
case eCookingStage_AlphaAmylase: {
// A basic operation for a basic stage
xBasicStageOperation( alphaAmylaseTime, alphaAmylaseTemperature, 2, eCookingStage_Mashout, true );
break;
}
case eCookingStage_Mashout: {
// A basic operation for a basic stage
xBasicStageOperation( mashoutTime, mashoutTemperature, 1, eCookingStage_Recirculation, true );
break;
}
case eCookingStage_Recirculation: {
// A basic operation for a basic stage
xBasicStageOperation( recirculationTime, recirculationTemperature, 1, eCookingStage_Sparge, true );
break;
}
case eCookingStage_Sparge: {
// A basic operation for a basic stage
xBasicStageOperation( spargeTime, spargeTemperature, 3, eCookingStage_Boil, false );
break;
}
case eCookingStage_Boil: {
// A basic operation for a basic stage
xBasicStageOperation( boilTime, boilTemperature, 2, eCookingStage_Cooling, false );
break;
}
case eCookingStage_Cooling: {
// A basic operation for a basic stage
xBasicStageOperation( coolingTime, coolingTemperature, 0, eCookingStage_Done, false );
break;
}
case eCookingStage_Clean: {
// A basic operation for a basic stage
xBasicStageOperation( cleaningTime, cleaningTemperature, 0, eCookingStage_Done, false );
break;
}
case eCookingStage_Purge: {
// A basic operation for a basic stage
//xBasicStageOperation( coolingTime, coolingTemperature, 1, eCookingStage_Done );
iPumpSpeed = PUMP_SPEED_MAX_MOSFET;
xRegulatePumpSpeed();
break;
}
case eCookingStage_Done: {
// Update cooking state
stopBrewing();
// Ask for screen refresh
repaint = true;
// Warn the user that the cooking is done
xWarnCookEnded();
break;
}
}
} }
// ##################################################### Menus ###################################################################
// #################################################### Helpers ################################################################## // #################################################### Helpers ##################################################################
...@@ -1708,7 +1495,6 @@ void resetMenu( boolean requestRepaintPaint ) { ...@@ -1708,7 +1495,6 @@ void resetMenu( boolean requestRepaintPaint ) {
} }
// reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep
//xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenuPosition, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 );
xSetupRotaryEncoder( eRotaryEncoderMode_Menu, mdMainMenu._position, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 ); xSetupRotaryEncoder( eRotaryEncoderMode_Menu, mdMainMenu._position, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 );
} }
......
...@@ -95,36 +95,45 @@ ...@@ -95,36 +95,45 @@
#define MENU_MAIN_INIT_POSITION eMainMenu_GO #define MENU_MAIN_INIT_POSITION eMainMenu_GO
#define MENU_MAIN_INIT_SELECTION eMainMenu_NULL #define MENU_MAIN_INIT_SELECTION eMainMenu_NULL
#define MENU_MAIN_INIT_REPAINT false #define MENU_MAIN_INIT_REPAINT false
#define MENU_MAIN_FUNCTION &runMainMenuSelection
#define MENU_PROFILE_TITLE "Profile Menu" #define MENU_PROFILE_TITLE "Profile Menu"
#define MENU_PROFILE_DIALOG {"", "-> Basic ", "-> Trigo ", "-> IPA ", "-> Belga ", "-> Red ", "-> APA ", "-> Custom ", "-> Back " } #define MENU_PROFILE_DIALOG {"", "-> Basic ", "-> Trigo ", "-> IPA ", "-> Belga ", "-> Red ", "-> APA ", "-> Custom ", "-> Back " }
#define MENU_PROFILE_INIT_POSITION eBeerProfileMenu_Basic #define MENU_PROFILE_INIT_POSITION eBeerProfileMenu_Basic
#define MENU_PROFILE_INIT_SELECTION eBeerProfileMenu_NULL #define MENU_PROFILE_INIT_SELECTION eBeerProfileMenu_NULL
#define MENU_PROFILE_INIT_REPAINT false #define MENU_PROFILE_INIT_REPAINT false
#define MENU_PROFILE_FUNCTION &runBeerProfileSelection
#define MENU_STAGE_TITLE "Stage Menu" #define MENU_STAGE_TITLE "Stage Menu"
#define MENU_STAGE_DIALOG {"", "-> Startpoint ", "-> BetaGlucanase", "-> Debranching ", "-> Proteolytic ", "-> Beta Amylase ", "-> Alpha Amylase", "-> Mashout ", "-> Recirculation", "-> Sparge ", "-> Boil ", "-> Cooling ", "-> Back " } #define MENU_STAGE_DIALOG {"", "-> Startpoint ", "-> BetaGlucanase", "-> Debranching ", "-> Proteolytic ", "-> Beta Amylase ", "-> Alpha Amylase", "-> Mashout ", "-> Recirculation", "-> Sparge ", "-> Boil ", "-> Cooling ", "-> Back " }
#define MENU_STAGE_INIT_POSITION eStageMenu_Startpoint #define MENU_STAGE_INIT_POSITION eStageMenu_Startpoint
#define MENU_STAGE_INIT_SELECTION eStageMenu_NULL #define MENU_STAGE_INIT_SELECTION eStageMenu_NULL
#define MENU_STAGE_INIT_REPAINT false #define MENU_STAGE_INIT_REPAINT false
#define MENU_STAGE_FUNCTION &runStageSelection
#define MENU_MALT_TITLE "Malt Menu" #define MENU_MALT_TITLE "Malt Menu"
#define MENU_MALT_DIALOG {"", "-> CM Ch. Pilsen", "-> CM Wheat Blan", "-> Back " } #define MENU_MALT_DIALOG {"", "-> CM Ch. Pilsen", "-> CM Wheat Blan", "-> Back " }
#define MENU_MALT_INIT_POSITION eMaltMenu_CastleMalting_Chteau_Pilsen_2RS #define MENU_MALT_INIT_POSITION eMaltMenu_CastleMalting_Chteau_Pilsen_2RS
#define MENU_MALT_INIT_SELECTION eMaltMenu_NULL #define MENU_MALT_INIT_SELECTION eMaltMenu_NULL
#define MENU_MALT_INIT_REPAINT false #define MENU_MALT_INIT_REPAINT false
#define MENU_MALT_FUNCTION &runMaltSelection
#define MENU_SETTINGS_TITLE "Settings Menu" #define MENU_SETTINGS_TITLE "Settings Menu"
#define MENU_SETTINGS_DIALOG {"", "-> PT100 Element", "-> PT100 Up ", "-> PT100 Down ", "-> Back " } #define MENU_SETTINGS_DIALOG {"", "-> PT100 Element", "-> PT100 Up ", "-> PT100 Down ", "-> Back " }
#define MENU_SETTINGS_INIT_POSITION eSettingsMenu_PT100_Element #define MENU_SETTINGS_INIT_POSITION eSettingsMenu_PT100_Element
#define MENU_SETTINGS_INIT_SELECTION eSettingsMenu_NULL #define MENU_SETTINGS_INIT_SELECTION eSettingsMenu_NULL
#define MENU_SETTINGS_INIT_REPAINT false #define MENU_SETTINGS_INIT_REPAINT false
#define MENU_SETTINGS_FUNCTION &runSettingsSelection
#define MENU_GLOBAL_STR_TEMPERATURE "temperature"
#define MENU_GLOBAL_STR_CELSIUS "*C"
#define MENU_START_TITLE MENU_STAGE_TITLE #define MENU_START_TITLE MENU_STAGE_TITLE
#define MENU_START_DIALOG MENU_STAGE_DIALOG #define MENU_START_DIALOG MENU_STAGE_DIALOG
#define MENU_START_INIT_POSITION MENU_STAGE_INIT_POSITION #define MENU_START_INIT_POSITION MENU_STAGE_INIT_POSITION
#define MENU_START_INIT_SELECTION MENU_STAGE_INIT_SELECTION #define MENU_START_INIT_SELECTION MENU_STAGE_INIT_SELECTION
#define MENU_START_INIT_REPAINT MENU_STAGE_INIT_REPAINT #define MENU_START_INIT_REPAINT MENU_STAGE_INIT_REPAINT
#define MENU_START_FUNCTION &runStartFromStageSelection
// ++++++++++++++++++++++++ Serial Monotor ++++++++++++++++++++++++ // ++++++++++++++++++++++++ Serial Monotor ++++++++++++++++++++++++
#define SETTING_SERIAL_MONITOR_BAUD_RATE 9600 #define SETTING_SERIAL_MONITOR_BAUD_RATE 9600
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment