Commit 0c5f686d authored by João Lino's avatar João Lino

Rel.3

parent fe9b974d
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
Released into the public domain. Released into the public domain.
*/ */
#ifndef CustomDataStructures_h #ifndef CustomDataStructures_h
#define CustomDataStructures_h
enum eRotaryEncoderMode { enum eRotaryEncoderMode {
eRotaryEncoderMode_Menu, eRotaryEncoderMode_Menu,
...@@ -13,42 +14,65 @@ enum eRotaryEncoderMode { ...@@ -13,42 +14,65 @@ enum eRotaryEncoderMode {
}; };
// menu // menu
enum eMenuType {
eMenuType_Main,
eMenuType_BeerProfile,
eMenuType_Stage,
eMenuType_Malt,
eMenuType_Settings
};
enum eMainMenuOptions { enum eMainMenuOptions {
eMainMenu_NULL,
eMainMenu_GO, eMainMenu_GO,
eMainMenu_Presets, eMainMenu_STOP,
eMainMenu_SKIP,
eMainMenu_BeerProfile,
eMainMenu_Stage,
eMainMenu_Malt, eMainMenu_Malt,
eMainMenu_Startpoint,
eMainMenu_BetaGlucanase,
eMainMenu_Debranching,
eMainMenu_Proteolytic,
eMainMenu_BetaAmylase,
eMainMenu_AlphaAmylase,
eMainMenu_Mashout,
eMainMenu_Recirculation,
eMainMenu_Sparge,
eMainMenu_Boil,
eMainMenu_Hops, eMainMenu_Hops,
eMainMenu_Cooling, eMainMenu_Clean,
eMainMenu_Purge,
eMainMenu_Settings, eMainMenu_Settings,
eMainMenu_Back eMainMenu_Back
}; };
enum ePresetsMenuOptions { enum eStageMenuOptions {
ePresetsMenu_Trigo, eStageMenu_NULL,
ePresetsMenu_IPA, eStageMenu_Startpoint,
ePresetsMenu_Belga, eStageMenu_BetaGlucanase,
ePresetsMenu_Red, eStageMenu_Debranching,
ePresetsMenu_APA, eStageMenu_Proteolytic,
ePresetsMenu_Back eStageMenu_BetaAmylase,
eStageMenu_AlphaAmylase,
eStageMenu_Mashout,
eStageMenu_Recirculation,
eStageMenu_Sparge,
eStageMenu_Boil,
eStageMenu_Cooling,
eStageMenu_Back
};
enum eBeerProfileMenuOptions {
eBeerProfileMenu_NULL,
eBeerProfileMenu_Basic,
eBeerProfileMenu_Trigo,
eBeerProfileMenu_IPA,
eBeerProfileMenu_Belga,
eBeerProfileMenu_Red,
eBeerProfileMenu_APA,
eBeerProfileMenu_Custom,
eBeerProfileMenu_Back
}; };
enum eMaltMenuOptions { enum eMaltMenuOptions {
eMaltMenu_NULL,
eMaltMenu_CastleMalting_Chteau_Pilsen_2RS, eMaltMenu_CastleMalting_Chteau_Pilsen_2RS,
eMaltMenu_CastleMalting_Wheat_Blanc, eMaltMenu_CastleMalting_Wheat_Blanc,
eMaltMenu_Back eMaltMenu_Back
}; };
enum eSettingsMenuOptions { enum eSettingsMenuOptions {
eSettingsMenu_NULL,
eSettingsMenu_PT100_Element, eSettingsMenu_PT100_Element,
eSettingsMenu_PT100_Up, eSettingsMenu_PT100_Up,
eSettingsMenu_PT100_Down, eSettingsMenu_PT100_Down,
...@@ -68,7 +92,19 @@ enum eCookingStages { ...@@ -68,7 +92,19 @@ enum eCookingStages {
eCookingStage_Sparge, eCookingStage_Sparge,
eCookingStage_Boil, eCookingStage_Boil,
eCookingStage_Cooling, eCookingStage_Cooling,
eCookingStage_Clean,
eCookingStage_Purge,
eCookingStage_Done eCookingStage_Done
}; };
enum eBeerProfile {
eBeerProfile_Basic,
eBeerProfile_Trigo,
eBeerProfile_IPA,
eBeerProfile_Belga,
eBeerProfile_Red,
eBeerProfile_APA,
eBeerProfile_Custom
};
#endif #endif
\ No newline at end of file
/*
Display.cpp - Display functions code file.
Created by João Lino, September 25, 2015.
Released into the public domain.
*/
#include "Display.h"
boolean lcdPrint(LiquidCrystal_I2C *lcd, String title, String message) {
int messageLength = message.length();
lcd->clear();
// print title
lcd->home();
lcd->print(title);
// print message
if(messageLength <= LCD_HORIZONTAL_RESOLUTION) {
lcd->setCursor(0,LCD_VERTICAL_RESOLUTION-1);
lcd->print(message);
delay(1000);
}
// print scrolling message
else {
String output_message = " ";
output_message += message;
messageLength = output_message.length();
// Adjust the message size for proper printing
if ( messageLength & 1 == 1 ) {
output_message+=" ";
messageLength+=2;
}
// print scrolling message
for (int cursor = 0; cursor < messageLength - LCD_HORIZONTAL_RESOLUTION; cursor+=2) {
if ((digitalRead(ROTARY_ENCODER_SW_PIN))) {
// Wait until switch is released
while (digitalRead(ROTARY_ENCODER_SW_PIN)) {}
// debounce
delay(10);
// Job is done, break the circle
return false;
} else {
lcd->setCursor(0,LCD_VERTICAL_RESOLUTION-1);
lcd->print(output_message.substring(cursor, cursor+16));
delay(500);
}
}
}
return true;
}
void xPaintStatusTemplate(LiquidCrystal_I2C *lcd, boolean cooking) {
// Clear LCD
lcd->clear();
// 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 XX 000.0/000C");
}
else {
lcd->print("OFF XX 000.0/000C");
}
// 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");
}
boolean displayStatus(LiquidCrystal_I2C *lcd, boolean cooking, float cookTemperature, float baseTemperature, float upTemperature, float downTemperature, unsigned long clockCounter, boolean repaint) {
boolean ret = repaint;
// Check whether a template repaint is required
if(repaint) {
// Repaint the LCD template
xPaintStatusTemplate(lcd, cooking);
// Reset the repaint flag after the repaint has been done
ret = false;
}
double displayTemperature = 0.0;
unsigned long ulTimeToShow = millis() % 6000;
lcd->setCursor (4,0);
if(ulTimeToShow < 2000) {
displayTemperature = baseTemperature;
lcd->print("TS");
}
else {
if(ulTimeToShow < 4000) {
displayTemperature = upTemperature;
lcd->print("UP");
}
else {
displayTemperature = downTemperature;
lcd->print("DW");
}
}
// Print positions with no numbers, before the measured temperature value
lcd->setCursor (7,0);
if (displayTemperature < 10) {
lcd->print(" ");
}
else {
if (displayTemperature < 100) {
lcd->print(" ");
}
}
// Print measured temperature value onto the LCD
lcd->print(displayTemperature, 1);
// Print positions with no numbers, before the target temperature value
lcd->setCursor (13,0);
if (cookTemperature < 10) {
lcd->print(" ");
}
else {
if (cookTemperature < 100) {
lcd->print(" ");
}
}
// Print target temperature value onto the LCD
lcd->print(cookTemperature);
// Calculate the numbers on the timer clock
unsigned long minutes = clockCounter / 1000 / 60;
unsigned long seconds = (clockCounter / 1000) % 60;
// Position the cursor at the begining of where the timer goes onto the screen
lcd->setCursor (10, 1);
// Print the timer values onto the LCD
if (minutes < 10) {
lcd->print(" 0");
}
else {
if (minutes < 100) {
lcd->print(" ");
}
}
lcd->print(minutes);
lcd->print(":");
if(seconds<10) {
lcd->print("0");
}
lcd->print(seconds);
return ret;
}
boolean displayMainMenu(LiquidCrystal_I2C *lcd, eMainMenuOptions position, boolean repaint) {
boolean ret = repaint;
if(repaint) {
// display menu
lcd->clear();
lcd->home (); // go home
lcd->print("Brewery Menu");
switch(position) {
case eMainMenu_GO: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> GO ");
break;
}
case eMainMenu_STOP: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> STOP ");
break;
}
case eMainMenu_SKIP: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> SKIP ");
break;
}
case eMainMenu_BeerProfile: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> BeerProfile ");
break;
}
case eMainMenu_Stage: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> Stages ");
break;
}
case eMainMenu_Malt: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> Malt ");
break;
}
case eMainMenu_Hops: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> Hops ");
break;
}
case eMainMenu_Clean: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> Clean ");
break;
}
case eMainMenu_Purge: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> Purge ");
break;
}
case eMainMenu_Settings: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> Settings ");
break;
}
case eMainMenu_Back: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> Back ");
break;
}
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, 0 );
}
}
ret = false;
}
return ret;
}
boolean displayBeerProfileMenu(LiquidCrystal_I2C *lcd, eBeerProfileMenuOptions position, boolean repaint) {
boolean ret = repaint;
if(repaint) {
// display menu
lcd->clear();
lcd->home (); // go home
lcd->print("Preset Menu");
switch(position) {
case eBeerProfileMenu_Basic: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> Basic ");
break;
}
case eBeerProfileMenu_Trigo: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> Trigo ");
break;
}
case eBeerProfileMenu_IPA: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> IPA ");
break;
}
case eBeerProfileMenu_Belga: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> Belga ");
break;
}
case eBeerProfileMenu_Red: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> Red ");
break;
}
case eBeerProfileMenu_APA: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> APA ");
break;
}
case eBeerProfileMenu_Custom: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> Custom ");
break;
}
case eBeerProfileMenu_Back: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> Back ");
break;
}
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, 0 );
}
}
ret = false;
}
return ret;
}
boolean displayStageMenu(LiquidCrystal_I2C *lcd, eStageMenuOptions position, boolean repaint) {
boolean ret = repaint;
if(repaint) {
// display menu
lcd->clear();
lcd->home (); // go home
lcd->print("Stage Menu");
switch(position) {
case eStageMenu_Startpoint: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> Startpoint ");
break;
}
case eStageMenu_BetaGlucanase: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> BetaGlucanase");
break;
}
case eStageMenu_Debranching: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> Debranching ");
break;
}
case eStageMenu_Proteolytic: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> Proteolytic ");
break;
}
case eStageMenu_BetaAmylase: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> Beta Amylase ");
break;
}
case eStageMenu_AlphaAmylase: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> Alpha Amylase");
break;
}
case eStageMenu_Mashout: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> Mashout ");
break;
}
case eStageMenu_Recirculation: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> Recirculation");
break;
}
case eStageMenu_Sparge: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> Sparge ");
break;
}
case eStageMenu_Boil: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> Boil ");
break;
}
case eStageMenu_Cooling: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> Cooling ");
break;
}
case eStageMenu_Back: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> Back ");
break;
}
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, 0 );
}
}
ret = false;
}
return ret;
}
boolean displayMaltMenu(LiquidCrystal_I2C *lcd, eMaltMenuOptions position, boolean repaint) {
boolean ret = repaint;
if(repaint) {
// display menu
lcd->clear();
lcd->home (); // go home
lcd->print("Malt Menu");
switch(position) {
case eMaltMenu_CastleMalting_Chteau_Pilsen_2RS: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> CM Ch. Pilsen");
break;
}
case eMaltMenu_CastleMalting_Wheat_Blanc: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> CM Wheat Blan");
break;
}
case eMaltMenu_Back: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> Back ");
break;
}
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, 0 );
}
}
ret = false;
}
return ret;
}
boolean displaySettingsMenu(LiquidCrystal_I2C *lcd, eSettingsMenuOptions position, boolean repaint) {
boolean ret = repaint;
if(repaint) {
// display menu
lcd->clear();
lcd->home (); // go home
lcd->print("Settings Menu");
switch(position) {
case eSettingsMenu_PT100_Element: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> PT100 Element");
break;
}
case eSettingsMenu_PT100_Up: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> PT100 Up ");
break;
}
case eSettingsMenu_PT100_Down: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> PT100 Down ");
break;
}
case eSettingsMenu_Back: {
lcd->setCursor (0,1); // go to start of 2nd line
lcd->print("-> Back ");
break;
}
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, 0 );
}
}
ret = false;
}
return ret;
}
\ No newline at end of file
/*
Display.h - Display functions header file.
Created by João Lino, September 25, 2015.
Released into the public domain.
*/
#ifndef DISPLAY_h
#define DISPLAY_h
#include <arduino.h>
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#include "config.h"
#include "CustomDataStructures.h"
boolean lcdPrint(LiquidCrystal_I2C *lcd, String title, String message);
void xPaintStatusTemplate(LiquidCrystal_I2C *lcd, boolean cooking);
boolean displayStatus(LiquidCrystal_I2C *lcd, boolean cooking, float cookTemperature, float baseTemperature, float upTemperature, float downTemperature, unsigned long clockCounter, boolean repaint);
boolean displayMainMenu(LiquidCrystal_I2C *lcd, eMainMenuOptions position, boolean repaint);
boolean displayBeerProfileMenu(LiquidCrystal_I2C *lcd, eBeerProfileMenuOptions position, boolean repaint);
boolean displayStageMenu(LiquidCrystal_I2C *lcd, eStageMenuOptions position, boolean repaint);
boolean displayMaltMenu(LiquidCrystal_I2C *lcd, eMaltMenuOptions position, boolean repaint);
boolean displaySettingsMenu(LiquidCrystal_I2C *lcd, eSettingsMenuOptions position, boolean repaint);
#endif
\ No newline at end of file
/*
void termometerCalibration() {
float temperaturePumpOFF = 200.0;
float temperaturePumpON = 200.0;
#ifdef DEBUG
debugPrintFunction("termometerCalibration");
#endif
for( int i = 0; i < 300; i++ ) {
basePT100.measure();
delay(100);
}
temperaturePumpOFF = basePT100.getCurrentTemperature();
analogWrite(PUMP_PIN, PUMP_SPEED_MAX);
for( int i = 0; i < 300; i++ ) {
basePT100.measure();
delay(100);
}
temperaturePumpON = basePT100.getCurrentTemperature();
analogWrite(PUMP_PIN, PUMP_SPEED_STOP);
#ifdef DEBUG
debugPrintVar("temperaturePumpOFF", temperaturePumpOFF);
debugPrintVar("temperaturePumpON", temperaturePumpON);
debugPrintVar("diff", temperaturePumpON - temperaturePumpOFF);
#endif
}
*/
\ No newline at end of file
...@@ -71,6 +71,18 @@ int supermario_tempo[] = { ...@@ -71,6 +71,18 @@ int supermario_tempo[] = {
12, 12, 12, 12, 12, 12, 12, 12,
}; };
//Underworld short melody
int underworld_melody_short[] = {
NOTE_C4, NOTE_C5, NOTE_A3, NOTE_A4,
NOTE_AS3, NOTE_AS4
};
//Underwolrd short tempo
int underworld_tempo_short[] = {
12, 12, 12, 12,
12, 12
};
//Underworld melody //Underworld melody
int underworld_melody[] = { int underworld_melody[] = {
NOTE_C4, NOTE_C5, NOTE_A3, NOTE_A4, NOTE_C4, NOTE_C5, NOTE_A3, NOTE_A4,
...@@ -117,6 +129,16 @@ int underworld_tempo[] = { ...@@ -117,6 +129,16 @@ int underworld_tempo[] = {
3, 3, 3 3, 3, 3
}; };
int buzz_1_melody[] = {
NOTE_E7, NOTE_E7, NOTE_E7, NOTE_E7,
0, 0, 0, 0,
};
//Mario main them tempo
int buzz_1_tempo[] = {
12, 12, 12, 12,
12, 12, 12, 12,
};
int song = 0; int song = 0;
void buzz(int targetPin, long frequency, long length) { void buzz(int targetPin, long frequency, long length) {
...@@ -139,7 +161,7 @@ void sing(int s, int pin) { ...@@ -139,7 +161,7 @@ void sing(int s, int pin) {
song = s; song = s;
switch(song) { switch(song) {
case 1: { case MELODY_SUPER_MARIO: {
int size = sizeof(supermario_melody) / sizeof(int); int size = sizeof(supermario_melody) / sizeof(int);
for (int thisNote = 0; thisNote < size; thisNote++) { for (int thisNote = 0; thisNote < size; thisNote++) {
...@@ -161,7 +183,7 @@ void sing(int s, int pin) { ...@@ -161,7 +183,7 @@ void sing(int s, int pin) {
} }
break; break;
} }
case 2: { case MELODY_UNDERWORLD: {
int size = sizeof(underworld_melody) / sizeof(int); int size = sizeof(underworld_melody) / sizeof(int);
for (int thisNote = 0; thisNote < size; thisNote++) { for (int thisNote = 0; thisNote < size; thisNote++) {
...@@ -183,7 +205,7 @@ void sing(int s, int pin) { ...@@ -183,7 +205,7 @@ void sing(int s, int pin) {
} }
break; break;
} }
case 3: { case MELODY_SUPER_MARIO_START: {
int size = sizeof(supermario_start_melody) / sizeof(int); int size = sizeof(supermario_start_melody) / sizeof(int);
for (int thisNote = 0; thisNote < size; thisNote++) { for (int thisNote = 0; thisNote < size; thisNote++) {
...@@ -205,6 +227,50 @@ void sing(int s, int pin) { ...@@ -205,6 +227,50 @@ void sing(int s, int pin) {
} }
break; break;
} }
case MELODY_UNDERWORLD_SHORT: {
int size = sizeof(underworld_melody_short) / sizeof(int);
for (int thisNote = 0; thisNote < size; thisNote++) {
// to calculate the note duration, take one second
// divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
int noteDuration = 1000 / underworld_tempo_short[thisNote];
buzz(pin, underworld_melody_short[thisNote], noteDuration);
// to distinguish the notes, set a minimum time between them.
// the note's duration + 30% seems to work well:
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// stop the tone playing:
buzz(pin, 0, noteDuration);
}
break;
}
case BUZZ_1: {
int size = sizeof(buzz_1_melody) / sizeof(int);
for (int thisNote = 0; thisNote < size; thisNote++) {
// to calculate the note duration, take one second
// divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
int noteDuration = 1000 / buzz_1_tempo[thisNote];
buzz(pin, buzz_1_melody[thisNote], noteDuration);
// to distinguish the notes, set a minimum time between them.
// the note's duration + 30% seems to work well:
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// stop the tone playing:
buzz(pin, 0, noteDuration);
}
break;
}
} }
} }
\ No newline at end of file
...@@ -103,9 +103,11 @@ ...@@ -103,9 +103,11 @@
// Define a special note, 'R', to represent a rest // Define a special note, 'R', to represent a rest
#define _R 0 #define _R 0
#define MELODY_SUPER_MARIO 1 #define MELODY_SUPER_MARIO 1
#define MELODY_UNDERWORLD 2 #define MELODY_UNDERWORLD 2
#define MELODY_SUPER_MARIO_START 3 #define MELODY_SUPER_MARIO_START 3
#define MELODY_UNDERWORLD_SHORT 4
#define BUZZ_1 5
// melody[] is an array of notes, accompanied by beats[], // melody[] is an array of notes, accompanied by beats[],
......
#define DEBUG /*
brew.ino - Main execution file.
// ######################### CONSTANTS ######################### Created by João Lino, August 28, 2014.
Released into the public domain.
// ######################### 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
// ++++++++++++++++++++++++ Temperature ++++++++++++++++++++++++
#define PT100_BASE_INPUT_PIN A4
#define PT100_BASE_OUTPUT_PIN 32
#define PT100_BASE_TIME_BETWEEN_READINGS 100
#define PT100_UP_INPUT_PIN A5
#define PT100_UP_OUTPUT_PIN 30
#define PT100_UP_TIME_BETWEEN_READINGS 100
#define PT100_DOWN_INPUT_PIN A6
#define PT100_DOWN_OUTPUT_PIN 31
#define PT100_DOWN_TIME_BETWEEN_READINGS 100
#define PT100_BASE_DEFAULT_ADC_VMAX 1.1
#define PT100_BASE_DEFAULT_VS 5.0
#define PT100_BASE_DEFAULT_R1_RESISTENCE 605.2 //608.99
#define PT100_BASE_DEFAULT_LINE_RESISTENCE 0.0
#define PT100_BASE_DEFAULT_OPERATION_RESISTENCE 0.0
#define PT100_UP_DEFAULT_ADC_VMAX 1.1
#define PT100_UP_DEFAULT_VS 5.0
#define PT100_UP_DEFAULT_R1_RESISTENCE 615.6 //621 //620 //618.1
#define PT100_UP_DEFAULT_LINE_RESISTENCE 0.0
#define PT100_UP_DEFAULT_OPERATION_RESISTENCE 0.0
#define PT100_DOWN_DEFAULT_ADC_VMAX 1.1
#define PT100_DOWN_DEFAULT_VS 5.0
#define PT100_DOWN_DEFAULT_R1_RESISTENCE 618.6 //619.3 //617.2
#define PT100_DOWN_DEFAULT_LINE_RESISTENCE 0.0
#define PT100_DOWN_DEFAULT_OPERATION_RESISTENCE 0.0
// ++++++++++++++++++++++++ Mixer ++++++++++++++++++++++++
//#define MIXER_PIN 12
//#define MIXER_MAX_POSITION 255
// ++++++++++++++++++++++++ Pump ++++++++++++++++++++++++
#include "Melody.h"
#define PIEZO_PIN 25
// ++++++++++++++++++++++++ Pump ++++++++++++++++++++++++
#define PUMP_PIN 6
#define PUMP_SPEED_STOP 0
#define PUMP_SPEED_SLOW 64
#define PUMP_SPEED_AVERAGE 128
#define PUMP_SPEED_FAST 192
#define PUMP_SPEED_MAX 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 20 // Number of miliseconds to ignore new signals a signal is received
// ++++++++++++++++++++++++ State Machine ++++++++++++++++++++++++ #define DEBUG
#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 ######################### // ######################### LIBRARIES #########################
// ++++++++++++++++++++++++ LiquidCrystal_I2C ++++++++++++++++++++++++ // ++++++++++++++++++++++++ LiquidCrystal_I2C ++++++++++++++++++++++++
#include <Wire.h> #include <Wire.h>
#include <LCD.h> #include <LCD.h>
#include <LiquidCrystal_I2C.h> #include <LiquidCrystal_I2C.h>
#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 +++++++++++++++++++++++++++++++++ // ++++++++++++++++++++++++ PT100 +++++++++++++++++++++++++++++++++
#include <PT100.h> #include <PT100.h>
// ++++++++++++++++++++++++ ENUM +++++++++++++++++++++++++++++++++ // ++++++++++++++++++++++++ OTHER +++++++++++++++++++++++++++++++++
#include "debug.h"
#include "config.h"
#include "CustomDataStructures.h" #include "CustomDataStructures.h"
// ######################### TEMPLATES ######################### #include "Melody.h"
// ++++++++++++++++++++++++ Debug ++++++++++++++++++++++++ #include "Display.h"
template <class T> void debugPrintVar( char *name, const T& value );
template <class T> void debugPrintVar( char *name, const T& value ) {
Serial.print("[");
Serial.print(name);
Serial.print(":");
Serial.print(value);
Serial.println("]");
}
void debugPrintFunction( char *name ) {
Serial.print("++++++++++++++++++++++++ ");
Serial.print(name);
Serial.println("++++++++++++++++++++++++");
}
// ######################### VARIABLES ######################### // ######################### VARIABLES #########################
// ++++++++++++++++++++++++ State Machine ++++++++++++++++++++++++ // ++++++++++++++++++++++++ State Machine ++++++++++++++++++++++++
eRotaryEncoderMode rotaryEncoderMode; eRotaryEncoderMode rotaryEncoderMode;
eMainMenuOptions mainMenuOption;
ePresetsMenuOptions presetsMenuOption; eCookingStages cookingStage;
eBeerProfile beerProfile;
eMenuType eMenuType;
eMainMenuOptions eMainMenuPosition;
eMainMenuOptions eMainMenuSelection;
eBeerProfileMenuOptions eBeerProfileMenuPosition;
eBeerProfileMenuOptions eBeerProfileMenuSelection;
eStageMenuOptions eStageMenuPosition;
eStageMenuOptions eStageMenuSelection;
eMaltMenuOptions eMaltMenuPosition;
eMaltMenuOptions eMaltMenuSelection;
eSettingsMenuOptions eSettingsMenuPosition;
eSettingsMenuOptions eSettingsMenuSelection;
eMaltMenuOptions maltMenuOption; eMaltMenuOptions maltMenuOption;
eSettingsMenuOptions settingsMenuOption; eSettingsMenuOptions settingsMenuOption;
eCookingStages cookingStage;
// ++++++++++++++++++++++++ Global Variables ++++++++++++++++++++++++ // ++++++++++++++++++++++++ Global Variables ++++++++++++++++++++++++
boolean cooking; boolean cooking;
boolean bStageFirstRun; boolean bStageFirstRun;
unsigned long clockStartTime; unsigned long clockStartTime;
unsigned long clockCounter; unsigned long clockLastUpdate;
unsigned long clockIgnore; long clockCounter;
unsigned long clockIgnore;
boolean clockStart; boolean clockStart;
boolean clockEnd; boolean clockEnd;
unsigned long cookTime; unsigned long cookTime;
int cookTemperature; int cookTemperature;
//cook_mode_list cookMode; //cook_mode_list cookMode;
//int cookMixerSpeed; //int cookMixerSpeed;
int cookHeatPWM; int finalYield;
unsigned long startpointTime; unsigned long startpointTime;
unsigned long betaGlucanaseTime; unsigned long betaGlucanaseTime;
unsigned long debranchingTime; unsigned long debranchingTime;
unsigned long proteolyticTime; unsigned long proteolyticTime;
unsigned long betaAmylaseTime; unsigned long betaAmylaseTime;
unsigned long alphaAmylaseTime; unsigned long alphaAmylaseTime;
unsigned long mashoutTime; unsigned long mashoutTime;
unsigned long recirculationTime; unsigned long recirculationTime;
unsigned long spargeTime; unsigned long spargeTime;
unsigned long boilTime; unsigned long boilTime;
unsigned long coolingTime; unsigned long coolingTime;
unsigned long cleaningTime;
int startpointTemperature; int startpointTemperature;
int betaGlucanaseTemperature; int betaGlucanaseTemperature;
...@@ -158,13 +90,13 @@ int recirculationTemperature; ...@@ -158,13 +90,13 @@ int recirculationTemperature;
int spargeTemperature; int spargeTemperature;
int boilTemperature; int boilTemperature;
int coolingTemperature; int coolingTemperature;
int cleaningTemperature;
//int menuSize;
int menu_position[MENU_MAX_DEPTH] = {MENU_INIT_VALUES};
boolean refresh; boolean refresh;
boolean repaint; boolean repaint;
boolean bStatusElement;
// ++++++++++++++++++++++++ Interrupts ++++++++++++++++++++++++ // ++++++++++++++++++++++++ Interrupts ++++++++++++++++++++++++
static unsigned long lastInterruptTime; static unsigned long lastInterruptTime;
...@@ -190,9 +122,9 @@ int iPumpSpeed; // Time frame to operate in ...@@ -190,9 +122,9 @@ int iPumpSpeed; // Time frame to operate in
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 +++++++++++++++++++++++
PT100 basePT100("base", 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, 0.0, 0.0); PT100 basePT100("base", PT100_BASE_OUTPUT_PIN, PT100_BASE_OUTPUT_R_PIN, PT100_BASE_INPUT_PIN, PT100_BASE_INPUT_R_PIN, PT100_BASE_TIME_BETWEEN_READINGS, PT100_BASE_DEFAULT_ADC_VMAX, PT100_BASE_DEFAULT_VS, PT100_BASE_DEFAULT_R1_RESISTENCE, PT100_BASE_DEFAULT_R2_RESISTENCE, 0.0, 0.0);//0.0, 0.0);
PT100 upPT100("up", 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, 0.112329092, -3.57); PT100 upPT100("up", PT100_UP_OUTPUT_PIN, PT100_UP_OUTPUT_R_PIN, PT100_UP_INPUT_PIN, PT100_UP_INPUT_R_PIN, PT100_UP_TIME_BETWEEN_READINGS, PT100_UP_DEFAULT_ADC_VMAX, PT100_UP_DEFAULT_VS, PT100_UP_DEFAULT_R1_RESISTENCE, PT100_UP_DEFAULT_R2_RESISTENCE, -0.2, 8.0);//8.0);//0.17, -7.2); //0.195, -7.6);//0.0, 0.0);//0.38, -3.0); //0.112329092, -3.57); //0.0, 0.0);
PT100 downPT100("down", 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, 0.22, -5.5); PT100 downPT100("down", PT100_DOWN_OUTPUT_PIN, PT100_DOWN_OUTPUT_R_PIN, PT100_DOWN_INPUT_PIN, PT100_DOWN_INPUT_R_PIN, PT100_DOWN_TIME_BETWEEN_READINGS, PT100_DOWN_DEFAULT_ADC_VMAX, PT100_DOWN_DEFAULT_VS, PT100_DOWN_DEFAULT_R1_RESISTENCE, PT100_DOWN_DEFAULT_R2_RESISTENCE, 0.0, -2.2);//0.228, -9); //0.26, -10);//0.0, 0.0);//0.53, -6.6); //0.22, -5.5); //0.0, 0.0);
// ######################### INTERRUPTS ######################### // ######################### INTERRUPTS #########################
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
...@@ -300,20 +232,25 @@ void xSafeHardwarePowerOff() { ...@@ -300,20 +232,25 @@ void xSafeHardwarePowerOff() {
// Force shutdown // Force shutdown
analogWrite(PUMP_PIN, PUMP_SPEED_STOP); // analogWrite values from 0 to 255 analogWrite(PUMP_PIN, PUMP_SPEED_STOP); // analogWrite values from 0 to 255
digitalWrite(HEATING_ELEMENT_OUTPUT_PIN, LOW); // Turn heading element OFF for safety digitalWrite(HEATING_ELEMENT_OUTPUT_PIN, LOW); // Turn heading element OFF for safety
bStatusElement = false;
basePT100.setSampleDeviation( 0.0 );
upPT100.setSampleDeviation( 0.0 );
downPT100.setSampleDeviation( 0.0 );
//analogWrite(MIXER_PIN, 0); // Turn mixer OFF for safety //analogWrite(MIXER_PIN, 0); // Turn mixer OFF for safety
} }
void displayWelcome() { void xWelcomeUser() {
#ifndef DEBUG //#ifndef DEBUG
lcdPrint(" Let's start", " Brewing!"); // Write welcome lcdPrint(&lcd, " Let's start", " Brewing!"); // Write welcome
// Play Melody; // Play Melody;
sing(MELODY_SUPER_MARIO_START, PIEZO_PIN); sing(MELODY_SUPER_MARIO_START, PIEZO_PIN);
//termometerCalibration(); //termometerCalibration();
delay(SETTING_WELCOME_TIMEOUT); // pause for effect delay(SETTING_WELCOME_TIMEOUT); // pause for effect
#endif //#endif
} }
void setup() { void setup() {
...@@ -326,6 +263,7 @@ void setup() { ...@@ -326,6 +263,7 @@ void setup() {
// ++++++++++++++++++++++++ Heating Element Relay ++++++++++++++++++++++++ // ++++++++++++++++++++++++ Heating Element Relay ++++++++++++++++++++++++
pinMode (HEATING_ELEMENT_OUTPUT_PIN, OUTPUT); pinMode (HEATING_ELEMENT_OUTPUT_PIN, OUTPUT);
digitalWrite (HEATING_ELEMENT_OUTPUT_PIN, LOW); digitalWrite (HEATING_ELEMENT_OUTPUT_PIN, LOW);
bStatusElement = false;
windowStartTime = millis(); windowStartTime = millis();
dWattPerPulse = HEATING_ELEMENT_MAX_WATTAGE / HEATING_ELEMENT_AC_FREQUENCY_HZ; dWattPerPulse = HEATING_ELEMENT_MAX_WATTAGE / HEATING_ELEMENT_AC_FREQUENCY_HZ;
...@@ -343,11 +281,11 @@ void setup() { ...@@ -343,11 +281,11 @@ void setup() {
// ++++++++++++++++++++++++ Temperature Sensor PT100 ++++++++++++++++++++++++ // ++++++++++++++++++++++++ Temperature Sensor PT100 ++++++++++++++++++++++++
//basePT100.setup(); //basePT100.setup();
/* /*
analogReference (INTERNAL1V1); // EXTERNAL && INTERNAL2V56 && INTERNAL1V1 analogReference (INTERNAL1V1); // EXTERNAL && INTERNAL2V56 && INTERNAL1V1
pinMode (PT100_OUTPUT_PIN, OUTPUT); // setup temperature sensor input pin pinMode (PT100_OUTPUT_PIN, OUTPUT); // setup temperature sensor input pin
digitalWrite (PT100_OUTPUT_PIN, LOW); // initialize sensor off digitalWrite (PT100_OUTPUT_PIN, LOW); // initialize sensor off
*/ */
// ++++++++++++++++++++++++ Serial Monitor ++++++++++++++++++++++++ // ++++++++++++++++++++++++ Serial Monitor ++++++++++++++++++++++++
Serial.begin (SETTING_SERIAL_MONITOR_BAUD_RATE); // setup terminal baud rate 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 Serial.println (SETTING_SERIAL_MONITOR_WELCOME_MESSAGE); // print a start message to the terminal
...@@ -363,15 +301,28 @@ void setup() { ...@@ -363,15 +301,28 @@ void setup() {
xSetupRotaryEncoder ( eRotaryEncoderMode_Disabled, 0, 0, 0, 0, 0 ); xSetupRotaryEncoder ( eRotaryEncoderMode_Disabled, 0, 0, 0, 0, 0 );
// ++++++++++++++++++++++++ State Machine ++++++++++++++++++++++++ // ++++++++++++++++++++++++ State Machine ++++++++++++++++++++++++
presetsMenuOption = ePresetsMenu_Trigo; eMenuType = eMenuType_Main;
maltMenuOption = eMaltMenu_CastleMalting_Chteau_Pilsen_2RS;
settingsMenuOption = eSettingsMenu_PT100_Element; eMainMenuPosition = eMainMenu_GO;
eMainMenuSelection = eMainMenu_NULL;
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;
// ++++++++++++++++++++++++ Global Variables ++++++++++++++++++++++++ // ++++++++++++++++++++++++ Global Variables ++++++++++++++++++++++++
cooking = false; cooking = false;
bStageFirstRun = true; bStageFirstRun = true;
clockStartTime = 0; clockStartTime = 0;
clockLastUpdate = 0;
clockCounter = 0; clockCounter = 0;
clockIgnore = 0; clockIgnore = 0;
clockStart = false; clockStart = false;
...@@ -381,9 +332,9 @@ void setup() { ...@@ -381,9 +332,9 @@ void setup() {
cookTemperature = 25; cookTemperature = 25;
//cookMode = quick_start; //cookMode = quick_start;
//cookMixerSpeed = 120; //cookMixerSpeed = 120;
cookHeatPWM = 5; finalYield = 25;
startpointTime = 3600; //120; startpointTime = 120;
betaGlucanaseTime = 0; betaGlucanaseTime = 0;
debranchingTime = 0; debranchingTime = 0;
proteolyticTime = 0; proteolyticTime = 0;
...@@ -394,8 +345,9 @@ void setup() { ...@@ -394,8 +345,9 @@ void setup() {
spargeTime = 1200; spargeTime = 1200;
boilTime = 5400; boilTime = 5400;
coolingTime = 120; coolingTime = 120;
cleaningTime = SETTING_CLEANING_TIME;
startpointTemperature = 50; //30; startpointTemperature = 30;
betaGlucanaseTemperature = 40; betaGlucanaseTemperature = 40;
debranchingTemperature = 40; debranchingTemperature = 40;
proteolyticTemperature = 50; proteolyticTemperature = 50;
...@@ -406,6 +358,7 @@ void setup() { ...@@ -406,6 +358,7 @@ void setup() {
spargeTemperature = 80; spargeTemperature = 80;
boilTemperature = 100; boilTemperature = 100;
coolingTemperature = 25; coolingTemperature = 25;
cleaningTemperature = SETTING_CLEANING_TEMPERATURE;
refresh = true; refresh = true;
repaint = true; repaint = true;
...@@ -416,16 +369,18 @@ void setup() { ...@@ -416,16 +369,18 @@ void setup() {
// ++++++++++++++++++++++++ PID ++++++++++++++++++++++++ // ++++++++++++++++++++++++ PID ++++++++++++++++++++++++
iWindowSize = HEATING_ELEMENT_DEFAULT_WINDOW_SIZE; // Time frame to operate in iWindowSize = HEATING_ELEMENT_DEFAULT_WINDOW_SIZE; // Time frame to operate in
// ######################### Code - Run Once ######################### // ######################### Code - Run Once #########################
xSafeHardwarePowerOff (); xSafeHardwarePowerOff ();
displayWelcome (); xWelcomeUser ();
xSetupRotaryEncoder ( eRotaryEncoderMode_Menu, eMainMenu_GO, MENU_SIZE_MAIN_MENU - 1, 0, 1, 0 ); xSetupRotaryEncoder ( eRotaryEncoderMode_Menu, eMainMenu_GO, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 );
} }
// ######################### MAIN LOOP ######################### // ######################### MAIN LOOP #########################
void loop() { void loop() {
//cleanSerialMonitor();
unsigned long inactivityTime = millis() - lastInterruptTime; unsigned long inactivityTime = millis() - lastInterruptTime;
if(inactivityTime > SETTING_MAX_INACTIVITY_TIME) { // Inactivity check if(inactivityTime > SETTING_MAX_INACTIVITY_TIME) { // Inactivity check
...@@ -433,598 +388,747 @@ void loop() { ...@@ -433,598 +388,747 @@ void loop() {
repaint = true; repaint = true;
refresh = false; refresh = false;
} }
displayStatus(); repaint = displayStatus( &lcd, cooking, cookTemperature, basePT100.getCurrentTemperature(), upPT100.getCurrentTemperature(), downPT100.getCurrentTemperature(), clockCounter, repaint );
} }
else { else {
displayMainMenu(); runMenu();
} }
operateMachine(); xManageMachineSystems();
} }
// ######################### FUNCTIONS ######################## // ######################### FUNCTIONS ########################
void xPaintStatusTemplate() { void runMenu() {
// Clear LCD #ifdef DEBUG_OFF
lcd.clear(); boolean debug_go = repaint;
if(debug_go) {
// Position the cursor at the begining of where the temperature template goes onto the screen debugPrintFunction("runMenu");
lcd.home(); debugPrintVar("repaint", repaint);
debugPrintVar("eMenuType", eMenuType);
// Print the target and measured temperature template debugPrintVar("rotaryEncoderVirtualPosition", rotaryEncoderVirtualPosition);
if(cooking) {
lcd.print("ON XX 000.0/000C");
}
else {
lcd.print("OFF XX 000.0/000C");
} }
#endif
// Position the cursor at the begining of where the mode and time template goes onto the screen switch(eMenuType) {
lcd.setCursor (0,LCD_VERTICAL_RESOLUTION-1); case eMenuType_Main: {
eMainMenuPosition = static_cast<eMainMenuOptions>(rotaryEncoderVirtualPosition);
lcd.print("**** 00:00"); repaint = displayMainMenu( &lcd, eMainMenuPosition, repaint );
}
void displayStatus() { if ( gotButtonPress( ROTARY_ENCODER_SW_PIN ) ) {
eMainMenuSelection = eMainMenuPosition;
}
// Check whether a template repaint is required runMainMenuSelection();
if(repaint) {
// Repaint the LCD template
xPaintStatusTemplate();
// Reset the repaint flag after the repaint has been done
repaint = false;
}
double displayTemperature = 0.0;
unsigned long ulTimeToShow = millis() % 6000;
lcd.setCursor (4,0); break;
if(ulTimeToShow < 2000) { }
displayTemperature = basePT100.getCurrentTemperature(); case eMenuType_BeerProfile: {
eBeerProfileMenuPosition = static_cast<eBeerProfileMenuOptions>(rotaryEncoderVirtualPosition);
repaint = displayBeerProfileMenu( &lcd, eBeerProfileMenuPosition, repaint );
lcd.print("TS"); if ( gotButtonPress( ROTARY_ENCODER_SW_PIN ) ) {
} eBeerProfileMenuSelection = eBeerProfileMenuPosition;
else { }
if(ulTimeToShow < 4000) {
displayTemperature = upPT100.getCurrentTemperature();
lcd.print("UP"); runBeerProfileSelection();
break;
} }
else { case eMenuType_Stage: {
displayTemperature = downPT100.getCurrentTemperature(); eStageMenuPosition = static_cast<eStageMenuOptions>(rotaryEncoderVirtualPosition);
repaint = displayStageMenu( &lcd, eStageMenuPosition, repaint );
lcd.print("DW"); if ( gotButtonPress( ROTARY_ENCODER_SW_PIN ) ) {
} eStageMenuSelection = eStageMenuPosition;
} }
// Print positions with no numbers, before the measured temperature value runStageSelection();
lcd.setCursor (7,0);
if (displayTemperature < 10) { break;
lcd.print(" ");
}
else {
if (displayTemperature < 100) {
lcd.print(" ");
} }
} case eMenuType_Malt: {
eMaltMenuPosition = static_cast<eMaltMenuOptions>(rotaryEncoderVirtualPosition);
repaint = displayMaltMenu( &lcd, eMaltMenuPosition, repaint );
// Print measured temperature value onto the LCD if ( gotButtonPress( ROTARY_ENCODER_SW_PIN ) ) {
lcd.print(displayTemperature, 1); eMaltMenuSelection = eMaltMenuPosition;
}
// Print positions with no numbers, before the target temperature value runMaltSelection();
lcd.setCursor (13,0);
if (cookTemperature < 10) { break;
lcd.print(" ");
}
else {
if (cookTemperature < 100) {
lcd.print(" ");
} }
} case eMenuType_Settings: {
eSettingsMenuPosition = static_cast<eSettingsMenuOptions>(rotaryEncoderVirtualPosition);
repaint = displaySettingsMenu( &lcd, eSettingsMenuPosition, repaint );
// Print target temperature value onto the LCD if ( gotButtonPress( ROTARY_ENCODER_SW_PIN ) ) {
lcd.print(cookTemperature); eSettingsMenuSelection = eSettingsMenuPosition;
}
// Calculate the numbers on the timer clock
unsigned long minutes = clockCounter / 1000 / 60;
unsigned long seconds = (clockCounter / 1000) % 60;
// Position the cursor at the begining of where the timer goes onto the screen runSettingsSelection();
lcd.setCursor (10, 1);
break;
// Print the timer values onto the LCD
if (minutes < 10) {
lcd.print(" 0");
}
else {
if (minutes < 100) {
lcd.print(" ");
} }
} }
lcd.print(minutes);
lcd.print(":"); #ifdef DEBUG_OFF
if(seconds<10) { if(debug_go) {
lcd.print("0"); debugPrintVar("repaint", repaint);
} }
lcd.print(seconds); #endif
} }
void displayMainMenu() { void runSettingsSelection() {
switch(menu_position[0]) { switch(eSettingsMenuSelection) {
case eMainMenu_GO: { case eSettingsMenu_PT100_Element: {
MainMenu_GO(); // Stuff
backToStatus();
menu_position[0] = -1; eMenuType = eMenuType_Main;
repaint = true;
// 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, eMainMenu_GO, MENU_SIZE_MAIN_MENU - 1, 0, 1, 0 ); xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenuPosition, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 );
break; break;
} }
case eMainMenu_STOP: { case eSettingsMenu_PT100_Up: {
MainMenu_STOP(); // Stuff
backToStatus();
menu_position[0] = -1; eMenuType = eMenuType_Main;
repaint = true;
// 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, eMainMenu_GO, MENU_SIZE_MAIN_MENU - 1, 0, 1, 0 ); xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenuPosition, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 );
break; break;
} }
case eMainMenu_Presets: { case eSettingsMenu_PT100_Down: {
MainMenu_Presets(); // Stuff
backToStatus();
menu_position[0] = -1; eMenuType = eMenuType_Main;
repaint = true;
// 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, eMainMenu_Presets, MENU_SIZE_MAIN_MENU - 1, 0, 1, 0 ); xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenuPosition, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 );
break; break;
} }
case eMainMenu_Malt: { case eSettingsMenu_Back: {
MainMenu_Malt(); 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 );
break;
}
default: {
}
}
eSettingsMenuSelection = eSettingsMenu_NULL;
}
void runMaltSelection() {
switch(eMaltMenuSelection) {
case eMaltMenu_CastleMalting_Chteau_Pilsen_2RS: {
// Stuff
backToStatus();
menu_position[0] = -1; eMenuType = eMenuType_Main;
repaint = true;
// 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, eMainMenu_Malt, MENU_SIZE_MAIN_MENU - 1, 0, 1, 0 ); xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenuPosition, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 );
break; break;
} }
case eMainMenu_Startpoint: { case eMaltMenu_CastleMalting_Wheat_Blanc: {
MainMenu_Startpoint(); // Stuff
backToStatus();
menu_position[0] = -1; eMenuType = eMenuType_Main;
repaint = true;
// 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, eMainMenu_Startpoint, MENU_SIZE_MAIN_MENU - 1, 0, 1, 0 ); xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenuPosition, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 );
break; break;
} }
case eMainMenu_BetaGlucanase: { case eMaltMenu_Back: {
MainMenu_BetaGlucanase(); eMenuType = eMenuType_Main;
repaint = true;
menu_position[0] = -1; // 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 );
break;
}
default: {
}
}
eMaltMenuSelection = eMaltMenu_NULL;
}
void runStageSelection() {
switch(eStageMenuSelection) {
case eStageMenu_Startpoint: {
startpointTime = getTimer( startpointTime );
startpointTemperature = xSetGenericValue( startpointTemperature, 0, 120, "temperature", "*C" );
backToStatus();
eMenuType = eMenuType_Main;
repaint = true;
// 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, eMainMenu_BetaGlucanase, MENU_SIZE_MAIN_MENU - 1, 0, 1, 0 ); xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenuPosition, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 );
break; break;
} }
case eMainMenu_Debranching: { case eStageMenu_BetaGlucanase: {
MainMenu_Debranching(); betaGlucanaseTime = getTimer( betaGlucanaseTime );
betaGlucanaseTemperature = xSetGenericValue( betaGlucanaseTemperature, 0, 120, "temperature", "*C" );
backToStatus();
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 );
menu_position[0] = -1; break;
}
case eStageMenu_Debranching: {
debranchingTime = getTimer( debranchingTime );
debranchingTemperature = xSetGenericValue( debranchingTemperature, 0, 120, "temperature", "*C" );
backToStatus();
eMenuType = eMenuType_Main;
repaint = true;
// 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, eMainMenu_Settings, MENU_SIZE_MAIN_MENU - 1, 0, 1, 0 ); xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenuPosition, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 );
break; break;
} }
case eMainMenu_Proteolytic: { case eStageMenu_Proteolytic: {
MainMenu_Proteolytic(); proteolyticTime = getTimer( proteolyticTime );
menu_position[0] = -1; proteolyticTemperature = xSetGenericValue( proteolyticTemperature, 0, 120, "temperature", "*C" );
backToStatus();
eMenuType = eMenuType_Main;
repaint = true;
// 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, eMainMenu_Proteolytic, MENU_SIZE_MAIN_MENU - 1, 0, 1, 0 ); xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenuPosition, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 );
break; break;
} }
case eMainMenu_BetaAmylase: { case eStageMenu_BetaAmylase: {
MainMenu_BetaAmylase(); betaAmylaseTime = getTimer( betaAmylaseTime );
menu_position[0] = -1; betaAmylaseTemperature = xSetGenericValue( betaAmylaseTemperature, 0, 120, "temperature", "*C" );
backToStatus();
eMenuType = eMenuType_Main;
repaint = true;
// 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, eMainMenu_BetaAmylase, MENU_SIZE_MAIN_MENU - 1, 0, 1, 0 ); xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenuPosition, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 );
break; break;
} }
case eMainMenu_AlphaAmylase: { case eStageMenu_AlphaAmylase: {
MainMenu_AlphaAmylase(); alphaAmylaseTime = getTimer( alphaAmylaseTime );
alphaAmylaseTemperature = xSetGenericValue( alphaAmylaseTemperature, 0, 120, "temperature", "*C" );
backToStatus();
eMenuType = eMenuType_Main;
repaint = true;
menu_position[0] = -1; // 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 );
break;
}
case eStageMenu_Mashout: {
mashoutTime = getTimer( mashoutTime );
mashoutTemperature = xSetGenericValue( mashoutTemperature, 0, 120, "temperature", "*C" );
backToStatus();
eMenuType = eMenuType_Main;
repaint = true;
// 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, eMainMenu_AlphaAmylase, MENU_SIZE_MAIN_MENU - 1, 0, 1, 0 ); xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenuPosition, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 );
break; break;
} }
case eMainMenu_Mashout: { case eStageMenu_Recirculation: {
MainMenu_Mashout(); recirculationTime = getTimer( recirculationTime );
recirculationTemperature = xSetGenericValue( recirculationTemperature, 0, 120, "temperature", "*C" );
backToStatus();
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 );
menu_position[0] = -1; break;
}
case eStageMenu_Sparge: {
spargeTime = getTimer( spargeTime );
spargeTemperature = xSetGenericValue( spargeTemperature, 0, 120, "temperature", "*C" );
backToStatus();
eMenuType = eMenuType_Main;
repaint = true;
// 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, eMainMenu_Mashout, MENU_SIZE_MAIN_MENU - 1, 0, 1, 0 ); xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenuPosition, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 );
break; break;
} }
case eMainMenu_Recirculation: { case eStageMenu_Boil: {
MainMenu_Recirculation(); boilTime = getTimer( boilTime );
menu_position[0] = -1; boilTemperature = xSetGenericValue( boilTemperature, 0, 120, "temperature", "*C" );
backToStatus();
eMenuType = eMenuType_Main;
repaint = true;
// 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, eMainMenu_Recirculation, MENU_SIZE_MAIN_MENU - 1, 0, 1, 0 ); xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenuPosition, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 );
break; break;
} }
case eMainMenu_Sparge: { case eStageMenu_Cooling: {
MainMenu_Sparge(); coolingTime = getTimer( coolingTime );
menu_position[0] = -1; coolingTemperature = xSetGenericValue( coolingTemperature, 0, 120, "temperature", "*C" );
backToStatus();
eMenuType = eMenuType_Main;
repaint = true;
// 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, eMainMenu_Sparge, MENU_SIZE_MAIN_MENU - 1, 0, 1, 0 ); xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenuPosition, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 );
break; break;
} }
case eMainMenu_Boil: { case eStageMenu_Back: {
MainMenu_Boil(); eMenuType = eMenuType_Main;
repaint = true;
menu_position[0] = -1; // 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 );
break;
}
default: {
}
}
eStageMenuSelection = eStageMenu_NULL;
}
void runBeerProfileSelection() {
switch(eBeerProfileMenuSelection) {
case eBeerProfileMenu_Basic: {
beerProfile = eBeerProfile_Basic;
startpointTime = 120;
betaGlucanaseTime = 0;
debranchingTime = 0;
proteolyticTime = 0;
betaAmylaseTime = 3600;
alphaAmylaseTime = 1800;
mashoutTime = 300;
recirculationTime = 1200;
spargeTime = 1200;
boilTime = 5400;
coolingTime = 120;
startpointTemperature = 30;
betaGlucanaseTemperature = 40;
debranchingTemperature = 40;
proteolyticTemperature = 50;
betaAmylaseTemperature = 60;
alphaAmylaseTemperature = 70;
mashoutTemperature = 80;
recirculationTemperature = 80;
spargeTemperature = 80;
boilTemperature = 100;
coolingTemperature = 25;
backToStatus();
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 );
break;
}
case eBeerProfileMenu_Trigo: {
beerProfile = eBeerProfile_Trigo;
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 = 62;
alphaAmylaseTemperature = 70;
mashoutTemperature = 78;
recirculationTemperature = 80;
spargeTemperature = 80;
boilTemperature = 100;
coolingTemperature = 25;
backToStatus();
eMenuType = eMenuType_Main;
repaint = true;
// 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, eMainMenu_Boil, MENU_SIZE_MAIN_MENU - 1, 0, 1, 0 ); xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenuPosition, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 );
break; break;
} }
case eMainMenu_Hops: { case eBeerProfileMenu_IPA: {
MainMenu_Hops(); beerProfile = eBeerProfile_IPA;
backToStatus();
menu_position[0] = -1; eMenuType = eMenuType_Main;
repaint = true;
// 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, eMainMenu_Hops, MENU_SIZE_MAIN_MENU - 1, 0, 1, 0 ); xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenuPosition, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 );
break; break;
} }
case eMainMenu_Cooling: { case eBeerProfileMenu_Belga: {
MainMenu_Cooling(); beerProfile = eBeerProfile_Belga;
backToStatus();
menu_position[0] = -1; eMenuType = eMenuType_Main;
repaint = true;
// 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, eMainMenu_Cooling, MENU_SIZE_MAIN_MENU - 1, 0, 1, 0 ); xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenuPosition, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 );
break; break;
} }
case eMainMenu_Purge: { case eBeerProfileMenu_Red: {
MainMenu_Purge(); beerProfile = eBeerProfile_Red;
menu_position[0] = -1; backToStatus();
eMenuType = eMenuType_Main;
repaint = true;
// 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, eMainMenu_Purge, MENU_SIZE_MAIN_MENU - 1, 0, 1, 0 ); xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenuPosition, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 );
break; break;
} }
case eMainMenu_Settings: { case eBeerProfileMenu_APA: {
MainMenu_Settings(); beerProfile = eBeerProfile_APA;
backToStatus();
menu_position[0] = -1; eMenuType = eMenuType_Main;
repaint = true;
// 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, eMainMenu_Settings, MENU_SIZE_MAIN_MENU - 1, 0, 1, 0 ); xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenuPosition, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 );
break; break;
} }
case eMainMenu_Back: { case eBeerProfileMenu_Custom: {
MainMenu_Back(); beerProfile = eBeerProfile_Custom;
menu_position[0] = -1; startpointTime = 120;
betaGlucanaseTime = 120;
debranchingTime = 120;
proteolyticTime = 120;
betaAmylaseTime = 120;
alphaAmylaseTime = 120;
mashoutTime = 120;
recirculationTime = 120;
spargeTime = 120;
boilTime = 120;
coolingTime = 120;
startpointTemperature = 50;
betaGlucanaseTemperature = 55;
debranchingTemperature = 60;
proteolyticTemperature = 65;
betaAmylaseTemperature = 70;
alphaAmylaseTemperature = 75;
mashoutTemperature = 80;
recirculationTemperature = 85;
spargeTemperature = 90;
boilTemperature = 95;
coolingTemperature = 100;
backToStatus();
eMenuType = eMenuType_Main;
repaint = true;
// 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, eMainMenu_Back, MENU_SIZE_MAIN_MENU - 1, 0, 1, 0 ); xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenuPosition, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 );
break;
}
case eBeerProfileMenu_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 );
break; break;
} }
default: { default: {
if(repaint) { }
// display menu
lcd.clear();
lcd.home (); // go home
lcd.print("Brewery Menu");
switch(rotaryEncoderVirtualPosition) {
case eMainMenu_GO: {
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print("-> GO ");
break;
}
case eMainMenu_STOP: {
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print("-> STOP ");
break;
}
case eMainMenu_Presets: {
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print("-> Presets ");
break;
}
case eMainMenu_Malt: {
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print("-> Malt ");
break;
}
case eMainMenu_Startpoint: {
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print("-> Startpoint ");
break;
}
case eMainMenu_BetaGlucanase: {
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print("-> BetaGlucanase");
break;
}
case eMainMenu_Debranching: {
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print("-> Debranching ");
break;
}
case eMainMenu_Proteolytic: {
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print("-> Proteolytic ");
break;
}
case eMainMenu_BetaAmylase: {
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print("-> Beta Amylase ");
break;
}
case eMainMenu_AlphaAmylase: {
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print("-> Alpha Amylase");
break;
}
case eMainMenu_Mashout: {
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print("-> Mashout ");
break;
}
case eMainMenu_Recirculation: {
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print("-> Recirculation");
break;
}
case eMainMenu_Sparge: {
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print("-> Sparge ");
break;
}
case eMainMenu_Boil: {
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print("-> Boil ");
break;
}
case eMainMenu_Hops: {
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print("-> Hops ");
break;
}
case eMainMenu_Cooling: {
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print("-> Cooling ");
break;
}
case eMainMenu_Purge: {
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print("-> Purge ");
break;
}
case eMainMenu_Settings: {
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print("-> Settings ");
break;
}
case eMainMenu_Back: {
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print("-> Back ");
break;
}
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, 0 );
}
}
repaint = false;
}
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
break;
}
}
} }
}
void MainMenu_GO() {
startBrewing();
xTransitionIntoStage_GlobalVariables( eCookingStage_Startpoint );
backToStatus();
}
void MainMenu_STOP() {
stopBrewing();
backToStatus();
}
void MainMenu_Presets() {
backToStatus();
}
void MainMenu_Malt() {
backToStatus();
}
void MainMenu_Startpoint() {
startpointTime = getTimer( startpointTime );
startpointTemperature = xSetGenericValue( startpointTemperature, 0, 120, "temperature", "*C" );
backToStatus();
}
void MainMenu_BetaGlucanase() {
betaGlucanaseTime = getTimer( betaGlucanaseTime );
betaGlucanaseTemperature = xSetGenericValue( betaGlucanaseTemperature, 0, 120, "temperature", "*C" );
backToStatus(); eBeerProfileMenuSelection = eBeerProfileMenu_NULL;
} }
void MainMenu_Debranching() { void runMainMenuSelection() {
debranchingTime = getTimer( debranchingTime ); switch(eMainMenuSelection) {
case eMainMenu_GO: {
debranchingTemperature = xSetGenericValue( debranchingTemperature, 0, 120, "temperature", "*C" ); finalYield = xSetGenericValue( finalYield, 0, 50, "Final Yield", "l" );
backToStatus();
}
void MainMenu_Proteolytic() {
proteolyticTime = getTimer( proteolyticTime );
proteolyticTemperature = xSetGenericValue( proteolyticTemperature, 0, 120, "temperature", "*C" );
backToStatus();
}
void MainMenu_BetaAmylase() {
betaAmylaseTime = getTimer( betaAmylaseTime );
betaAmylaseTemperature = xSetGenericValue( betaAmylaseTemperature, 0, 120, "temperature", "*C" );
backToStatus();
}
void MainMenu_AlphaAmylase() {
alphaAmylaseTime = getTimer( alphaAmylaseTime );
alphaAmylaseTemperature = xSetGenericValue( alphaAmylaseTemperature, 0, 120, "temperature", "*C" );
backToStatus();
}
void MainMenu_Mashout() { startBrewing();
mashoutTime = getTimer( mashoutTime );
mashoutTemperature = xSetGenericValue( mashoutTemperature, 0, 120, "temperature", "*C" );
backToStatus(); xSetupGlobalVariablesForStage( eCookingStage_Startpoint );
}
void MainMenu_Recirculation() { backToStatus();
recirculationTime = getTimer( recirculationTime );
// reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep
recirculationTemperature = xSetGenericValue( recirculationTemperature, 0, 120, "temperature", "*C" ); xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenuPosition, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 );
xPurgePump();
backToStatus(); break;
} }
case eMainMenu_STOP: {
stopBrewing();
void MainMenu_Sparge() { backToStatus();
spargeTime = getTimer( spargeTime );
// reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep
spargeTemperature = xSetGenericValue( spargeTemperature, 0, 120, "temperature", "*C" ); xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMainMenuPosition, MENU_SIZE_MAIN_MENU - 1, 1, 1, 0 );
break;
}
case eMainMenu_SKIP: {
cookTime = 0;
backToStatus(); backToStatus();
}
// 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 );
break;
}
case eMainMenu_BeerProfile: {
eMenuType = eMenuType_BeerProfile;
repaint = true;
// reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep
xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eBeerProfileMenuPosition, MENU_SIZE_PROFILES_MENU - 1, 1, 1, 0 );
break;
}
case eMainMenu_Stage: {
eMenuType = eMenuType_Stage;
repaint = true;
// reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep
xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eStageMenuPosition, MENU_SIZE_STAGE_MENU - 1, 1, 1, 0 );
break;
}
case eMainMenu_Malt: {
eMenuType = eMenuType_Malt;
repaint = true;
// reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep
xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eMaltMenuPosition, MENU_SIZE_MALT_MENU - 1, 1, 1, 0 );
break;
}
case eMainMenu_Hops: {
backToStatus();
// 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 );
break;
}
case eMainMenu_Clean: {
// Stop anything that might be still going on
xSafeHardwarePowerOff();
void MainMenu_Boil() { // Start at the Clean stage
boilTime = getTimer( boilTime ); startBrewing();
boilTemperature = xSetGenericValue( boilTemperature, 0, 120, "temperature", "*C" );
backToStatus(); xSetupGlobalVariablesForStage( eCookingStage_Clean );
}
void MainMenu_Hops() { backToStatus();
// 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 );
xPurgePump();
backToStatus(); break;
}
} case eMainMenu_Purge: {
// Stop anything that might be still going on
xSafeHardwarePowerOff();
void MainMenu_Cooling() { // Start at the Purge stage
coolingTime = getTimer( coolingTime ); startBrewing();
coolingTemperature = xSetGenericValue( coolingTemperature, 0, 120, "temperature", "*C" );
backToStatus(); xSetupGlobalVariablesForStage( eCookingStage_Purge );
}
void MainMenu_Purge() { backToStatus();
// Stop anything that might be still going on
xSafeHardwarePowerOff(); // 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 );
xPurgePump();
// Start at the Purge stage break;
startBrewing(); }
xTransitionIntoStage_GlobalVariables( eCookingStage_Purge ); case eMainMenu_Settings: {
eMenuType = eMenuType_Settings;
repaint = true;
backToStatus(); // reset operation state | INPUT : eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep
} xSetupRotaryEncoder( eRotaryEncoderMode_Menu, eSettingsMenuPosition, MENU_SIZE_SETTINGS_MENU - 1, 1, 1, 0 );
break;
}
case eMainMenu_Back: {
backToStatus();
// 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 );
void MainMenu_Settings() { break;
iPumpSpeed = xSetGenericValue( iPumpSpeed, 0, 255, "Pump Speed", "PWM" ); }
default: {
}
}
backToStatus(); eMainMenuSelection = eMainMenu_NULL;
} }
void MainMenu_Back() {
backToStatus();
}
void xCountTheTime( int temperatureRange ) { void xCountTheTime( int temperatureRange, boolean bAverageUpDown ) {
unsigned long now = millis(); unsigned long now = millis();
unsigned long elapsedTime = now - clockLastUpdate;
double temperatureCount = 0;
if( bAverageUpDown ) {
float tup = upPT100.getCurrentTemperature();
float tdown = downPT100.getCurrentTemperature();
if(tup > tdown) {
temperatureCount = tup;
}
else {
temperatureCount = tdown;
}
} else {
temperatureCount = basePT100.getCurrentTemperature();
}
// Check if the machine is in the right temperature range, for the current mode, // Check if the machine is in the right temperature range, for the current mode,
if(!(basePT100.getCurrentTemperature() > (cookTemperature - temperatureRange) && basePT100.getCurrentTemperature() < (cookTemperature + temperatureRange))) { //if(!( temperatureCount > (cookTemperature - temperatureRange) && temperatureCount < (cookTemperature + temperatureRange))) {
clockIgnore += now - clockStartTime - clockIgnore; float margin = temperatureRange;
if( cookTemperature >= 100.0 ) {
margin = 2.0;
}
if( temperatureCount < (cookTemperature - margin) ) {
clockIgnore += elapsedTime;
} }
// Calculate the remaining time on the clock // Calculate the remaining time on the clock
clockCounter = cookTime * 1000 - (now - clockStartTime - clockIgnore); clockCounter = cookTime * 1000 - (now - clockStartTime - clockIgnore);
#ifdef DEBUG_OFF if ( clockCounter < 0 ) {
clockCounter = 0;
}
clockLastUpdate = now;
#ifdef DEBUG_OFF
debugPrintFunction("xCountTheTime"); debugPrintFunction("xCountTheTime");
debugPrintVar("millis()", now); debugPrintVar("millis()", now);
debugPrintVar("cookTime", cookTime); debugPrintVar("cookTime", cookTime);
debugPrintVar("clockStartTime", clockStartTime); debugPrintVar("clockStartTime", clockStartTime);
debugPrintVar("clockIgnore", clockIgnore); debugPrintVar("clockIgnore", clockIgnore);
debugPrintVar("clockCounter", clockCounter); debugPrintVar("clockCounter", clockCounter);
#endif #endif
} }
bool isTimeLeft() { bool isTimeLeft() {
...@@ -1040,11 +1144,35 @@ double ulWattToWindowTime( double ulAppliedWatts ) { ...@@ -1040,11 +1144,35 @@ double ulWattToWindowTime( double ulAppliedWatts ) {
return (double)iWindowSize / 1000.0 * ulPulsesRequired * 1000.0 / HEATING_ELEMENT_AC_FREQUENCY_HZ; return (double)iWindowSize / 1000.0 * ulPulsesRequired * 1000.0 / HEATING_ELEMENT_AC_FREQUENCY_HZ;
} }
bool xRegulateTemperature() { bool xRegulateTemperature( boolean bAverageUpDown ) {
double difference = cookTemperature - basePT100.getCurrentTemperature(); double difference = 0;
bool overTemperature = false; bool overTemperature = false;
double wattage = 0.0; double wattage = 0.0;
if( bAverageUpDown ) {
float tbase = basePT100.getCurrentTemperature();
float tup = upPT100.getCurrentTemperature();
float tdown = downPT100.getCurrentTemperature();
if(tup > tdown) {
difference = cookTemperature - tup;
}
else {
difference = cookTemperature - tdown;
}
if (tbase > (cookTemperature + 2.0)) {
difference = 0.0;
}
if (tbase < (cookTemperature)) {
difference = cookTemperature - tbase;
}
} else {
difference = cookTemperature - basePT100.getCurrentTemperature();
}
// Deviation between the cook temperature set and the cook temperature measured // Deviation between the cook temperature set and the cook temperature measured
if( difference < 0.0 ) { if( difference < 0.0 ) {
difference = difference * (-1.0); difference = difference * (-1.0);
...@@ -1060,15 +1188,20 @@ bool xRegulateTemperature() { ...@@ -1060,15 +1188,20 @@ bool xRegulateTemperature() {
// turn it off // turn it off
wattage = 0.0; wattage = 0.0;
} else { } else {
if(difference <= 1) { if(difference <= 0.5) {
// pulse lightly at 500 watt // pulse lightly at 500 watt
wattage = 500.0; if(cookTemperature > 99.0) {
wattage = 1500.0;
}
else {
wattage = 500.0;
}
} else { } else {
if(difference <= 3) { if(difference <= 1.0) {
// pulse moderately at 1000 watt // pulse moderately at 1000 watt
wattage = 1000.0; wattage = 1000.0;
} else { } else {
if(difference <= 6) { if(difference <= 3.0) {
// pulse hardly at 2000 watt // pulse hardly at 2000 watt
wattage = 2000.0; wattage = 2000.0;
} else { } else {
...@@ -1088,11 +1221,13 @@ bool xRegulateTemperature() { ...@@ -1088,11 +1221,13 @@ bool xRegulateTemperature() {
// Apply wattage to the element at the right time // Apply wattage to the element at the right time
if( ulWattToWindowTime( wattage ) > (millis() - windowStartTime) ) { if( ulWattToWindowTime( wattage ) > (millis() - windowStartTime) ) {
digitalWrite(HEATING_ELEMENT_OUTPUT_PIN,HIGH); digitalWrite(HEATING_ELEMENT_OUTPUT_PIN,HIGH);
bStatusElement = true;
} else { } else {
digitalWrite(HEATING_ELEMENT_OUTPUT_PIN,LOW); digitalWrite(HEATING_ELEMENT_OUTPUT_PIN,LOW);
bStatusElement = false;
} }
#ifdef DEBUG_OFF #ifdef DEBUG_OFF
//debugPrintFunction("xRegulateTemperature"); //debugPrintFunction("xRegulateTemperature");
debugPrintVar("difference", difference); debugPrintVar("difference", difference);
//debugPrintVar("overTemperature", overTemperature); //debugPrintVar("overTemperature", overTemperature);
...@@ -1101,23 +1236,34 @@ bool xRegulateTemperature() { ...@@ -1101,23 +1236,34 @@ bool xRegulateTemperature() {
//debugPrintVar("millis()", millis()); //debugPrintVar("millis()", millis());
//debugPrintVar("windowStartTime", windowStartTime); //debugPrintVar("windowStartTime", windowStartTime);
//debugPrintVar("test", ulWattToWindowTime( wattage ) > (millis() - windowStartTime) ); //debugPrintVar("test", ulWattToWindowTime( wattage ) > (millis() - windowStartTime) );
#endif #endif
}
void xPurgePump() {
for(int i = 0; i < 2; i++) {
analogWrite(PUMP_PIN, PUMP_SPEED_MAX); // analogWrite values from 0 to 255
delay(1000);
analogWrite(PUMP_PIN, PUMP_SPEED_STOP); // analogWrite values from 0 to 255
delay(1500);
}
} }
bool xRegulatePumpSpeed() { bool xRegulatePumpSpeed() {
analogWrite(PUMP_PIN, iPumpSpeed); // analogWrite values from 0 to 255 // analogWrite(PUMP_PIN, iPumpSpeed); // analogWrite values from 0 to 255
if(basePT100.getCurrentTemperature() > PUMP_TEMPERATURE_MAX_OPERATION) {
analogWrite(PUMP_PIN, PUMP_SPEED_STOP); // analogWrite values from 0 to 255
if( iPumpSpeed ) { basePT100.setSampleDeviation( 0.0 );
//basePT100.setPower( PT100_BASE_DARLINGTON_ADC_VMAX, PT100_BASE_DARLINGTON_VS ); upPT100.setSampleDeviation( 0.0 );
basePT100.setMeasuredTemperatureDeviation( -0.90 ); downPT100.setSampleDeviation( 0.0 );
upPT100.setMeasuredTemperatureDeviation( -1.00 );
downPT100.setMeasuredTemperatureDeviation( -1.10 );
} }
else { else {
//basePT100.setPower( PT100_BASE_DEFAULT_ADC_VMAX, PT100_BASE_DEFAULT_VS ); analogWrite(PUMP_PIN, iPumpSpeed); // analogWrite values from 0 to 255
basePT100.setMeasuredTemperatureDeviation( 0.0 );
upPT100.setMeasuredTemperatureDeviation( 0.0 ); basePT100.setSampleDeviation( -2.0 );
downPT100.setMeasuredTemperatureDeviation( 0.0 ); upPT100.setSampleDeviation( -2.0 );
downPT100.setSampleDeviation( -2.0 );
} }
} }
...@@ -1125,7 +1271,16 @@ void xWarnClockEnded() { ...@@ -1125,7 +1271,16 @@ void xWarnClockEnded() {
sing(MELODY_SUPER_MARIO_START, PIEZO_PIN); sing(MELODY_SUPER_MARIO_START, PIEZO_PIN);
} }
void xWarnCookEnded() {
sing(MELODY_UNDERWORLD_SHORT, PIEZO_PIN);
}
void xStageFirstRun( int stageTime, int stageTemperature, int stagePumpSpeed, eCookingStages stage ) { void xStageFirstRun( int stageTime, int stageTemperature, int stagePumpSpeed, eCookingStages stage ) {
#ifdef DEBUG_OFF
debugPrintFunction("xStageFirstRun");
debugPrintVar("cookingStage", stage);
#endif
// Set Stage // Set Stage
bStageFirstRun = true; bStageFirstRun = true;
cookingStage = stage; cookingStage = stage;
...@@ -1138,85 +1293,188 @@ void xStageFirstRun( int stageTime, int stageTemperature, int stagePumpSpeed, eC ...@@ -1138,85 +1293,188 @@ void xStageFirstRun( int stageTime, int stageTemperature, int stagePumpSpeed, eC
// Reset the clock // Reset the clock
clockStartTime = millis(); clockStartTime = millis();
clockLastUpdate = clockStartTime;
clockIgnore = 0; clockIgnore = 0;
// Set the pump speed // Set the pump speed
iPumpSpeed = stagePumpSpeed; iPumpSpeed = stagePumpSpeed;
} }
void xTransitionIntoStage_GlobalVariables(eCookingStages nextStage) { void xSetupGlobalVariablesForStage(eCookingStages nextStage) {
#ifdef DEBUG_OFF
debugPrintFunction("xSetupGlobalVariablesForStage");
debugPrintVar("cookingStage", nextStage);
#endif
// Operate the machine according to the current mode // Operate the machine according to the current mode
switch(nextStage) { switch(nextStage) {
case eCookingStage_Startpoint: { 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;
}
default: {
}
}
// Make sure there is water
xWaitForAction("Water", "Make sure there is water in the machine before start cooking.");
repaint = true;
// A basic operation for a basic stage // A basic operation for a basic stage
xStageFirstRun( startpointTime, startpointTemperature, 255, eCookingStage_Startpoint ); xStageFirstRun( startpointTime, startpointTemperature, PUMP_SPEED_MAX, eCookingStage_Startpoint );
break; break;
} }
case eCookingStage_BetaGlucanase: { 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;
}
default: {
}
}
// A basic operation for a basic stage // A basic operation for a basic stage
xStageFirstRun( betaGlucanaseTime, betaGlucanaseTemperature, 255, eCookingStage_BetaGlucanase ); xStageFirstRun( betaGlucanaseTime, betaGlucanaseTemperature, PUMP_SPEED_MAX, eCookingStage_BetaGlucanase );
break; break;
} }
case eCookingStage_Debranching: { case eCookingStage_Debranching: {
// A basic operation for a basic stage // A basic operation for a basic stage
xStageFirstRun( debranchingTime, debranchingTemperature, 255, eCookingStage_Debranching ); xStageFirstRun( debranchingTime, debranchingTemperature, PUMP_SPEED_MAX, eCookingStage_Debranching );
break; break;
} }
case eCookingStage_Proteolytic: { case eCookingStage_Proteolytic: {
// A basic operation for a basic stage // A basic operation for a basic stage
xStageFirstRun( proteolyticTime, proteolyticTemperature, 255, eCookingStage_Proteolytic ); xStageFirstRun( proteolyticTime, proteolyticTemperature, PUMP_SPEED_MAX, eCookingStage_Proteolytic );
break; break;
} }
case eCookingStage_BetaAmylase: { case eCookingStage_BetaAmylase: {
// A basic operation for a basic stage // A basic operation for a basic stage
xStageFirstRun( betaAmylaseTime, betaAmylaseTemperature, 255, eCookingStage_BetaAmylase ); xStageFirstRun( betaAmylaseTime, betaAmylaseTemperature, PUMP_SPEED_MAX, eCookingStage_BetaAmylase );
break; break;
} }
case eCookingStage_AlphaAmylase: { case eCookingStage_AlphaAmylase: {
// A basic operation for a basic stage // A basic operation for a basic stage
xStageFirstRun( alphaAmylaseTime, alphaAmylaseTemperature, 255, eCookingStage_AlphaAmylase ); xStageFirstRun( alphaAmylaseTime, alphaAmylaseTemperature, PUMP_SPEED_MAX, eCookingStage_AlphaAmylase );
break; break;
} }
case eCookingStage_Mashout: { case eCookingStage_Mashout: {
// A basic operation for a basic stage // A basic operation for a basic stage
xStageFirstRun( mashoutTime, mashoutTemperature, 255, eCookingStage_Mashout ); xStageFirstRun( mashoutTime, mashoutTemperature, PUMP_SPEED_MAX, eCookingStage_Mashout );
break; break;
} }
case eCookingStage_Recirculation: { case eCookingStage_Recirculation: {// Make sure there is water
xWaitForAction("Sparge Water", "Start heating your sparge water.");
repaint = true;
// A basic operation for a basic stage // A basic operation for a basic stage
xStageFirstRun( recirculationTime, recirculationTemperature, 255, eCookingStage_Recirculation ); xStageFirstRun( recirculationTime, recirculationTemperature, PUMP_SPEED_MAX, eCookingStage_Recirculation );
break; break;
} }
case eCookingStage_Sparge: { case eCookingStage_Sparge: {
// Make sure there is water
xWaitForAction("Sparge Water", "Start pouring the sparge water.");
repaint = true;
// A basic operation for a basic stage // A basic operation for a basic stage
xStageFirstRun( spargeTime, spargeTemperature, 255, eCookingStage_Sparge ); xStageFirstRun( spargeTime, spargeTemperature, PUMP_SPEED_MAX, eCookingStage_Sparge );
break; break;
} }
case eCookingStage_Boil: { 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;
}
default: {
xWaitForAction("Hops", "Add the hops in the right order, at the right time.");
}
}
repaint = true;
// A basic operation for a basic stage // A basic operation for a basic stage
xStageFirstRun( boilTime, boilTemperature, 255, eCookingStage_Boil ); xStageFirstRun( boilTime, boilTemperature, PUMP_SPEED_MAX, eCookingStage_Boil );
break; break;
} }
case eCookingStage_Cooling: { 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
xStageFirstRun( coolingTime, coolingTemperature, PUMP_SPEED_MAX, 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 // A basic operation for a basic stage
xStageFirstRun( coolingTime, coolingTemperature, 255, eCookingStage_Cooling ); xStageFirstRun( cleaningTime, cleaningTemperature, PUMP_SPEED_MAX, eCookingStage_Clean );
break; break;
} }
case eCookingStage_Purge: { case eCookingStage_Purge: {
// A basic operation for a basic stage // A basic operation for a basic stage
xStageFirstRun( 0, 0, 255, eCookingStage_Purge ); xStageFirstRun( 0, 0, PUMP_SPEED_MAX, eCookingStage_Purge );
xRegulatePumpSpeed(); xRegulatePumpSpeed();
...@@ -1224,19 +1482,14 @@ void xTransitionIntoStage_GlobalVariables(eCookingStages nextStage) { ...@@ -1224,19 +1482,14 @@ void xTransitionIntoStage_GlobalVariables(eCookingStages nextStage) {
} }
case eCookingStage_Done: { case eCookingStage_Done: {
// A basic operation for a basic stage // A basic operation for a basic stage
xStageFirstRun( 0, 0, 0, eCookingStage_Done ); xStageFirstRun( 0, 0, PUMP_SPEED_STOP, eCookingStage_Done );
break; break;
} }
default : {
// A basic operation for a basic stage
xStageFirstRun( 0, 0, 0, eCookingStage_Done );
}
} }
} }
void xTransitionIntoStage(eCookingStages nextStage) { void xTransitionIntoStage(eCookingStages nextStage) {
// Turn off all hardware that can damage itself if the machine is not cooking // Turn off all hardware that can damage itself if the machine is not cooking
xSafeHardwarePowerOff(); xSafeHardwarePowerOff();
...@@ -1244,10 +1497,10 @@ void xTransitionIntoStage(eCookingStages nextStage) { ...@@ -1244,10 +1497,10 @@ void xTransitionIntoStage(eCookingStages nextStage) {
xWarnClockEnded(); xWarnClockEnded();
// Reset global stage variables // Reset global stage variables
xTransitionIntoStage_GlobalVariables( nextStage ); xSetupGlobalVariablesForStage( nextStage );
} }
void xBasicStageOperation( int iStageTime, int iStageTemperature, int iStageTemperatureRange, eCookingStages nextStage ) { void xBasicStageOperation( int iStageTime, int iStageTemperature, int iStageTemperatureRange, eCookingStages nextStage, boolean bAverageUpDown ) {
if(bStageFirstRun) { if(bStageFirstRun) {
// Don't run this again // Don't run this again
bStageFirstRun = false; bStageFirstRun = false;
...@@ -1257,7 +1510,7 @@ void xBasicStageOperation( int iStageTime, int iStageTemperature, int iStageTemp ...@@ -1257,7 +1510,7 @@ void xBasicStageOperation( int iStageTime, int iStageTemperature, int iStageTemp
// When the stage should be skipped // When the stage should be skipped
if( iStageTime == 0) { if( iStageTime == 0) {
// Continue to the next stage // Continue to the next stage
//xTransitionIntoStage_GlobalVariables( nextStage ); //xSetupGlobalVariablesForStage( nextStage );
// There is nothing to do, in this stage // There is nothing to do, in this stage
return; return;
...@@ -1268,16 +1521,24 @@ void xBasicStageOperation( int iStageTime, int iStageTemperature, int iStageTemp ...@@ -1268,16 +1521,24 @@ void xBasicStageOperation( int iStageTime, int iStageTemperature, int iStageTemp
} }
} else { } else {
// Account for time spent at the target temperature | Input 1: range in ºC within which the target temperature is considered to be reached // 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 ); #ifdef DEBUG_OFF
xCountTheTime( iStageTemperatureRange, false );
#else
xCountTheTime( iStageTemperatureRange, bAverageUpDown );
#endif
if( isTimeLeft() ) { if( isTimeLeft() ) {
// Do temperature control // Do temperature control
xRegulateTemperature(); xRegulateTemperature( bAverageUpDown );
// Do flow control // Do flow control
xRegulatePumpSpeed(); xRegulatePumpSpeed();
} else { } else {
#ifdef DEBUG_OFF
debugPrintFunction("xBasicStageOperation");
debugPrintVar("clockCounter", clockCounter);
#endif
// Continue to the next stage // Continue to the next stage
xTransitionIntoStage( nextStage ); xTransitionIntoStage( nextStage );
...@@ -1289,20 +1550,33 @@ void xBasicStageOperation( int iStageTime, int iStageTemperature, int iStageTemp ...@@ -1289,20 +1550,33 @@ void xBasicStageOperation( int iStageTime, int iStageTemperature, int iStageTemp
return; return;
} }
void xWarnCookEnded() { void xManageMachineSystems() {
sing(MELODY_UNDERWORLD, PIEZO_PIN);
}
void operateMachine() { #ifdef DEBUG
Serial.print(millis());
Serial.print(",");
if(cooking) {
Serial.print("1");
}
else {
Serial.print("0");
}
Serial.print(",");
Serial.print(cookTemperature);
Serial.print(",");
if(bStatusElement) {
Serial.print("1");
}
else {
Serial.print("0");
}
Serial.print(",");
#endif
// Measure temperature, for effect // Measure temperature, for effect
//analogWrite(6, 0); basePT100.measure1(false, false);
//delay(1); upPT100.measure1(false, false);
basePT100.measure(); downPT100.measure1(true, false);
upPT100.measure();
downPT100.measure();
Serial.println(" ");
//analogWrite(6, iPumpSpeed);
// If cooking is done, return (this is a nice place to double check safety and ensure the cooking parts aren't on. // If cooking is done, return (this is a nice place to double check safety and ensure the cooking parts aren't on.
if(!cooking) { if(!cooking) {
...@@ -1315,67 +1589,73 @@ void operateMachine() { ...@@ -1315,67 +1589,73 @@ void operateMachine() {
switch(cookingStage) { switch(cookingStage) {
case eCookingStage_Startpoint: { case eCookingStage_Startpoint: {
// A basic operation for a basic stage // A basic operation for a basic stage
xBasicStageOperation( startpointTime, startpointTemperature, 1, eCookingStage_BetaGlucanase ); xBasicStageOperation( startpointTime, startpointTemperature, 1, eCookingStage_BetaGlucanase, false);
break; break;
} }
case eCookingStage_BetaGlucanase: { case eCookingStage_BetaGlucanase: {
// A basic operation for a basic stage // A basic operation for a basic stage
xBasicStageOperation( betaGlucanaseTime, betaGlucanaseTemperature, 1, eCookingStage_Debranching ); xBasicStageOperation( betaGlucanaseTime, betaGlucanaseTemperature, 0, eCookingStage_Debranching, true );
break; break;
} }
case eCookingStage_Debranching: { case eCookingStage_Debranching: {
// A basic operation for a basic stage // A basic operation for a basic stage
xBasicStageOperation( debranchingTime, debranchingTemperature, 1, eCookingStage_Proteolytic ); xBasicStageOperation( debranchingTime, debranchingTemperature, 0, eCookingStage_Proteolytic, true );
break; break;
} }
case eCookingStage_Proteolytic: { case eCookingStage_Proteolytic: {
// A basic operation for a basic stage // A basic operation for a basic stage
xBasicStageOperation( proteolyticTime, proteolyticTemperature, 1, eCookingStage_BetaAmylase ); xBasicStageOperation( proteolyticTime, proteolyticTemperature, 0, eCookingStage_BetaAmylase, true );
break; break;
} }
case eCookingStage_BetaAmylase: { case eCookingStage_BetaAmylase: {
// A basic operation for a basic stage // A basic operation for a basic stage
xBasicStageOperation( betaAmylaseTime, betaAmylaseTemperature, 1, eCookingStage_AlphaAmylase ); xBasicStageOperation( betaAmylaseTime, betaAmylaseTemperature, 0, eCookingStage_AlphaAmylase, true );
break; break;
} }
case eCookingStage_AlphaAmylase: { case eCookingStage_AlphaAmylase: {
// A basic operation for a basic stage // A basic operation for a basic stage
xBasicStageOperation( alphaAmylaseTime, alphaAmylaseTemperature, 1, eCookingStage_Mashout ); xBasicStageOperation( alphaAmylaseTime, alphaAmylaseTemperature, 0, eCookingStage_Mashout, true );
break; break;
} }
case eCookingStage_Mashout: { case eCookingStage_Mashout: {
// A basic operation for a basic stage // A basic operation for a basic stage
xBasicStageOperation( mashoutTime, mashoutTemperature, 1, eCookingStage_Recirculation ); xBasicStageOperation( mashoutTime, mashoutTemperature, 0, eCookingStage_Recirculation, true );
break; break;
} }
case eCookingStage_Recirculation: { case eCookingStage_Recirculation: {
// A basic operation for a basic stage // A basic operation for a basic stage
xBasicStageOperation( recirculationTime, recirculationTemperature, 1, eCookingStage_Sparge ); xBasicStageOperation( recirculationTime, recirculationTemperature, 0, eCookingStage_Sparge, true );
break; break;
} }
case eCookingStage_Sparge: { case eCookingStage_Sparge: {
// A basic operation for a basic stage // A basic operation for a basic stage
xBasicStageOperation( spargeTime, spargeTemperature, 1, eCookingStage_Boil ); xBasicStageOperation( spargeTime, spargeTemperature, 1, eCookingStage_Boil, false );
break; break;
} }
case eCookingStage_Boil: { case eCookingStage_Boil: {
// A basic operation for a basic stage // A basic operation for a basic stage
xBasicStageOperation( boilTime, boilTemperature, 1, eCookingStage_Cooling ); xBasicStageOperation( boilTime, boilTemperature, 2, eCookingStage_Cooling, false );
break; break;
} }
case eCookingStage_Cooling: { case eCookingStage_Cooling: {
// A basic operation for a basic stage // A basic operation for a basic stage
xBasicStageOperation( coolingTime, coolingTemperature, 1, eCookingStage_Done ); xBasicStageOperation( coolingTime, coolingTemperature, 1, eCookingStage_Done, false );
break;
}
case eCookingStage_Clean: {
// A basic operation for a basic stage
xBasicStageOperation( cleaningTime, cleaningTemperature, 1, eCookingStage_Done, false );
break; break;
} }
...@@ -1388,12 +1668,17 @@ void operateMachine() { ...@@ -1388,12 +1668,17 @@ void operateMachine() {
break; break;
} }
default : { case eCookingStage_Done: {
// Update state // Update cooking state
cooking = false; stopBrewing();
// Ask for screen refresh
repaint = true;
// Warn the user that the cooking is done // Warn the user that the cooking is done
xWarnCookEnded(); xWarnCookEnded();
break;
} }
} }
} }
...@@ -1445,7 +1730,7 @@ int getTimer(int init) { ...@@ -1445,7 +1730,7 @@ int getTimer(int init) {
break; break;
} else { } else {
// Don't forget to keep an eye on the cooking // Don't forget to keep an eye on the cooking
operateMachine(); xManageMachineSystems();
} }
// display current timer // display current timer
...@@ -1500,7 +1785,7 @@ int getTemperature(int init) { ...@@ -1500,7 +1785,7 @@ int getTemperature(int init) {
break; break;
} else { } else {
// Don't forget to keep an eye on the cooking // Don't forget to keep an eye on the cooking
operateMachine(); xManageMachineSystems();
} }
// display current timer // display current timer
...@@ -1555,7 +1840,7 @@ int xSetGenericValue(int init, int min, int max, char *valueName, char *unit) { ...@@ -1555,7 +1840,7 @@ int xSetGenericValue(int init, int min, int max, char *valueName, char *unit) {
break; break;
} else { } else {
// Don't forget to keep an eye on the cooking // Don't forget to keep an eye on the cooking
operateMachine(); xManageMachineSystems();
} }
// Check if there was an update by the rotary encoder // Check if there was an update by the rotary encoder
...@@ -1584,40 +1869,43 @@ int xSetGenericValue(int init, int min, int max, char *valueName, char *unit) { ...@@ -1584,40 +1869,43 @@ int xSetGenericValue(int init, int min, int max, char *valueName, char *unit) {
// ###################### Set Variables ################################################## // ###################### Set Variables ##################################################
void lcdPrint(String title, String message) { void xWaitForAction(String title, String message) {
int messageLength = message.length(); while(true) {
// Check if pushbutton is pressed
lcd.clear(); if ( digitalRead(ROTARY_ENCODER_SW_PIN) ) {
// Wait until switch is released
// print title while ( digitalRead(ROTARY_ENCODER_SW_PIN) ) {}
lcd.home();
lcd.print(title); // debounce
delay( 10 );
// print message
if(messageLength <= LCD_HORIZONTAL_RESOLUTION) { // Job is done, break the circle
lcd.setCursor(0,LCD_VERTICAL_RESOLUTION-1); break;
lcd.print(message); } else {
delay(1000); sing(BUZZ_1, PIEZO_PIN);
}
// print scrolling message // Print the message
else { if(! lcdPrint(&lcd, title, message)) {
String output_message = " "; break;
output_message += message; }
messageLength = output_message.length();
// Adjust the message size for proper printing
if ( messageLength & 1 == 1 ) {
output_message+=" ";
messageLength+=2;
}
// print scrolling message
for (int cursor = 0; cursor < messageLength - LCD_HORIZONTAL_RESOLUTION; cursor+=2) {
lcd.setCursor(0,LCD_VERTICAL_RESOLUTION-1);
lcd.print(output_message.substring(cursor, cursor+16));
delay(500);
} }
} }
} }
boolean gotButtonPress(int iPin) {
boolean ret = false;
if ((digitalRead(iPin))) { // check if pushbutton is pressed
ret = true;
while (digitalRead(iPin)) {} // wait til switch is released
delay(10); // debounce
}
return ret;
}
void cleanSerialMonitor() {
for (int i = 0; i < 40; i++) {
Serial.println();
}
}
\ No newline at end of file
/*
debug.h - Debug functions.
Created by João Lino, September 25, 2015.
Released into the public domain.
*/
#ifndef CONFIG_h
#define CONFIG_h
// ######################### SETTINGS #########################
#define SETTING_CLEANING_TIME 1200 //1200
#define SETTING_CLEANING_TEMPERATURE 45 //45
// ++++++++++++++++++++++++ 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
// ++++++++++++++++++++++++ Temperature ++++++++++++++++++++++++
#define PT100_BASE_INPUT_PIN A4
#define PT100_BASE_OUTPUT_PIN 32
#define PT100_BASE_INPUT_R_PIN A7
#define PT100_BASE_OUTPUT_R_PIN 7
#define PT100_BASE_TIME_BETWEEN_READINGS 1
#define PT100_UP_INPUT_PIN A5
#define PT100_UP_OUTPUT_PIN 30
#define PT100_UP_INPUT_R_PIN A8
#define PT100_UP_OUTPUT_R_PIN 9
#define PT100_UP_TIME_BETWEEN_READINGS 1
#define PT100_DOWN_INPUT_PIN A6
#define PT100_DOWN_OUTPUT_PIN 31
#define PT100_DOWN_INPUT_R_PIN A9
#define PT100_DOWN_OUTPUT_R_PIN 8
#define PT100_DOWN_TIME_BETWEEN_READINGS 1
#define PT100_BASE_DEFAULT_ADC_VMAX 1.1
#define PT100_BASE_DEFAULT_VS 5.0
#define PT100_BASE_DEFAULT_R1_RESISTENCE 605.2
#define PT100_BASE_DEFAULT_R2_RESISTENCE 605.2
#define PT100_UP_DEFAULT_ADC_VMAX 1.1
#define PT100_UP_DEFAULT_VS 5.0
#define PT100_UP_DEFAULT_R1_RESISTENCE 630.0 //620.0
#define PT100_UP_DEFAULT_R2_RESISTENCE 610.0
#define PT100_DOWN_DEFAULT_ADC_VMAX 1.1
#define PT100_DOWN_DEFAULT_VS 5.0
#define PT100_DOWN_DEFAULT_R1_RESISTENCE 616.0
#define PT100_DOWN_DEFAULT_R2_RESISTENCE 611.0
// ++++++++++++++++++++++++ Mixer ++++++++++++++++++++++++
//#define MIXER_PIN 12
//#define MIXER_MAX_POSITION 255
// ++++++++++++++++++++++++ Pump ++++++++++++++++++++++++
#define PIEZO_PIN 25
// ++++++++++++++++++++++++ Pump ++++++++++++++++++++++++
#define PUMP_PIN 6
#define PUMP_TEMPERATURE_MAX_OPERATION 90
#define PUMP_SPEED_STOP 0
#define PUMP_SPEED_SLOW 64
#define PUMP_SPEED_AVERAGE 128
#define PUMP_SPEED_FAST 192
#define PUMP_SPEED_MAX 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 50 //20 // 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_SIZE_MAIN_MENU 12
#define MENU_SIZE_PROFILES_MENU 9
#define MENU_SIZE_STAGE_MENU 13
#define MENU_SIZE_MALT_MENU 4
#define MENU_SIZE_SETTINGS_MENU 5
#define SETTING_SERIAL_MONITOR_BAUD_RATE 9600
#define SETTING_SERIAL_MONITOR_WELCOME_MESSAGE "Let's start Brewing!"
// ######################### LIBRARIES #########################
// ++++++++++++++++++++++++ LiquidCrystal_I2C ++++++++++++++++++++++++
#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
#endif
\ No newline at end of file
/*
debug.h - Debug functions.
Created by João Lino, September 25, 2015.
Released into the public domain.
*/
#ifndef DEBUG_h
#define DEBUB_h
// ######################### TEMPLATES #########################
template <class T> void debugPrintVar( char *name, const T& value );
template <class T> void debugPrintVar( char *name, const T& value ) {
Serial.print("[");
Serial.print(name);
Serial.print(":");
Serial.print(value);
Serial.println("]");
}
void debugPrintFunction( char *name ) {
Serial.print("++++++++++++++++++++++++ ");
Serial.print(name);
Serial.println("++++++++++++++++++++++++");
}
#endif
\ No newline at end of file
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