diff --git a/brew.ino b/brew.ino index 88f14050a7852dad732cf178ef7ad875c4e76dcf..b5524d229f1c9941ccb93f0c709b0fe96b59336f 100644 --- a/brew.ino +++ b/brew.ino @@ -4,59 +4,59 @@ // ######################### SETTINGS ######################### // ++++++++++++++++++++++++ Heating Element Relay ++++++++++++++++++++++++ -#define HEATING_ELEMENT_DEFAULT_WINDOW_SIZE 1000 -#define HEATING_ELEMENT_OUTPUT_PIN 24 -#define HEATING_ELEMENT_MAX_HEAT_PWM_INTEGER 5 -#define HEATING_ELEMENT_MAX_HEAT_PWM_FLOAT 5.0 -#define HEATING_ELEMENT_MAX_WATTAGE 3000.0 // Minimum = 2000.0 -#define HEATING_ELEMENT_AC_FREQUENCY_HZ 50.0 +#define HEATING_ELEMENT_DEFAULT_WINDOW_SIZE 1000 +#define HEATING_ELEMENT_OUTPUT_PIN 24 +#define HEATING_ELEMENT_MAX_HEAT_PWM_INTEGER 5 +#define HEATING_ELEMENT_MAX_HEAT_PWM_FLOAT 5.0 +#define HEATING_ELEMENT_MAX_WATTAGE 3000.0 // Minimum = 2000.0 +#define HEATING_ELEMENT_AC_FREQUENCY_HZ 50.0 // ++++++++++++++++++++++++ Temperature ++++++++++++++++++++++++ -#define PT100_BASE_INPUT_PIN A4 -#define PT100_BASE_OUTPUT_PIN 30 -#define PT100_BASE_TIME_BETWEEN_READINGS 100 -#define PT100_UP_INPUT_PIN A5 -#define PT100_UP_OUTPUT_PIN 31 -#define PT100_UP_TIME_BETWEEN_READINGS 100 -#define PT100_DOWN_INPUT_PIN A6 -#define PT100_DOWN_OUTPUT_PIN 32 -#define PT100_DOWN_TIME_BETWEEN_READINGS 100 - -#define PT100_BASE_DEFAULT_ADC_VMAX 1.081 -#define PT100_BASE_DEFAULT_VS 4.87 -#define PT100_BASE_DEFAULT_R1_RESISTENCE 606.0 -#define PT100_BASE_DEFAULT_LINE_RESISTENCE 0.7 -#define PT100_BASE_DEFAULT_OPERATION_RESISTENCE 0.0 -#define PT100_UP_DEFAULT_ADC_VMAX 1.081 -#define PT100_UP_DEFAULT_VS 4.87 -#define PT100_UP_DEFAULT_R1_RESISTENCE 606.0 -#define PT100_UP_DEFAULT_LINE_RESISTENCE 0.7 -#define PT100_UP_DEFAULT_OPERATION_RESISTENCE 0.0 -#define PT100_DOWN_DEFAULT_ADC_VMAX 1.081 -#define PT100_DOWN_DEFAULT_VS 4.87 -#define PT100_DOWN_DEFAULT_R1_RESISTENCE 606.0 -#define PT100_DOWN_DEFAULT_LINE_RESISTENCE 0.7 -#define PT100_DOWN_DEFAULT_OPERATION_RESISTENCE 0.0 +#define PT100_BASE_INPUT_PIN A4 +#define PT100_BASE_OUTPUT_PIN 30 +#define PT100_BASE_TIME_BETWEEN_READINGS 100 +#define PT100_UP_INPUT_PIN A5 +#define PT100_UP_OUTPUT_PIN 31 +#define PT100_UP_TIME_BETWEEN_READINGS 100 +#define PT100_DOWN_INPUT_PIN A6 +#define PT100_DOWN_OUTPUT_PIN 32 +#define PT100_DOWN_TIME_BETWEEN_READINGS 100 + +#define PT100_BASE_DEFAULT_ADC_VMAX 1.081 +#define PT100_BASE_DEFAULT_VS 4.87 +#define PT100_BASE_DEFAULT_R1_RESISTENCE 606.0 +#define PT100_BASE_DEFAULT_LINE_RESISTENCE 0.7 +#define PT100_BASE_DEFAULT_OPERATION_RESISTENCE 0.0 +#define PT100_UP_DEFAULT_ADC_VMAX 1.081 +#define PT100_UP_DEFAULT_VS 4.87 +#define PT100_UP_DEFAULT_R1_RESISTENCE 606.0 +#define PT100_UP_DEFAULT_LINE_RESISTENCE 0.7 +#define PT100_UP_DEFAULT_OPERATION_RESISTENCE 0.0 +#define PT100_DOWN_DEFAULT_ADC_VMAX 1.081 +#define PT100_DOWN_DEFAULT_VS 4.87 +#define PT100_DOWN_DEFAULT_R1_RESISTENCE 606.0 +#define PT100_DOWN_DEFAULT_LINE_RESISTENCE 0.7 +#define PT100_DOWN_DEFAULT_OPERATION_RESISTENCE 0.0 // ++++++++++++++++++++++++ Mixer ++++++++++++++++++++++++ -//#define MIXER_PIN 12 -//#define MIXER_MAX_POSITION 255 +//#define MIXER_PIN 12 +//#define MIXER_MAX_POSITION 255 // ++++++++++++++++++++++++ Rotary Encoder ++++++++++++++++++++++++ -#define ROTARY_ENCODER_INTERRUPT_NUMBER 1 // On Mega2560 boards, interrupt 1 is on pin 3 -#define ROTARY_ENCODER_CLK_PIN 3 // Used for generating interrupts using CLK signal -#define ROTARY_ENCODER_DT_PIN 22 // Used for reading DT signal -#define ROTARY_ENCODER_SW_PIN 23 // Used for the push button switch -#define ROTARY_ENCODER_DEBOUNCE_TIME 10 // Number of miliseconds to ignore new signals a signal is received +#define ROTARY_ENCODER_INTERRUPT_NUMBER 1 // On Mega2560 boards, interrupt 1 is on pin 3 +#define ROTARY_ENCODER_CLK_PIN 3 // Used for generating interrupts using CLK signal +#define ROTARY_ENCODER_DT_PIN 22 // Used for reading DT signal +#define ROTARY_ENCODER_SW_PIN 23 // Used for the push button switch +#define ROTARY_ENCODER_DEBOUNCE_TIME 10 // Number of miliseconds to ignore new signals a signal is received // ++++++++++++++++++++++++ State Machine ++++++++++++++++++++++++ -#define SETTING_WELCOME_TIMEOUT 100 -#define SETTING_MAX_INACTIVITY_TIME 3000 -#define MENU_MAX_DEPTH 10 -#define MENU_INIT_VALUES -1,-1,-1,-1,-1,-1,-1,-1,-1,-1 -#define MENU_SIZE_MAIN_MENU 17 -#define SETTING_SERIAL_MONITOR_BAUD_RATE 9600 -#define SETTING_SERIAL_MONITOR_WELCOME_MESSAGE "Let's start Brewing!" +#define SETTING_WELCOME_TIMEOUT 100 +#define SETTING_MAX_INACTIVITY_TIME 3000 +#define MENU_MAX_DEPTH 10 +#define MENU_INIT_VALUES -1,-1,-1,-1,-1,-1,-1,-1,-1,-1 +#define MENU_SIZE_MAIN_MENU 17 +#define SETTING_SERIAL_MONITOR_BAUD_RATE 9600 +#define SETTING_SERIAL_MONITOR_WELCOME_MESSAGE "Let's start Brewing!" // ######################### LIBRARIES ######################### // ++++++++++++++++++++++++ LiquidCrystal_I2C ++++++++++++++++++++++++ @@ -64,17 +64,17 @@ #include #include -#define LCD_I2C_ADDR 0x27 // <<----- Add your address here. Find it from I2C Scanner -#define LCD_HORIZONTAL_RESOLUTION 16 -#define LCD_VERTICAL_RESOLUTION 2 -#define LCD_BACKLIGHT_PIN 3 -#define LCD_EN_PIN 2 -#define LCD_RW_PIN 1 -#define LCD_RS_PIN 0 -#define LCD_D4_PIN 4 -#define LCD_D5_PIN 5 -#define LCD_D6_PIN 6 -#define LCD_D7_PIN 7 +#define LCD_I2C_ADDR 0x27 // <<----- Add your address here. Find it from I2C Scanner +#define LCD_HORIZONTAL_RESOLUTION 16 +#define LCD_VERTICAL_RESOLUTION 2 +#define LCD_BACKLIGHT_PIN 3 +#define LCD_EN_PIN 2 +#define LCD_RW_PIN 1 +#define LCD_RS_PIN 0 +#define LCD_D4_PIN 4 +#define LCD_D5_PIN 5 +#define LCD_D6_PIN 6 +#define LCD_D7_PIN 7 // ++++++++++++++++++++++++ PT100 +++++++++++++++++++++++++++++++++ #include @@ -92,86 +92,86 @@ eSettingsMenuOptions settingsMenuOption; eCookingStages cookingStage; // ++++++++++++++++++++++++ Global Variables ++++++++++++++++++++++++ -boolean cooking; -boolean bStageFirstRun; - -int clockStartTime; -int clockCounter; -int clockIgnore; -boolean clockStart; -boolean clockEnd; - -int cookTime; -int cookTemperature; -//cook_mode_list cookMode; -//int cookMixerSpeed; -int cookHeatPWM; - -int startpointTime; -int betaGlucanaseTime; -int debranchingTime; -int proteolyticTime; -int betaAmylaseTime; -int alphaAmylaseTime; -int mashoutTime; -int recirculationTime; -int spargeTime; -int boilTime; -int coolingTime; - -int startpointTemperature; -int betaGlucanaseTemperature; -int debranchingTemperature; -int proteolyticTemperature; -int betaAmylaseTemperature; -int alphaAmylaseTemperature; -int mashoutTemperature; -int recirculationTemperature; -int spargeTemperature; -int boilTemperature; -int coolingTemperature; - -//int menuSize; -int menu_position[MENU_MAX_DEPTH] = {MENU_INIT_VALUES}; - -boolean refresh; -boolean repaint; +boolean cooking; +boolean bStageFirstRun; + +int clockStartTime; +int clockCounter; +int clockIgnore; +boolean clockStart; +boolean clockEnd; + +int cookTime; +int cookTemperature; +//cook_mode_list cookMode; +//int cookMixerSpeed; +int cookHeatPWM; + +int startpointTime; +int betaGlucanaseTime; +int debranchingTime; +int proteolyticTime; +int betaAmylaseTime; +int alphaAmylaseTime; +int mashoutTime; +int recirculationTime; +int spargeTime; +int boilTime; +int coolingTime; + +int startpointTemperature; +int betaGlucanaseTemperature; +int debranchingTemperature; +int proteolyticTemperature; +int betaAmylaseTemperature; +int alphaAmylaseTemperature; +int mashoutTemperature; +int recirculationTemperature; +int spargeTemperature; +int boilTemperature; +int coolingTemperature; + +//int menuSize; +int menu_position[MENU_MAX_DEPTH] = {MENU_INIT_VALUES}; + +boolean refresh; +boolean repaint; // ++++++++++++++++++++++++ Interrupts ++++++++++++++++++++++++ -static unsigned long lastInterruptTime; +static unsigned long lastInterruptTime; // ++++++++++++++++++++++++ Rotary Encoder ++++++++++++++++++++++++ -volatile int rotaryEncoderVirtualPosition = 0; -volatile int rotaryEncoderMaxPosition = 1; -volatile int rotaryEncoderMinPosition = 0; -volatile int rotaryEncoderSingleStep = 1; -volatile int rotaryEncoderMultiStep = 1; +volatile int rotaryEncoderVirtualPosition = 0; +volatile int rotaryEncoderMaxPosition = 1; +volatile int rotaryEncoderMinPosition = 0; +volatile int rotaryEncoderSingleStep = 1; +volatile int rotaryEncoderMultiStep = 1; // ++++++++++++++++++++++++ Heating Element Relay ++++++++++++++++++++++++ -int iWindowSize; // Time frame to operate in -unsigned long windowStartTime; -double dWattPerPulse; +int iWindowSize; // Time frame to operate in +unsigned long windowStartTime; +double dWattPerPulse; // ######################### INITIALIZE ######################### // ++++++++++++++++++++++++ Library - LiquidCrystal_I2C ++++++++++++++++++++++++ -LiquidCrystal_I2C lcd(LCD_I2C_ADDR, LCD_EN_PIN, LCD_RW_PIN, LCD_RS_PIN, LCD_D4_PIN, LCD_D5_PIN, LCD_D6_PIN, LCD_D7_PIN); +LiquidCrystal_I2C lcd(LCD_I2C_ADDR, LCD_EN_PIN, LCD_RW_PIN, LCD_RS_PIN, LCD_D4_PIN, LCD_D5_PIN, LCD_D6_PIN, LCD_D7_PIN); // +++++++++++++++++++++++ PT100 +++++++++++++++++++++++ -PT100 basePT100(PT100_BASE_OUTPUT_PIN, PT100_BASE_INPUT_PIN, PT100_BASE_TIME_BETWEEN_READINGS, PT100_BASE_DEFAULT_ADC_VMAX, PT100_BASE_DEFAULT_VS, PT100_BASE_DEFAULT_R1_RESISTENCE, PT100_BASE_DEFAULT_LINE_RESISTENCE, PT100_BASE_DEFAULT_OPERATION_RESISTENCE); -PT100 upPT100(PT100_UP_OUTPUT_PIN, PT100_UP_INPUT_PIN, PT100_UP_TIME_BETWEEN_READINGS, PT100_UP_DEFAULT_ADC_VMAX, PT100_UP_DEFAULT_VS, PT100_UP_DEFAULT_R1_RESISTENCE, PT100_UP_DEFAULT_LINE_RESISTENCE, PT100_UP_DEFAULT_OPERATION_RESISTENCE); -PT100 downPT100(PT100_DOWN_OUTPUT_PIN, PT100_DOWN_INPUT_PIN, PT100_DOWN_TIME_BETWEEN_READINGS, PT100_DOWN_DEFAULT_ADC_VMAX, PT100_DOWN_DEFAULT_VS, PT100_DOWN_DEFAULT_R1_RESISTENCE, PT100_DOWN_DEFAULT_LINE_RESISTENCE, PT100_DOWN_DEFAULT_OPERATION_RESISTENCE); +PT100 basePT100(PT100_BASE_OUTPUT_PIN, PT100_BASE_INPUT_PIN, PT100_BASE_TIME_BETWEEN_READINGS, PT100_BASE_DEFAULT_ADC_VMAX, PT100_BASE_DEFAULT_VS, PT100_BASE_DEFAULT_R1_RESISTENCE, PT100_BASE_DEFAULT_LINE_RESISTENCE, PT100_BASE_DEFAULT_OPERATION_RESISTENCE); +PT100 upPT100(PT100_UP_OUTPUT_PIN, PT100_UP_INPUT_PIN, PT100_UP_TIME_BETWEEN_READINGS, PT100_UP_DEFAULT_ADC_VMAX, PT100_UP_DEFAULT_VS, PT100_UP_DEFAULT_R1_RESISTENCE, PT100_UP_DEFAULT_LINE_RESISTENCE, PT100_UP_DEFAULT_OPERATION_RESISTENCE); +PT100 downPT100(PT100_DOWN_OUTPUT_PIN, PT100_DOWN_INPUT_PIN, PT100_DOWN_TIME_BETWEEN_READINGS, PT100_DOWN_DEFAULT_ADC_VMAX, PT100_DOWN_DEFAULT_VS, PT100_DOWN_DEFAULT_R1_RESISTENCE, PT100_DOWN_DEFAULT_LINE_RESISTENCE, PT100_DOWN_DEFAULT_OPERATION_RESISTENCE); // ######################### INTERRUPTS ######################### void xSetupRotaryEncoder( eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep ) { - if( newMode >= 0 ) rotaryEncoderMode = newMode; - if( newPosition >= 0 ) rotaryEncoderVirtualPosition = newPosition; - if( newMaxPosition >= 0 ) rotaryEncoderMaxPosition = newMaxPosition; - if( newMinPosition >= 0 ) rotaryEncoderMinPosition = newMinPosition; - if( newSingleStep >= 0 ) rotaryEncoderSingleStep = newSingleStep; - if( newMultiStep >= 0 ) rotaryEncoderMultiStep = newMultiStep; + if( newMode >= 0 ) rotaryEncoderMode = newMode; + if( newPosition >= 0 ) rotaryEncoderVirtualPosition = newPosition; + if( newMaxPosition >= 0 ) rotaryEncoderMaxPosition = newMaxPosition; + if( newMinPosition >= 0 ) rotaryEncoderMinPosition = newMinPosition; + if( newSingleStep >= 0 ) rotaryEncoderSingleStep = newSingleStep; + if( newMultiStep >= 0 ) rotaryEncoderMultiStep = newMultiStep; } -void isr () { // Interrupt service routine is executed when a HIGH to LOW transition is detected on CLK +void isr () { // Interrupt service routine is executed when a HIGH to LOW transition is detected on CLK repaint = true; refresh = true; unsigned long interruptTime = millis(); @@ -200,7 +200,7 @@ void isr () { // Interrupt service routine is executed when a HIGH to LOW tran // Input of rotary encoder controling time variables case eRotaryEncoderMode_Time: { - if (!digitalRead(ROTARY_ENCODER_DT_PIN)) { + if (!digitalRead(ROTARY_ENCODER_DT_PIN)) { if(rotaryEncoderVirtualPosition >= 60) { rotaryEncoderVirtualPosition = (rotaryEncoderVirtualPosition + rotaryEncoderMultiStep); } @@ -269,113 +269,113 @@ void isr () { // Interrupt service routine is executed when a HIGH to LOW tran // ######################### START ######################### void xSafeHardwarePowerOff() { -// analogWrite(MIXER_PIN, 0); // Turn mixer OFF for safety - digitalWrite(HEATING_ELEMENT_OUTPUT_PIN, LOW); // Turn heading element OFF for safety - //basePT100.xSafeHardwarePowerOff(); // Turn temperature sensor OFF for safety +// analogWrite(MIXER_PIN, 0); // Turn mixer OFF for safety + digitalWrite(HEATING_ELEMENT_OUTPUT_PIN, LOW); // Turn heading element OFF for safety + //basePT100.xSafeHardwarePowerOff(); // Turn temperature sensor OFF for safety } void displayWelcome() { - lcdPrint(" Let's start", " Brewing!"); // Write welcome - delay(SETTING_WELCOME_TIMEOUT); // pause for effect + lcdPrint(" Let's start", " Brewing!"); // Write welcome + delay(SETTING_WELCOME_TIMEOUT); // pause for effect } void setup() { - // ++++++++++++++++++++++++ Rotary Encoder ++++++++++++++++++++++++ - pinMode (ROTARY_ENCODER_CLK_PIN,INPUT); - pinMode (ROTARY_ENCODER_DT_PIN, INPUT); - pinMode (ROTARY_ENCODER_SW_PIN, INPUT); - attachInterrupt (ROTARY_ENCODER_INTERRUPT_NUMBER, isr, FALLING); - - // ++++++++++++++++++++++++ Heating Element Relay ++++++++++++++++++++++++ - pinMode (HEATING_ELEMENT_OUTPUT_PIN, OUTPUT); - digitalWrite (HEATING_ELEMENT_OUTPUT_PIN, LOW); - windowStartTime = millis(); - dWattPerPulse = HEATING_ELEMENT_MAX_WATTAGE / HEATING_ELEMENT_AC_FREQUENCY_HZ; - - // ++++++++++++++++++++++++ Mixer ++++++++++++++++++++++++ - // pinMode (MIXER_PIN, OUTPUT); - // analogWrite (MIXER_PIN, 0); - - // ++++++++++++++++++++++++ Temperature Sensor PT100 ++++++++++++++++++++++++ - //basePT100.setup(); + // ++++++++++++++++++++++++ Rotary Encoder ++++++++++++++++++++++++ + pinMode (ROTARY_ENCODER_CLK_PIN,INPUT); + pinMode (ROTARY_ENCODER_DT_PIN, INPUT); + pinMode (ROTARY_ENCODER_SW_PIN, INPUT); + attachInterrupt (ROTARY_ENCODER_INTERRUPT_NUMBER, isr, FALLING); + + // ++++++++++++++++++++++++ Heating Element Relay ++++++++++++++++++++++++ + pinMode (HEATING_ELEMENT_OUTPUT_PIN, OUTPUT); + digitalWrite (HEATING_ELEMENT_OUTPUT_PIN, LOW); + windowStartTime = millis(); + dWattPerPulse = HEATING_ELEMENT_MAX_WATTAGE / HEATING_ELEMENT_AC_FREQUENCY_HZ; + + // ++++++++++++++++++++++++ Mixer ++++++++++++++++++++++++ + // pinMode (MIXER_PIN, OUTPUT); + // analogWrite (MIXER_PIN, 0); + + // ++++++++++++++++++++++++ Temperature Sensor PT100 ++++++++++++++++++++++++ + //basePT100.setup(); /* - analogReference (INTERNAL1V1); // EXTERNAL && INTERNAL2V56 && INTERNAL1V1 - pinMode (PT100_OUTPUT_PIN, OUTPUT); // setup temperature sensor input pin - digitalWrite (PT100_OUTPUT_PIN, LOW); // initialize sensor off + analogReference (INTERNAL1V1); // EXTERNAL && INTERNAL2V56 && INTERNAL1V1 + pinMode (PT100_OUTPUT_PIN, OUTPUT); // setup temperature sensor input pin + digitalWrite (PT100_OUTPUT_PIN, LOW); // initialize sensor off */ - // ++++++++++++++++++++++++ Serial Monitor ++++++++++++++++++++++++ - Serial.begin(SETTING_SERIAL_MONITOR_BAUD_RATE); // setup terminal baud rate - Serial.println(SETTING_SERIAL_MONITOR_WELCOME_MESSAGE); // print a start message to the terminal - - // ++++++++++++++++++++++++ Library - LiquidCrystal_I2C ++++++++++++++++++++++++ - lcd.begin (LCD_HORIZONTAL_RESOLUTION,LCD_VERTICAL_RESOLUTION); // <<----- My LCD was 16x2 - lcd.setBacklightPin(LCD_BACKLIGHT_PIN,POSITIVE); // Setup backlight pin - lcd.setBacklight(HIGH); // Switch on the backlight - - // ######################### INITIALIZE ######################### - // ++++++++++++++++++++++++ Rotary Encoder ++++++++++++++++++++++++ - // set operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep - xSetupRotaryEncoder( eRotaryEncoderMode_Disabled, 0, 0, 0, 0, 0 ); - - // ++++++++++++++++++++++++ State Machine ++++++++++++++++++++++++ - presetsMenuOption = ePresetsMenu_Trigo; - maltMenuOption = eMaltMenu_CastleMalting_Chteau_Pilsen_2RS; - settingsMenuOption = eSettingsMenu_PT100_Element; - cookingStage = eCookingStage_Startpoint; - // ++++++++++++++++++++++++ Global Variables ++++++++++++++++++++++++ - cooking = false; + // ++++++++++++++++++++++++ Serial Monitor ++++++++++++++++++++++++ + Serial.begin (SETTING_SERIAL_MONITOR_BAUD_RATE); // setup terminal baud rate + Serial.println (SETTING_SERIAL_MONITOR_WELCOME_MESSAGE); // print a start message to the terminal + + // ++++++++++++++++++++++++ Library - LiquidCrystal_I2C ++++++++++++++++++++++++ + lcd.begin (LCD_HORIZONTAL_RESOLUTION,LCD_VERTICAL_RESOLUTION); // <<----- My LCD was 16x2 + lcd.setBacklightPin (LCD_BACKLIGHT_PIN,POSITIVE); // Setup backlight pin + lcd.setBacklight (HIGH); // Switch on the backlight + + // ######################### INITIALIZE ######################### + // ++++++++++++++++++++++++ Rotary Encoder ++++++++++++++++++++++++ + // set operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep + xSetupRotaryEncoder ( eRotaryEncoderMode_Disabled, 0, 0, 0, 0, 0 ); + + // ++++++++++++++++++++++++ State Machine ++++++++++++++++++++++++ + presetsMenuOption = ePresetsMenu_Trigo; + maltMenuOption = eMaltMenu_CastleMalting_Chteau_Pilsen_2RS; + settingsMenuOption = eSettingsMenu_PT100_Element; + cookingStage = eCookingStage_Startpoint; + // ++++++++++++++++++++++++ Global Variables ++++++++++++++++++++++++ + cooking = false; bStageFirstRun = true; - clockStartTime = 0; - clockCounter = 0; - clockIgnore = 0; - clockStart = false; - clockEnd = false; - - cookTime = 3600; - cookTemperature = 25; - //cookMode = quick_start; - //cookMixerSpeed = 120; - cookHeatPWM = 5; - - startpointTime = 120; - betaGlucanaseTime = 0; - debranchingTime = 0; - proteolyticTime = 0; - betaAmylaseTime = 3600; - alphaAmylaseTime = 1800; - mashoutTime = 300; - recirculationTime = 1200; - spargeTime = 1200; - boilTime = 5400; - coolingTime = 120; - - startpointTemperature = 45; - betaGlucanaseTemperature = 40; - debranchingTemperature = 40; - proteolyticTemperature = 50; - betaAmylaseTemperature = 60; - alphaAmylaseTemperature = 70; - mashoutTemperature = 80; - recirculationTemperature = 80; - spargeTemperature = 80; - boilTemperature = 100; - coolingTemperature = 25; - - refresh = true; - repaint = true; - - // ++++++++++++++++++++++++ Interrupts ++++++++++++++++++++++++ - lastInterruptTime = 0; - - // ++++++++++++++++++++++++ PID ++++++++++++++++++++++++ - iWindowSize = HEATING_ELEMENT_DEFAULT_WINDOW_SIZE; // Time frame to operate in + clockStartTime = 0; + clockCounter = 0; + clockIgnore = 0; + clockStart = false; + clockEnd = false; + + cookTime = 3600; + cookTemperature = 25; + //cookMode = quick_start; + //cookMixerSpeed = 120; + cookHeatPWM = 5; + + startpointTime = 120; + betaGlucanaseTime = 0; + debranchingTime = 0; + proteolyticTime = 0; + betaAmylaseTime = 3600; + alphaAmylaseTime = 1800; + mashoutTime = 300; + recirculationTime = 1200; + spargeTime = 1200; + boilTime = 5400; + coolingTime = 120; + + startpointTemperature = 45; + betaGlucanaseTemperature = 40; + debranchingTemperature = 40; + proteolyticTemperature = 50; + betaAmylaseTemperature = 60; + alphaAmylaseTemperature = 70; + mashoutTemperature = 80; + recirculationTemperature = 80; + spargeTemperature = 80; + boilTemperature = 100; + coolingTemperature = 25; + + refresh = true; + repaint = true; + + // ++++++++++++++++++++++++ Interrupts ++++++++++++++++++++++++ + lastInterruptTime = 0; + + // ++++++++++++++++++++++++ PID ++++++++++++++++++++++++ + iWindowSize = HEATING_ELEMENT_DEFAULT_WINDOW_SIZE; // Time frame to operate in // ######################### Code - Run Once ######################### - xSafeHardwarePowerOff(); - displayWelcome(); - - xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_GO, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); + xSafeHardwarePowerOff (); + displayWelcome (); + + xSetupRotaryEncoder ( eRotaryEncoderMode_Menu, eMainMenu_GO, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); } // ######################### START ######################### @@ -383,7 +383,7 @@ void setup() { void loop() { unsigned long inactivityTime = millis() - lastInterruptTime; - if(inactivityTime > SETTING_MAX_INACTIVITY_TIME) { // Inactivity check + if(inactivityTime > SETTING_MAX_INACTIVITY_TIME) { // Inactivity check if(refresh) { repaint = true; refresh = false; @@ -398,32 +398,32 @@ void loop() { } void xPaintStatusTemplate() { - // Clear LCD - lcd.clear(); + // Clear LCD + lcd.clear(); - // Position the cursor at the begining of where the temperature template goes onto the screen - lcd.home(); + // Position the cursor at the begining of where the temperature template goes onto the screen + lcd.home(); - // Print the target and measured temperature template - if(cooking) { - lcd.print("ON : 000*C/000*C"); - } - else { - lcd.print("OFF: 000*C/000*C"); - } + // Print the target and measured temperature template + if(cooking) { + lcd.print("ON : 000*C/000*C"); + } + else { + lcd.print("OFF: 000*C/000*C"); + } - // Position the cursor at the begining of where the mode and time template goes onto the screen - lcd.setCursor (0,LCD_VERTICAL_RESOLUTION-1); + // Position the cursor at the begining of where the mode and time template goes onto the screen + lcd.setCursor (0,LCD_VERTICAL_RESOLUTION-1); - lcd.print("**** 00:00"); + lcd.print("**** 00:00"); } void displayStatus() { // Check whether a template repaint is required if(repaint) { - // Repaint the LCD template - xPaintStatusTemplate(); + // Repaint the LCD template + xPaintStatusTemplate(); // Reset the repaint flag after the repaint has been done repaint = false; @@ -487,9 +487,9 @@ void displayMainMenu() { MainMenu_GO(); menu_position[0] = -1; - - // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep - xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_GO, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); + + // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep + xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_GO, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); break; } @@ -497,9 +497,9 @@ void displayMainMenu() { MainMenu_Presets(); menu_position[0] = -1; - - // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep - xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_Presets, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); + + // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep + xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_Presets, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); break; } @@ -507,9 +507,9 @@ void displayMainMenu() { MainMenu_Malt(); menu_position[0] = -1; - - // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep - xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_Malt, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); + + // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep + xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_Malt, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); break; } @@ -517,9 +517,9 @@ void displayMainMenu() { MainMenu_Startpoint(); menu_position[0] = -1; - - // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep - xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_Startpoint, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); + + // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep + xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_Startpoint, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); break; } @@ -527,9 +527,9 @@ void displayMainMenu() { MainMenu_BetaGlucanase(); menu_position[0] = -1; - - // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep - xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_BetaGlucanase, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); + + // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep + xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_BetaGlucanase, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); break; } @@ -537,9 +537,9 @@ void displayMainMenu() { MainMenu_Debranching(); menu_position[0] = -1; - - // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep - xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_Settings, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); + + // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep + xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_Settings, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); break; } @@ -547,9 +547,9 @@ void displayMainMenu() { MainMenu_Proteolytic(); menu_position[0] = -1; - - // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep - xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_Proteolytic, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); + + // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep + xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_Proteolytic, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); break; } @@ -557,9 +557,9 @@ void displayMainMenu() { MainMenu_BetaAmylase(); menu_position[0] = -1; - - // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep - xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_BetaAmylase, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); + + // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep + xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_BetaAmylase, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); break; } @@ -567,9 +567,9 @@ void displayMainMenu() { MainMenu_AlphaAmylase(); menu_position[0] = -1; - - // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep - xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_AlphaAmylase, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); + + // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep + xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_AlphaAmylase, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); break; } @@ -577,9 +577,9 @@ void displayMainMenu() { MainMenu_Mashout(); menu_position[0] = -1; - - // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep - xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_Mashout, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); + + // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep + xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_Mashout, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); break; } @@ -587,9 +587,9 @@ void displayMainMenu() { MainMenu_Recirculation(); menu_position[0] = -1; - - // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep - xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_Recirculation, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); + + // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep + xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_Recirculation, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); break; } @@ -597,9 +597,9 @@ void displayMainMenu() { MainMenu_Sparge(); menu_position[0] = -1; - - // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep - xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_Sparge, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); + + // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep + xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_Sparge, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); break; } @@ -607,9 +607,9 @@ void displayMainMenu() { MainMenu_Boil(); menu_position[0] = -1; - - // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep - xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_Boil, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); + + // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep + xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_Boil, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); break; } @@ -617,9 +617,9 @@ void displayMainMenu() { MainMenu_Hops(); menu_position[0] = -1; - - // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep - xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_Hops, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); + + // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep + xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_Hops, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); break; } @@ -627,9 +627,9 @@ void displayMainMenu() { MainMenu_Cooling(); menu_position[0] = -1; - - // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep - xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_Cooling, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); + + // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep + xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_Cooling, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); break; } @@ -749,17 +749,17 @@ void displayMainMenu() { } default: { // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep - xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_GO, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); + xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenu_GO, MENU_SIZE_MAIN_MENU - 1, 0, 1, 1 ); } } repaint = false; } - if ((digitalRead(ROTARY_ENCODER_SW_PIN))) { // check if pushbutton is pressed + if ((digitalRead(ROTARY_ENCODER_SW_PIN))) { // check if pushbutton is pressed menu_position[0] = rotaryEncoderVirtualPosition; - while (digitalRead(ROTARY_ENCODER_SW_PIN)) {} // wait til switch is released - delay(10); // debounce + while (digitalRead(ROTARY_ENCODER_SW_PIN)) {} // wait til switch is released + delay(10); // debounce break; } } @@ -767,7 +767,7 @@ void displayMainMenu() { } void MainMenu_GO() { - startBrewing(); + startBrewing(); backToStatus(); } @@ -775,91 +775,91 @@ void MainMenu_GO() { void MainMenu_Presets() { backToStatus(); - + } void MainMenu_Malt() { backToStatus(); - + } void MainMenu_Startpoint() { - startpointTime = getTimer( startpointTime ); - - startpointTemperature = xSetGenericValue( startpointTemperature, 0, 120, "temperature", "*C" ); + startpointTime = getTimer( startpointTime ); + + startpointTemperature = xSetGenericValue( startpointTemperature, 0, 120, "temperature", "*C" ); backToStatus(); } void MainMenu_BetaGlucanase() { - betaGlucanaseTime = getTimer( betaGlucanaseTime ); - - betaGlucanaseTemperature = xSetGenericValue( betaGlucanaseTemperature, 0, 120, "temperature", "*C" ); + betaGlucanaseTime = getTimer( betaGlucanaseTime ); + + betaGlucanaseTemperature = xSetGenericValue( betaGlucanaseTemperature, 0, 120, "temperature", "*C" ); backToStatus(); } void MainMenu_Debranching() { - debranchingTime = getTimer( debranchingTime ); - - debranchingTemperature = xSetGenericValue( debranchingTemperature, 0, 120, "temperature", "*C" ); + debranchingTime = getTimer( debranchingTime ); + + debranchingTemperature = xSetGenericValue( debranchingTemperature, 0, 120, "temperature", "*C" ); backToStatus(); } void MainMenu_Proteolytic() { - proteolyticTime = getTimer( proteolyticTime ); - - proteolyticTemperature = xSetGenericValue( proteolyticTemperature, 0, 120, "temperature", "*C" ); + proteolyticTime = getTimer( proteolyticTime ); + + proteolyticTemperature = xSetGenericValue( proteolyticTemperature, 0, 120, "temperature", "*C" ); backToStatus(); } void MainMenu_BetaAmylase() { - betaAmylaseTime = getTimer( betaAmylaseTime ); - - betaAmylaseTemperature = xSetGenericValue( betaAmylaseTemperature, 0, 120, "temperature", "*C" ); + betaAmylaseTime = getTimer( betaAmylaseTime ); + + betaAmylaseTemperature = xSetGenericValue( betaAmylaseTemperature, 0, 120, "temperature", "*C" ); backToStatus(); } void MainMenu_AlphaAmylase() { - alphaAmylaseTime = getTimer( alphaAmylaseTime ); - - alphaAmylaseTemperature = xSetGenericValue( alphaAmylaseTemperature, 0, 120, "temperature", "*C" ); + alphaAmylaseTime = getTimer( alphaAmylaseTime ); + + alphaAmylaseTemperature = xSetGenericValue( alphaAmylaseTemperature, 0, 120, "temperature", "*C" ); backToStatus(); } void MainMenu_Mashout() { - mashoutTime = getTimer( mashoutTime ); - - mashoutTemperature = xSetGenericValue( mashoutTemperature, 0, 120, "temperature", "*C" ); + mashoutTime = getTimer( mashoutTime ); + + mashoutTemperature = xSetGenericValue( mashoutTemperature, 0, 120, "temperature", "*C" ); backToStatus(); } void MainMenu_Recirculation() { - recirculationTime = getTimer( recirculationTime ); - - recirculationTemperature = xSetGenericValue( recirculationTemperature, 0, 120, "temperature", "*C" ); + recirculationTime = getTimer( recirculationTime ); + + recirculationTemperature = xSetGenericValue( recirculationTemperature, 0, 120, "temperature", "*C" ); backToStatus(); } void MainMenu_Sparge() { - spargeTime = getTimer( spargeTime ); - - spargeTemperature = xSetGenericValue( spargeTemperature, 0, 120, "temperature", "*C" ); + spargeTime = getTimer( spargeTime ); + + spargeTemperature = xSetGenericValue( spargeTemperature, 0, 120, "temperature", "*C" ); backToStatus(); } void MainMenu_Boil() { - boilTime = getTimer( boilTime ); - - boilTemperature = xSetGenericValue( boilTemperature, 0, 120, "temperature", "*C" ); + boilTime = getTimer( boilTime ); + + boilTemperature = xSetGenericValue( boilTemperature, 0, 120, "temperature", "*C" ); backToStatus(); } @@ -867,13 +867,13 @@ void MainMenu_Boil() { void MainMenu_Hops() { backToStatus(); - + } void MainMenu_Cooling() { - coolingTime = getTimer( coolingTime ); - - coolingTemperature = xSetGenericValue( coolingTemperature, 0, 120, "temperature", "*C" ); + coolingTime = getTimer( coolingTime ); + + coolingTemperature = xSetGenericValue( coolingTemperature, 0, 120, "temperature", "*C" ); backToStatus(); } @@ -889,78 +889,78 @@ void MainMenu_Back() { } void xCountTheTime( int temperatureRange ) { - // Check if the machine is in the right temperature range, for the current mode, - if(!(basePT100.getCurrentTemperature() > (cookTemperature - temperatureRange) && basePT100.getCurrentTemperature() < (cookTemperature + temperatureRange))) { - clockIgnore += millis() - clockStartTime - clockCounter; - } - - // Calculate the remaining time on the clock - clockCounter = cookTime - ((millis() - clockStartTime - clockIgnore) / 1000); + // Check if the machine is in the right temperature range, for the current mode, + if(!(basePT100.getCurrentTemperature() > (cookTemperature - temperatureRange) && basePT100.getCurrentTemperature() < (cookTemperature + temperatureRange))) { + clockIgnore += millis() - clockStartTime - clockCounter; + } + + // Calculate the remaining time on the clock + clockCounter = cookTime - ((millis() - clockStartTime - clockIgnore) / 1000); } bool isTimeLeft() { - if( clockCounter >= cookTime ) { - return false; - } - return true; + if( clockCounter >= cookTime ) { + return false; + } + return true; } double ulWattToWindowTime( double ulAppliedWatts ) { double ulPulsesRequired = ulAppliedWatts / dWattPerPulse; - return (double)iWindowSize / 1000.0 * ulPulsesRequired; + return (double)iWindowSize / 1000.0 * ulPulsesRequired; } bool xRegulateTemperature() { - double difference = basePT100.getCurrentTemperature() - cookTemperature; - bool overTemperature = false; - double wattage = 0.0; - - // Deviation between the cook temperature set and the cook temperature measured - if( difference < 0.0 ) { - difference = difference * (-1.0); - overTemperature = true; - } - - // Calculate applied wattage, based on the distance from the target temperature - if( overTemperature ) { - // turn it off - wattage = 0.0; - } else { - if(difference <= 1) { - // turn it off - wattage = 0.0; - } else { - if(difference <= 3) { - // pulse lightly at 500 watt - wattage = 500.0; - } else { - if(difference <= 6) { - // pulse moderately at 1000 watt - wattage = 1000.0; - } else { - if(difference <= 9) { - // pulse hardly at 2000 watt - wattage = 2000.0; - } else { - //pulse constantly at HEATING_ELEMENT_MAX_WATTAGE watt - wattage = HEATING_ELEMENT_MAX_WATTAGE; - } - } - } - } - } - - // Update the recorded time for the begining of the window, if the previous window has passed + double difference = basePT100.getCurrentTemperature() - cookTemperature; + bool overTemperature = false; + double wattage = 0.0; + + // Deviation between the cook temperature set and the cook temperature measured + if( difference < 0.0 ) { + difference = difference * (-1.0); + overTemperature = true; + } + + // Calculate applied wattage, based on the distance from the target temperature + if( overTemperature ) { + // turn it off + wattage = 0.0; + } else { + if(difference <= 1) { + // turn it off + wattage = 0.0; + } else { + if(difference <= 3) { + // pulse lightly at 500 watt + wattage = 500.0; + } else { + if(difference <= 6) { + // pulse moderately at 1000 watt + wattage = 1000.0; + } else { + if(difference <= 9) { + // pulse hardly at 2000 watt + wattage = 2000.0; + } else { + //pulse constantly at HEATING_ELEMENT_MAX_WATTAGE watt + wattage = HEATING_ELEMENT_MAX_WATTAGE; + } + } + } + } + } + + // 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); - } else { - digitalWrite(HEATING_ELEMENT_OUTPUT_PIN,LOW); - } + + // Apply wattage to the element at the right time + if( ulWattToWindowTime( wattage ) > (millis() - windowStartTime)) { + digitalWrite(HEATING_ELEMENT_OUTPUT_PIN,HIGH); + } else { + digitalWrite(HEATING_ELEMENT_OUTPUT_PIN,LOW); + } } void xWarnClockEnded() { @@ -968,69 +968,69 @@ void xWarnClockEnded() { } void xStageFirstRun( int stageTime, int stageTemperature ) { - // Set the clock - cookTime = stageTime; - - // Set the target temperature - cookTemperature = stageTemperature; - - // Reset the clock - clockStartTime = millis(); - clockIgnore = 0; + // Set the clock + cookTime = stageTime; + + // Set the target temperature + cookTemperature = stageTemperature; + + // Reset the clock + clockStartTime = millis(); + clockIgnore = 0; } void xTransitionIntoStage_GlobalVariables(eCookingStages nextStage) { - // Reset global stage variables - bStageFirstRun = true; - cookingStage = nextStage; + // Reset global stage variables + bStageFirstRun = true; + cookingStage = nextStage; } 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 - xTransitionIntoStage_GlobalVariables( 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 + xTransitionIntoStage_GlobalVariables( nextStage ); } void xBasicStageOperation( int iStageTime, int iStageTemperature, int iStageTemperatureRange, eCookingStages nextStage ) { - if(bStageFirstRun) { - // Don't run this again - bStageFirstRun = false; - - // When the stage should be skipped - if( iStageTime == 0) { - // Continue to the next stage - xTransitionIntoStage_GlobalVariables( nextStage ); - - // There is nothing to do, in this stage - return; - } else { - // Set the clock, target temperature and Reset the clock - xStageFirstRun( iStageTime, iStageTemperature ); - } - } else { - // Account for time spent at the target temperature | Input 1: range in ºC within which the target temperature is considered to be reached - xCountTheTime( iStageTemperatureRange ); - - if( isTimeLeft() ) { - // Do temperature control - xRegulateTemperature(); - - } else { - // Continue to the next stage - xTransitionIntoStage( nextStage ); - - // There is nothing to do, in this stage - return; - } - } - // There is nothing to do, in this iteration - return; + if(bStageFirstRun) { + // Don't run this again + bStageFirstRun = false; + + // When the stage should be skipped + if( iStageTime == 0) { + // Continue to the next stage + xTransitionIntoStage_GlobalVariables( nextStage ); + + // There is nothing to do, in this stage + return; + } else { + // Set the clock, target temperature and Reset the clock + xStageFirstRun( iStageTime, iStageTemperature ); + } + } else { + // Account for time spent at the target temperature | Input 1: range in ºC within which the target temperature is considered to be reached + xCountTheTime( iStageTemperatureRange ); + + if( isTimeLeft() ) { + // Do temperature control + xRegulateTemperature(); + + } else { + // Continue to the next stage + xTransitionIntoStage( nextStage ); + + // There is nothing to do, in this stage + return; + } + } + // There is nothing to do, in this iteration + return; } void xWarnCookEnded() { @@ -1041,103 +1041,103 @@ void operateMachine() { // Measure temperature, for effect basePT100.measure(); - upPT100.measure(); - downPT100.measure(); + upPT100.measure(); + downPT100.measure(); // 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(); - + xSafeHardwarePowerOff(); + return; } - - // Operate the machine according to the current mode - switch(cookingStage) { - case eCookingStage_Startpoint: { - // A basic operation for a basic stage - xBasicStageOperation( startpointTime, startpointTemperature, 1, eCookingStage_BetaGlucanase ); - - // There is nothing to do, in this iteration - break; - } - case eCookingStage_BetaGlucanase: { - // A basic operation for a basic stage - xBasicStageOperation( betaGlucanaseTime, betaGlucanaseTemperature, 1, eCookingStage_Debranching ); - - // There is nothing to do, in this iteration - break; - } - case eCookingStage_Debranching: { - // A basic operation for a basic stage - xBasicStageOperation( debranchingTime, debranchingTemperature, 1, eCookingStage_Proteolytic ); - - // There is nothing to do, in this iteration - break; - } - case eCookingStage_Proteolytic: { - // A basic operation for a basic stage - xBasicStageOperation( proteolyticTime, proteolyticTemperature, 1, eCookingStage_BetaAmylase ); - - // There is nothing to do, in this iteration - break; - } - case eCookingStage_BetaAmylase: { - // A basic operation for a basic stage - xBasicStageOperation( betaAmylaseTime, betaAmylaseTemperature, 1, eCookingStage_AlphaAmylase ); - - // There is nothing to do, in this iteration - break; - } - case eCookingStage_AlphaAmylase: { - // A basic operation for a basic stage - xBasicStageOperation( alphaAmylaseTime, alphaAmylaseTemperature, 1, eCookingStage_Mashout ); - - // There is nothing to do, in this iteration - break; - } - case eCookingStage_Mashout: { - // A basic operation for a basic stage - xBasicStageOperation( mashoutTime, mashoutTemperature, 1, eCookingStage_Recirculation ); - - // There is nothing to do, in this iteration - break; - } - case eCookingStage_Recirculation: { - // A basic operation for a basic stage - xBasicStageOperation( recirculationTime, recirculationTemperature, 1, eCookingStage_Sparge ); - - // There is nothing to do, in this iteration - break; - } - case eCookingStage_Sparge: { - // A basic operation for a basic stage - xBasicStageOperation( spargeTime, spargeTemperature, 1, eCookingStage_Boil ); - - // There is nothing to do, in this iteration - break; - } - case eCookingStage_Boil: { - // A basic operation for a basic stage - xBasicStageOperation( boilTime, boilTemperature, 1, eCookingStage_Cooling ); - - // There is nothing to do, in this iteration - break; - } - case eCookingStage_Cooling: { - // A basic operation for a basic stage - xBasicStageOperation( coolingTime, coolingTemperature, 1, eCookingStage_Done ); - - // There is nothing to do, in this iteration - break; - } - default : { - // Update state - cooking = false; - - // Warn the user that the cooking is done - xWarnCookEnded(); - } - } + + // Operate the machine according to the current mode + switch(cookingStage) { + case eCookingStage_Startpoint: { + // A basic operation for a basic stage + xBasicStageOperation( startpointTime, startpointTemperature, 1, eCookingStage_BetaGlucanase ); + + // There is nothing to do, in this iteration + break; + } + case eCookingStage_BetaGlucanase: { + // A basic operation for a basic stage + xBasicStageOperation( betaGlucanaseTime, betaGlucanaseTemperature, 1, eCookingStage_Debranching ); + + // There is nothing to do, in this iteration + break; + } + case eCookingStage_Debranching: { + // A basic operation for a basic stage + xBasicStageOperation( debranchingTime, debranchingTemperature, 1, eCookingStage_Proteolytic ); + + // There is nothing to do, in this iteration + break; + } + case eCookingStage_Proteolytic: { + // A basic operation for a basic stage + xBasicStageOperation( proteolyticTime, proteolyticTemperature, 1, eCookingStage_BetaAmylase ); + + // There is nothing to do, in this iteration + break; + } + case eCookingStage_BetaAmylase: { + // A basic operation for a basic stage + xBasicStageOperation( betaAmylaseTime, betaAmylaseTemperature, 1, eCookingStage_AlphaAmylase ); + + // There is nothing to do, in this iteration + break; + } + case eCookingStage_AlphaAmylase: { + // A basic operation for a basic stage + xBasicStageOperation( alphaAmylaseTime, alphaAmylaseTemperature, 1, eCookingStage_Mashout ); + + // There is nothing to do, in this iteration + break; + } + case eCookingStage_Mashout: { + // A basic operation for a basic stage + xBasicStageOperation( mashoutTime, mashoutTemperature, 1, eCookingStage_Recirculation ); + + // There is nothing to do, in this iteration + break; + } + case eCookingStage_Recirculation: { + // A basic operation for a basic stage + xBasicStageOperation( recirculationTime, recirculationTemperature, 1, eCookingStage_Sparge ); + + // There is nothing to do, in this iteration + break; + } + case eCookingStage_Sparge: { + // A basic operation for a basic stage + xBasicStageOperation( spargeTime, spargeTemperature, 1, eCookingStage_Boil ); + + // There is nothing to do, in this iteration + break; + } + case eCookingStage_Boil: { + // A basic operation for a basic stage + xBasicStageOperation( boilTime, boilTemperature, 1, eCookingStage_Cooling ); + + // There is nothing to do, in this iteration + break; + } + case eCookingStage_Cooling: { + // A basic operation for a basic stage + xBasicStageOperation( coolingTime, coolingTemperature, 1, eCookingStage_Done ); + + // There is nothing to do, in this iteration + break; + } + default : { + // Update state + cooking = false; + + // Warn the user that the cooking is done + xWarnCookEnded(); + } + } } // #################################################### Helpers ################################################################## @@ -1157,8 +1157,8 @@ void backToStatus() { // #################################################### Set Variables ################################################################## int getTimer(int init) { - // set operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep - xSetupRotaryEncoder( eRotaryEncoderMode_Time, init, 7200, 0, 1, 30 ); + // set operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep + xSetupRotaryEncoder( eRotaryEncoderMode_Time, init, 7200, 0, 1, 30 ); // initialize variables int rotaryEncoderPreviousPosition = 0; @@ -1174,19 +1174,19 @@ int getTimer(int init) { while(true) { // Check if pushbutton is pressed - if ((digitalRead(ROTARY_ENCODER_SW_PIN))) { + if ((digitalRead(ROTARY_ENCODER_SW_PIN))) { // Wait until switch is released - while (digitalRead(ROTARY_ENCODER_SW_PIN)) {} + while (digitalRead(ROTARY_ENCODER_SW_PIN)) {} - // debounce - delay(10); + // debounce + delay(10); - // Job is done, break the circle + // Job is done, break the circle break; } else { - // Don't forget to keep an eye on the cooking - operateMachine(); - } + // Don't forget to keep an eye on the cooking + operateMachine(); + } // display current timer if (rotaryEncoderVirtualPosition != rotaryEncoderPreviousPosition) { @@ -1229,19 +1229,19 @@ int getTemperature(int init) { while(true) { // Check if pushbutton is pressed - if ((digitalRead(ROTARY_ENCODER_SW_PIN))) { + if ((digitalRead(ROTARY_ENCODER_SW_PIN))) { // Wait until switch is released - while (digitalRead(ROTARY_ENCODER_SW_PIN)) {} + while (digitalRead(ROTARY_ENCODER_SW_PIN)) {} - // debounce - delay(10); + // debounce + delay(10); - // Job is done, break the circle + // Job is done, break the circle break; } else { - // Don't forget to keep an eye on the cooking - operateMachine(); - } + // Don't forget to keep an eye on the cooking + operateMachine(); + } // display current timer if (rotaryEncoderVirtualPosition != rotaryEncoderPreviousPosition) { @@ -1266,9 +1266,9 @@ int getTemperature(int init) { return rotaryEncoderVirtualPosition; } -int xSetGenericValue(int init, int min, int max, char *valueName, char *unit) { - // set operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep - xSetupRotaryEncoder( eRotaryEncoderMode_Generic, init, max, min, 1, 5 ); +int xSetGenericValue(int init, int min, int max, char *valueName, char *unit) { + // set operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep + xSetupRotaryEncoder( eRotaryEncoderMode_Generic, init, max, min, 1, 5 ); // initialize variables int rotaryEncoderPreviousPosition = 0; @@ -1280,7 +1280,7 @@ int xSetGenericValue(int init, int min, int max, char *valueName, char *unit) { lcd.print( valueName ); lcd.setCursor ( 0 , LCD_VERTICAL_RESOLUTION - 1 ); lcd.print( " 0 " ); - lcd.print( unit ); + lcd.print( unit ); rotaryEncoderMaxPosition = TEMPERATURE_SETTING_MAX_VALUE; @@ -1288,17 +1288,17 @@ int xSetGenericValue(int init, int min, int max, char *valueName, char *unit) { // Check if pushbutton is pressed if ( digitalRead(ROTARY_ENCODER_SW_PIN) ) { // Wait until switch is released - while ( digitalRead(ROTARY_ENCODER_SW_PIN) ) {} + while ( digitalRead(ROTARY_ENCODER_SW_PIN) ) {} - // debounce - delay( 10 ); + // debounce + delay( 10 ); - // Job is done, break the circle + // Job is done, break the circle break; } else { - // Don't forget to keep an eye on the cooking - operateMachine(); - } + // Don't forget to keep an eye on the cooking + operateMachine(); + } // Check if there was an update by the rotary encoder if( rotaryEncoderVirtualPosition != rotaryEncoderPreviousPosition ) {