Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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