Skip to content

Instantly share code, notes, and snippets.

@LVLAaron
Last active August 29, 2015 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LVLAaron/6a62d19a41b6d549ca53 to your computer and use it in GitHub Desktop.
Save LVLAaron/6a62d19a41b6d549ca53 to your computer and use it in GitHub Desktop.
HVAC_Control
// name: HVAC.ino
// author: Aaron Anderson
// -------------LIBRARIES---------------- THESE ARE REQUIRED TO BE IN YOUR SKETCHBOOK\LIBRARY FOLDER FOR COMPILING ----
#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 = 55; // This is the default heater trigger temp setting
int cool = 70; // 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 = 60; // 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
long currentTemp = 0; // Current room temperature
int serialSpeed = 9600; // Default serial comm speed
long 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"}; // 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 0x7 // 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() {
// 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();
// Leaves the relays "off" (no click until something is needed)
// digitalWrite(heatPin, HIGH);
// digitalWrite(coolPin, HIGH);
// digitalWrite(fanPin, HIGH);
}
// ----------------------------------------------------------------------------------------
// 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);
}
// --------------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, HIGH);
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, HIGH);
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) {
if (menuPosition == 1) {
menuPosition = 0;
} else {
menuPosition = 1;
}
}
// If the Right Button is pushed, change the menu context
if (buttons & BUTTON_RIGHT) {
if (menuPosition == 1) {
menuPosition = 0;
} else {
menuPosition = 1;
}
}
// 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("Setpoint: ");
if (menuPosition == 0) {
lcd.print(cool);
}
if (menuPosition == 1) {
lcd.print(heat);
}
}
// ----------------------------------------------------------------------------------------
// 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;
long 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);
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