/*
Based on a project by Jason Poel Smith
https://www.allaboutcircuits.com/projects/convert-a-vintage-thermostat-into-a-modern-energy-saver/
*/
#include <Servo.h> //include libraries
Servo myservo;
int defaultTemperature = 70; //Default temperature that will be adjusted throughout the week
//Day and Time Variables
int dayTimeArray [7][24]=
{
//Sunday Array (Day 0)
{
0, // 12:00 am (hour 0)
0, // 1:00 am (hour 1)
0, // 2:00 am (hour 2)
0, // 3:00 am (hour 3)
0, // 4:00 am (hour 4)
0, // 5:00 am (hour 5)
0, // 6:00 am (hour 6)
0, // 7:00 am (hour 7)
0, // 8:00 am (hour 8)
0, // 9:00 am (hour 9)
0, // 10:00 am (hour 10)
0, // 11:00 am (hour 11)
0, // 12:00 pm (hour 12)
0, // 1:00 pm (hour 13)
0, // 2:00 pm (hour 14)
0, // 3:00 pm (hour 15)
0, // 4:00 pm (hour 16)
0, // 5:00 pm (hour 17)
0, // 6:00 pm (hour 18)
0, // 7:00 pm (hour 19)
0, // 8:00 pm (hour 20)
0, // 9:00 pm (hour 21)
0, // 10:00 pm (hour 22)
0 // 11:00 pm (hour 23)
},
//Monday Array (Day 1)
{
0, // 12:00 am (hour 0)
0, // 1:00 am (hour 1)
0, // 2:00 am (hour 2)
0, // 3:00 am (hour 3)
0, // 4:00 am (hour 4)
0, // 5:00 am (hour 5)
0, // 6:00 am (hour 6)
0, // 7:00 am (hour 7)
0, // 8:00 am (hour 8)
0, // 9:00 am (hour 9)
0, // 10:00 am (hour 10)
0, // 11:00 am (hour 11)
0, // 12:00 pm (hour 12)
0, // 1:00 pm (hour 13)
0, // 2:00 pm (hour 14)
0, // 3:00 pm (hour 15)
0, // 4:00 pm (hour 16)
0, // 5:00 pm (hour 17)
0, // 6:00 pm (hour 18)
0, // 7:00 pm (hour 19)
0, // 8:00 pm (hour 20)
0, // 9:00 pm (hour 21)
0, // 10:00 pm (hour 22)
0 // 11:00 pm (hour 23)
},
//Tuesday Array (Day 2)
{
0, // 12:00 am (hour 0)
0, // 1:00 am (hour 1)
0, // 2:00 am (hour 2)
0, // 3:00 am (hour 3)
0, // 4:00 am (hour 4)
0, // 5:00 am (hour 5)
0, // 6:00 am (hour 6)
0, // 7:00 am (hour 7)
0, // 8:00 am (hour 8)
0, // 9:00 am (hour 9)
0, // 10:00 am (hour 10)
0, // 11:00 am (hour 11)
0, // 12:00 pm (hour 12)
0, // 1:00 pm (hour 13)
0, // 2:00 pm (hour 14)
0, // 3:00 pm (hour 15)
0, // 4:00 pm (hour 16)
0, // 5:00 pm (hour 17)
0, // 6:00 pm (hour 18)
0, // 7:00 pm (hour 19)
0, // 8:00 pm (hour 20)
0, // 9:00 pm (hour 21)
0, // 10:00 pm (hour 22)
0 // 11:00 pm (hour 23)
},
//Wednesday Array (Day 3)
{
0, // 12:00 am (hour 0)
0, // 1:00 am (hour 1)
0, // 2:00 am (hour 2)
0, // 3:00 am (hour 3)
0, // 4:00 am (hour 4)
0, // 5:00 am (hour 5)
0, // 6:00 am (hour 6)
0, // 7:00 am (hour 7)
0, // 8:00 am (hour 8)
0, // 9:00 am (hour 9)
0, // 10:00 am (hour 10)
0, // 11:00 am (hour 11)
0, // 12:00 pm (hour 12)
0, // 1:00 pm (hour 13)
0, // 2:00 pm (hour 14)
0, // 3:00 pm (hour 15)
0, // 4:00 pm (hour 16)
0, // 5:00 pm (hour 17)
0, // 6:00 pm (hour 18)
0, // 7:00 pm (hour 19)
0, // 8:00 pm (hour 20)
0, // 9:00 pm (hour 21)
0, // 10:00 pm (hour 22)
0 // 11:00 pm (hour 23)
},
//Thursday Array (Day 4)
{
0, // 12:00 am (hour 0)
0, // 1:00 am (hour 1)
0, // 2:00 am (hour 2)
0, // 3:00 am (hour 3)
0, // 4:00 am (hour 4)
0, // 5:00 am (hour 5)
0, // 6:00 am (hour 6)
0, // 7:00 am (hour 7)
0, // 8:00 am (hour 8)
0, // 9:00 am (hour 9)
0, // 10:00 am (hour 10)
0, // 11:00 am (hour 11)
0, // 12:00 pm (hour 12)
0, // 1:00 pm (hour 13)
0, // 2:00 pm (hour 14)
0, // 3:00 pm (hour 15)
0, // 4:00 pm (hour 16)
0, // 5:00 pm (hour 17)
0, // 6:00 pm (hour 18)
0, // 7:00 pm (hour 19)
0, // 8:00 pm (hour 20)
0, // 9:00 pm (hour 21)
0, // 10:00 pm (hour 22)
0 // 11:00 pm (hour 23)
},
//Friday Array (Day 5)
{
0, // 12:00 am (hour 0)
0, // 1:00 am (hour 1)
0, // 2:00 am (hour 2)
0, // 3:00 am (hour 3)
0, // 4:00 am (hour 4)
0, // 5:00 am (hour 5)
0, // 6:00 am (hour 6)
0, // 7:00 am (hour 7)
0, // 8:00 am (hour 8)
0, // 9:00 am (hour 9)
0, // 10:00 am (hour 10)
0, // 11:00 am (hour 11)
0, // 12:00 pm (hour 12)
0, // 1:00 pm (hour 13)
0, // 2:00 pm (hour 14)
0, // 3:00 pm (hour 15)
0, // 4:00 pm (hour 16)
0, // 5:00 pm (hour 17)
0, // 6:00 pm (hour 18)
0, // 7:00 pm (hour 19)
0, // 8:00 pm (hour 20)
0, // 9:00 pm (hour 21)
0, // 10:00 pm (hour 22)
0 // 11:00 pm (hour 23)
},
//Saturday Array (Day 6)
{
0, // 12:00 am (hour 0)
0, // 1:00 am (hour 1)
0, // 2:00 am (hour 2)
0, // 3:00 am (hour 3)
0, // 4:00 am (hour 4)
0, // 5:00 am (hour 5)
0, // 6:00 am (hour 6)
0, // 7:00 am (hour 7)
0, // 8:00 am (hour 8)
0, // 9:00 am (hour 9)
0, // 10:00 am (hour 10)
0, // 11:00 am (hour 11)
0, // 12:00 pm (hour 12)
0, // 1:00 pm (hour 13)
0, // 2:00 pm (hour 14)
0, // 3:00 pm (hour 15)
0, // 4:00 pm (hour 16)
0, // 5:00 pm (hour 17)
0, // 6:00 pm (hour 18)
0, // 7:00 pm (hour 19)
0, // 8:00 pm (hour 20)
0, // 9:00 pm (hour 21)
0, // 10:00 pm (hour 22)
0 // 11:00 pm (hour 23)
},
};
int currentDay = 0;
int currentHour = 0;
int currentMinute = 0;
int currentSecond = 0;
int goalTemperature = 70; //Current temperature setting
int manualTemperatureAdjustment = 0; //Manually adjustment to the temperature setting with buttons
int servoTemperatureConversion = 4; //How many degrees of the servo rotation correspond to a degree in temperature
int temperatureDifference = 0; //Difference between current temperature setting and the default temperature
int defaultPosition = 70; //Default servo position that will be adjusted based on temperature setting
int servoDifference = 0; //Difference between current servo position setting and the default position
int currentPosition = 70; //Current servo position
int previousPosition = 69; //Previous servo position
int upButtonPin = 11; //Pin to read positive manual adjustment buttons
int downButtonPin = 10; //Pin to read negative manual adjustment buttons
int upButtonState = 0; //Current state of positive adjustment button
int downButtonState = 0; //Current state of negative adjustment button
unsigned long currentTime = 0; //Milliseconds since start of program
unsigned long secondMarker = 1000; //1000 milliseconds per second
void setup()
{
pinMode(upButtonPin, INPUT);
pinMode(downButtonPin, INPUT);
myservo.attach(9); //Attaches the servo on pin 9 to the servo object
Serial.begin(9600); //Serial Monitor fuction for debugging and monitoring
}
void loop()
{
currentTime = millis(); //Tracks current time
if(currentTime > secondMarker)
{
currentSecond = currentSecond + 1; //Adjust second counter
if(currentSecond > 59)
{
currentSecond = 0;
currentMinute = currentMinute + 1; //Adjust minute counter
}
if(currentMinute > 59)
{
currentMinute = 0;
currentHour = currentHour + 1; //Adjust hour counter
}
if(currentHour > 23)
{
currentHour = 0;
currentDay = currentDay + 1; //Adjust day counter
}
if(currentDay > 6)
{
currentDay = 0;
}
secondMarker = secondMarker + 1000; //Adjust time marker to update seconds
if(secondMarker < 1000 && currentTime > 10000) //Resets clock counter when the millis() function resets
{
delay(1000);
}
}
Serial.print(currentDay); //display clock for debugging
Serial.print(" ");
Serial.print(currentHour);
Serial.print(" ");
Serial.print(currentMinute);
Serial.print(" ");
Serial.print(currentSecond);
Serial.print(" ");
Serial.print(currentTime);
Serial.print(" ");
Serial.println(secondMarker);
temperatureDifference = dayTimeArray[currentDay][currentHour] + manualTemperatureAdjustment;
servoDifference = temperatureDifference * servoTemperatureConversion;
currentPosition = defaultPosition + servoDifference;
goalTemperature = defaultTemperature + temperatureDifference;
if (previousPosition != currentPosition)
{
Serial.print("Default Temperature "); //Display updated temperature information
Serial.println(defaultTemperature);
Serial.print("Day Time Adjustment ");
Serial.println(dayTimeArray[currentDay][currentHour]);
Serial.print("Manual Adjustment ");
Serial.println(manualTemperatureAdjustment);
Serial.print("Goal Temperature ");
Serial.println(goalTemperature);
Serial.println();
Serial.print("Default Servo Position ");
Serial.println(defaultPosition);
Serial.print("Servo Position Adjustment ");
Serial.println(servoDifference);
Serial.print("Current Servo Position ");
Serial.println(currentPosition);
Serial.println();
Serial.println();
myservo.write(currentPosition); //Adjust the servo to match the current settings
delay(500);
previousPosition = currentPosition;
}
upButtonState = digitalRead(upButtonPin); //Check buttons for manual adjustments
downButtonState = digitalRead(downButtonPin); //Check buttons for manual adjustments
if (upButtonState == HIGH)
{
manualTemperatureAdjustment = manualTemperatureAdjustment + 1; //Adjust temperature setting up
}
if (downButtonState == HIGH)
{
manualTemperatureAdjustment = manualTemperatureAdjustment - 1; //Adjust temperature setting down
}
}