A State Machine for my Arduino Beer Kettle Temperature Display
// LCD SHIELD | |
// include the library code: | |
#include <Wire.h> | |
#include <utility/Adafruit_MCP23017.h> | |
#include <Adafruit_RGBLCDShield.h> | |
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield(); | |
#define OFF 0x0 | |
#define RED 0x1 | |
#define YELLOW 0x3 | |
#define GREEN 0x2 | |
#define TEAL 0x6 | |
#define BLUE 0x4 | |
#define VIOLET 0x5 | |
#define WHITE 0x7 | |
int const tempSenPin = A0; | |
// Temperature Values | |
float tempSenValue = 0; | |
float tempCalibrationAdjustment = 0; | |
int tempSenInterval = 500; | |
bool isDegreeF = 1; | |
long lastTempMillis = 0; // store the last time the temp was checked | |
// Target Values | |
int targetValue = 158; // Degrees F | |
// Tollerance Values | |
int tolerance = 5; | |
int minTempRange = 0; | |
float minMidTempRange = 25; | |
float maxMidTempRange = 75; | |
int maxTempRange = 100; | |
// Colour LED Values | |
int coldLEDPin = 8; | |
int goodLEDPin = 9; | |
int hotLEDPin = 10; | |
bool coldLEDState = 0; | |
bool goodLEDState = 0; | |
bool hotLEDState = 0; | |
// Menu Values | |
int menuPosition = 1; | |
long btnDelay = 600; | |
long previousBtnMillis = 0; // store the last time a button was pressed | |
void setup() { | |
// LCD Shield | |
lcd.begin(16, 2); | |
lcd.print("TEST MODE"); | |
lcd.setBacklight(RED); | |
// Temp Probe | |
pinMode(tempSenPin, INPUT); | |
// LED Pins | |
pinMode(coldLEDPin, OUTPUT); | |
pinMode(goodLEDPin, OUTPUT); | |
pinMode(hotLEDPin, OUTPUT); | |
// Turn on All LEDS | |
lcd.setCursor(0,1); | |
lcd.print("ALL LED ON"); | |
digitalWrite(coldLEDPin, HIGH); | |
digitalWrite(goodLEDPin, HIGH); | |
digitalWrite(hotLEDPin, HIGH); | |
delay(2000); | |
digitalWrite(coldLEDPin, LOW); | |
digitalWrite(goodLEDPin, LOW); | |
digitalWrite(hotLEDPin, LOW); | |
lcd.clear(); | |
lcd.setBacklight(WHITE); | |
lcd.setCursor(0,0); | |
lcd.print("Starting"); | |
delay(1000); | |
lcd.clear(); | |
} // close setup | |
void loop() { | |
unsigned long currentMillis = millis(); | |
// Handle Buttons | |
uint8_t buttons = lcd.readButtons(); | |
// Select Button Returns to Current Temp Screen | |
if ((buttons == BUTTON_SELECT) && ((currentMillis - previousBtnMillis) >= btnDelay)) { | |
menuPosition = 1; | |
previousBtnMillis = currentMillis; // Remember the time | |
lcd.clear(); | |
} // close BUTTON_SELECT | |
// Cycle Left through the Menu | |
if ((buttons == BUTTON_LEFT) && ((currentMillis - previousBtnMillis) >= btnDelay)) { | |
menuPosition = menuPosition - 1; | |
previousBtnMillis = currentMillis; // Remember the time | |
lcd.clear(); | |
} // close BUTTON_LEFT | |
// Cycle Right through the Menu | |
if ((buttons == BUTTON_RIGHT) && ((currentMillis - previousBtnMillis) >= btnDelay)) { | |
menuPosition = menuPosition + 1; | |
previousBtnMillis = currentMillis; // Remember the time | |
lcd.clear(); | |
} // close BUTTON_RIGHT | |
// Adjust Menu Position to Cycle Through the Menu | |
if (menuPosition > 4) { menuPosition = 1; } | |
if (menuPosition < 1) { menuPosition = 4; } | |
// If this is Menu 2 (Target Value), Accept UP and DOWN buttons | |
if (menuPosition == 2) { | |
if ( | |
(buttons == BUTTON_UP) && | |
((currentMillis - previousBtnMillis) >= btnDelay) | |
) { | |
previousBtnMillis = currentMillis; | |
targetValue = targetValue + 1; | |
lcd.clear(); | |
} // close BUTTON_UP | |
if ( | |
(buttons == BUTTON_DOWN) && | |
((currentMillis - previousBtnMillis) >= btnDelay) | |
) { | |
previousBtnMillis = currentMillis; | |
targetValue = targetValue - 1; | |
lcd.clear(); | |
} // close BUTTON_DOWN | |
} // close menuPosition 2 | |
// If this is Menu 3 (Tolerance Value), Accept UP and DOWN buttons | |
if (menuPosition == 3) { | |
if ( | |
(buttons == BUTTON_UP) && | |
((currentMillis - previousBtnMillis) >= btnDelay) | |
) { | |
previousBtnMillis = currentMillis; | |
tolerance = tolerance + 1; | |
lcd.clear(); | |
} // close BUTTON_UP | |
if ( | |
(buttons == BUTTON_DOWN) && | |
((currentMillis - previousBtnMillis) >= btnDelay) | |
) { | |
previousBtnMillis = currentMillis; | |
tolerance = tolerance - 1; | |
lcd.clear(); | |
} // close BUTTON_DOWN | |
} // close menuPosition 3 | |
// If this is Menu 4 (Unit of Measure), Accept UP and DOWN buttons | |
if (menuPosition == 4) { | |
if ( | |
((buttons == BUTTON_UP) || (buttons == BUTTON_DOWN)) && | |
((currentMillis - previousBtnMillis) >= btnDelay) | |
) { | |
isDegreeF = !isDegreeF; | |
if (isDegreeF) { | |
tempSenValue = int(toFahrenheit(tempSenValue)); | |
targetValue = int(toFahrenheit(targetValue)); | |
} else { | |
tempSenValue = int(toCelsius(tempSenValue)); | |
targetValue = int(toCelsius(targetValue)); | |
} | |
previousBtnMillis = currentMillis; | |
lcd.clear(); | |
} // close BUTTON_UP or BUTTON_DOWN | |
} // close menuPosition 4 | |
// Read Temp Sensor | |
if ((currentMillis - lastTempMillis) >= tempSenInterval) { | |
// Current Sensor reads in Celsius | |
tempSenValue = analogRead(tempSenPin); | |
tempSenValue = tempSenValue + tempCalibrationAdjustment; | |
if (isDegreeF) { | |
tempSenValue = toFahrenheit(tempSenValue); | |
} | |
// Set values for triggering the LED | |
minTempRange = targetValue - tolerance; | |
minMidTempRange = minTempRange + (tolerance / 2); | |
maxTempRange = targetValue + tolerance; | |
maxMidTempRange = maxTempRange - (tolerance / 2); | |
lastTempMillis = currentMillis; | |
} // close if tempSenInterval | |
// Set Menu Display | |
if (menuPosition == 1) { | |
lcd.setBacklight(TEAL); | |
lcd.setCursor(0,0); | |
lcd.print("Current Temp"); | |
lcd.setCursor(0,1); | |
lcd.print(int(tempSenValue)); | |
if (isDegreeF) { | |
lcd.print(" F"); | |
} else { | |
lcd.print(" C"); | |
} | |
} // close if (menuPosition == 1) | |
if (menuPosition == 2) { | |
lcd.setBacklight(GREEN); | |
lcd.setCursor(0,0); | |
lcd.print("Target Temp"); | |
lcd.setCursor(0,1); | |
lcd.print(targetValue); | |
if (isDegreeF) { | |
lcd.print(" F"); | |
} else { | |
lcd.print(" C"); | |
} | |
} // close if (menuPosition == 2) | |
if (menuPosition == 3) { | |
lcd.setBacklight(BLUE); | |
lcd.setCursor(0,0); | |
lcd.print("Tolerance"); | |
lcd.setCursor(0,1); | |
lcd.print(tolerance); | |
lcd.print(" Degrees"); | |
} // close if (menuPosition == 3) | |
if (menuPosition == 4) { | |
lcd.setBacklight(VIOLET); | |
lcd.setCursor(0,0); | |
lcd.print("Set Unit"); | |
lcd.setCursor(0,1); | |
if (isDegreeF) { | |
lcd.print("Fahrenheit"); | |
} else { | |
lcd.print("Celsius"); | |
} | |
} // close if (menuPosition == 4) | |
// Set LED States | |
if ((tempSenValue >= minTempRange) && (tempSenValue <= maxTempRange)) { | |
// We are within the bounds of the calculated tolerance | |
goodLEDState = 1; | |
// If we are close to the outside of the range, set the cold led as well | |
if (tempSenValue < minMidTempRange) { | |
coldLEDState = 1; | |
} else { | |
coldLEDState = 0; | |
} | |
// If we are close to the outside of the range, set the hot left as well | |
if (tempSenValue > maxMidTempRange) { | |
hotLEDState = 1; | |
} else { | |
hotLEDState = 0; | |
} | |
} else if (tempSenValue < minTempRange) { | |
// too cold... set cold led | |
hotLEDState = 0; | |
goodLEDState = 0; | |
coldLEDState = 1; | |
} else if (tempSenValue > maxTempRange) { | |
// too hot... set hot led | |
hotLEDState = 1; | |
goodLEDState = 0; | |
coldLEDState = 0; | |
} | |
// Set the LED Pins on or off | |
if (coldLEDState) { digitalWrite(coldLEDPin, HIGH); } else { digitalWrite(coldLEDPin, LOW); } | |
if (goodLEDState) { digitalWrite(goodLEDPin, HIGH); } else { digitalWrite(goodLEDPin, LOW); } | |
if (hotLEDState) { digitalWrite(hotLEDPin, HIGH); } else { digitalWrite(hotLEDPin, LOW); } | |
} // close loop | |
float toFahrenheit(int value) { | |
float returnValue; | |
returnValue = (value*1.8)+32; | |
return returnValue; | |
} // close toFahrenheit | |
float toCelsius(int value) { | |
float returnValue; | |
returnValue = (5.0/9.0)*(value-32); | |
return returnValue; | |
} // close toCelsius |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment