Created
June 25, 2014 02:39
-
-
Save LVLAaron/c600fc9cd74e8d7502f8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// name: HVAC_Thermostat.ino | |
// -------------LIBRARIES---------------- | |
#include <Wire.h> // Protocol to communicate with I2C devices | |
#include <Adafruit_MCP23017.h> // LCD protocol | |
#include <Adafruit_RGBLCDShield.h> // LCD + Button shield protocol | |
#include "DHT.h" // DHT11 Temp/Humidity Sensor | |
// --------------PARAMETERS--------------------- | |
int heat = 45; // This is the default heater trigger temp setting | |
int cool = 73; // This is the default cooling trigger temp setting | |
int buffer = 1; // This is the range away from the setpoint the heat or AC will overcool/heat to prevent shorter cycles | |
int heatPin = 7; // Digital pin used for turning on the heater relay | |
int coolPin = 8; // Digital pin used for turning on the AC relay | |
int fanPin = 9; // Digital pin used for turning on the fan relay | |
int cycleTime = 60000; // The length of time to delay running the AC or heat to prevent short cycling | |
boolean heatRunning = false; // Stores whether the heater is currently running or not | |
boolean coolRunning = false; // Stores whether the AC is currently running or not | |
boolean fanRunning = false; // Stores whether the Fan is currently running or not | |
float currentTemp = 70; // Current room temperature | |
int serialSpeed = 9600; // Default serial comm speed | |
float oldTemp = 0; // Used to only update the currentTemp if the temp has changed | |
unsigned long timeOut; // Backlight timeout variable | |
boolean editable = false; // Determines whether or not button presses will do anything, used to avoid accidental changes | |
char* menu[] = {"Cooling", "Heating", "Fan"}; // Menu display for either setting the high point or the low point of the temp range | |
int menuPosition = 1; // Current position in the setting menu | |
unsigned long heatLastRan; // Stores the time the heater last ran | |
unsigned long coolLastRan; // Stores the time the AC last ran | |
unsigned long TempLastCheck; // Stores the last sensor reading ran | |
// -------------Library Interaction-------------- | |
// Create our LCD Shield instance | |
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield(); | |
#define ON 0x6 // For single color LCD, set on to white | |
#define OFF 0x0 // For single color LCD, set off to black | |
#define DHTTYPE DHT11 // DHT 11 | |
#define DHTPIN 4 // what pin we're connected to | |
DHT dht(DHTPIN, DHTTYPE); | |
// ---------------------------------------------------------------------------------------- | |
// Function Name: setup() | |
// Parameters: None | |
// Returns: None | |
// Description: This function executes housekeeping duties and staging for the loop() function; executed once | |
// ---------------------------------------------------------------------------------------- | |
void setup() { | |
// Leaves the relays "off" (no click until something is needed) | |
digitalWrite(heatPin, HIGH); | |
digitalWrite(coolPin, HIGH); | |
digitalWrite(fanPin, HIGH); | |
// pinMode(busPin,INPUT); // Designate temperature bus pin data direction | |
pinMode(heatPin, OUTPUT); // Heat circuit relay | |
pinMode(coolPin, OUTPUT); // Cooling circuit relay | |
pinMode(fanPin, OUTPUT); // Fan circuit relay | |
Serial.begin(serialSpeed); | |
lcd.begin(16, 2); // set up the LCD's number of columns and rows | |
lcd.setBacklight(ON); // Start off with backlight on until time-out | |
timeOut = millis(); // Set the initial backlight time | |
TempLastCheck = millis(); // Set the initial sensor timing | |
dht.begin(); | |
} | |
// ---------------------------------------------------------------------------------------- | |
// Function Name: loop() | |
// Parameters: None | |
// Returns: None | |
// Description: This is the main executing block of the program, calling all ancillary functions to operate the Arduino | |
// ---------------------------------------------------------------------------------------- | |
void loop() { | |
if ((millis() - timeOut) > 30000) { // Turn on backlight for 30 seconds, else turn it off | |
lcd.setBacklight(OFF); | |
editable == false; | |
} else { | |
lcd.setBacklight(ON); | |
} | |
lcd.setCursor(0, 1); // Starting position of character printing | |
uint8_t buttons = lcd.readButtons(); // Constantly check to see if something has been put on the bus | |
// --------------Handle updating Temp Change Display--------------------- | |
if (getTemp()) { // Constantly check to see if the temperature has changed, and update appropriately | |
lcd.clear(); | |
lcd.print("Temp: "); | |
lcd.print(currentTemp); | |
lcd.setCursor(0, 1); | |
lcd.print("A:"); | |
lcd.print(coolRunning); | |
lcd.print(" H:"); | |
lcd.print(heatRunning); | |
lcd.print(" F:"); | |
lcd.print(fanRunning); | |
} | |
// --------------Handle Button Presses--------------------- | |
if (buttons) { | |
timeOut = millis(); | |
lcd.setBacklight(ON); | |
if (buttons & BUTTON_SELECT) { // Allow parameters to be changed only if the Select button has been pressed first | |
editable = true; | |
} | |
if (editable) { // go to buttonHandler to handle menu switching and parameter manipulations | |
buttonHandler(buttons); | |
} | |
} | |
// --------------Handle Heat and Cooling Cycles--------------------- | |
powerControl(); | |
} | |
// ---------------------------------------------------------------------------------------- | |
// Function Name: powerControlHandler() | |
// Parameters: None | |
// Returns: None | |
// Description: This function will handle turning AC or Heat off and on based on current temp, timers, and setpoints | |
// ---------------------------------------------------------------------------------------- | |
void powerControl() { | |
// TODO: Add in fan relay control | |
// This executes if the heater is running and it gets warm enough to turn off. | |
if (heatRunning && (currentTemp > (heat + buffer))) { | |
heatRunning = false; | |
heatLastRan = millis(); | |
digitalWrite(heatPin, HIGH); | |
return; | |
} | |
// This executes if the AC is running and it gets cool enough to turn off | |
if (coolRunning && (currentTemp < (cool - buffer))) { | |
coolRunning = false; | |
coolLastRan = millis(); | |
digitalWrite(coolPin, HIGH); | |
return; | |
} | |
// This executes if it gets cold enough and the heater has not run for a minimum time (short cycle protection) | |
if ((currentTemp < heat) && ((millis() - heatLastRan) > cycleTime)) { | |
digitalWrite(heatPin, LOW); | |
heatRunning = true; | |
return; | |
} | |
// This executes if it gets hot enough and the AC has not run for 10 minutes (short cycle protection) | |
if ((currentTemp > cool) && ((millis() - coolLastRan) > 60)) { | |
digitalWrite(coolPin, LOW); | |
coolRunning = true; | |
return; | |
} | |
return; | |
} | |
// ---------------------------------------------------------------------------------------- | |
// Function Name: buttonHandler() | |
// Parameters: None | |
// Returns: Boolean, True if the temperature has changed, else False | |
// Description: This function polls the temp sensors, retrieves the values, and then returns | |
// ---------------------------------------------------------------------------------------- | |
boolean buttonHandler(uint8_t buttons) { | |
// --------------PARAMETERS--------------------- | |
int heatModifier = 0; | |
int coolModifier = 0; | |
// --------------SETUP--------------------- | |
lcd.clear(); | |
// If the UP Button is pushed, increasing the setpoint | |
if (buttons & BUTTON_UP) { | |
if (menuPosition == 0) { | |
coolModifier = 1; | |
} | |
if (menuPosition == 1) { | |
heatModifier = 1; | |
} | |
} | |
// If the Down Button is pushed, decreasing the setpoint | |
if (buttons & BUTTON_DOWN) { | |
if (menuPosition == 0) { | |
coolModifier = -1; | |
} | |
if (menuPosition == 1) { | |
heatModifier = -1; | |
} | |
} | |
// If the Left Button is pushed, change the menu context | |
if (buttons & BUTTON_LEFT) { | |
menuPosition--; // decrement the variable | |
if ( menuPosition < 0 ) { | |
menuPosition = 0; // don't let it decrement too much | |
} | |
} | |
// If the Right Button is pushed, change the menu context | |
if (buttons & BUTTON_RIGHT) { | |
menuPosition++; // increment the variable | |
if ( menuPosition <= 2 ) { | |
menuPosition = 2; // don't let it increment too much | |
} | |
} | |
// If anything has been modified, update accordingly | |
heat = heat + heatModifier; | |
cool = cool + coolModifier; | |
// Print proper menu title and setpoint | |
lcd.setCursor(0, 0); | |
lcd.print(menu[menuPosition]); | |
lcd.setCursor(0, 1); | |
lcd.print("Setting: "); | |
if (menuPosition == 0) { | |
lcd.print(cool); | |
} | |
if (menuPosition == 1) { | |
lcd.print(heat); | |
} | |
if (menuPosition == 2) { | |
lcd.print(fanRunning); | |
} | |
} | |
// ---------------------------------------------------------------------------------------- | |
// Function Name: getTemp() | |
// Parameters: None | |
// Returns: Boolean, True if the temperature has changed, else False | |
// Description: This function polls the temp sensors, retrieves the values, and then returns | |
// ---------------------------------------------------------------------------------------- | |
boolean getTemp() { | |
//currentTemp = 0; | |
float temp = 0; | |
if ((millis() - TempLastCheck) > 2000) { | |
TempLastCheck = millis(); | |
temp = dht.readTemperature(true); | |
/* | |
Serial.println(""); | |
Serial.print("temp: "); | |
Serial.println(temp); | |
Serial.print("CurrentTemp: "); | |
Serial.println(currentTemp); | |
Serial.print("OldTemp: "); | |
Serial.println(oldTemp); | |
Serial.print("cool: "); | |
Serial.println(cool); | |
Serial.print("heat: "); | |
Serial.println(heat); | |
Serial.println(""); | |
Serial.print("heat running: "); | |
Serial.println(heatRunning); | |
Serial.print("cool running: "); | |
Serial.println(coolRunning); | |
*/ | |
if (temp != currentTemp) { | |
currentTemp = temp; | |
} | |
} | |
// Check to see if temperature has changed | |
if (currentTemp != oldTemp) { | |
oldTemp = currentTemp; | |
return true; | |
} | |
else { | |
return false; | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment