#include "Wire.h" // Emulated Wire.h library
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// Pin Definitions
#define TEMP_SENSOR_PIN A0
#define SLIDER_PIN A1 // Analog pin for sliding potentiometer
#define POWER_MODE_PIN 4
#define SWITCH_PIN 2 // Pin for the switch
#define CONDENSER_FAN_PIN 5
#define EVAPORATOR_FAN_PIN 6
#define COMPRESSOR_PIN 7
// Power Modes
#define OFF_MODE 0
#define ON_MODE 1
#define AUTO_MODE 2
// Temperature Constants
#define MIN_TEMP 50 // Minimum temperature (in Fahrenheit)
#define MAX_TEMP 99 // Maximum temperature (in Fahrenheit)
// Timing Constants (in milliseconds)
#define FAN_DELAY 3000 // 3 seconds delay between turning on fans
#define COMPRESSOR_DELAY 6000 // 6 seconds delay before turning on compressor
#define COOLING_CYCLE_INTERVAL 1800000 // 30 minutes interval before cooling cycle starts again in ON mode
#define AUTO_MODE_DELAY 600000 // 10 minutes delay before turning on again in AUTO mode
// Global Variables
float currentTemperature = 0.0;
float setPointTemperature = 75.0; // Initial set point temperature
int powerMode = OFF_MODE;
unsigned long lastCoolingStartTime = 0;
// Initialize OLED Display
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Button State Variables
int sliderValue = 0; // Slider value from the potentiometer
void setup() {
// Initialize Serial Communication
Serial.begin(9600);
// Initialize I2C communication
Wire.begin();
// Initialize pins
pinMode(POWER_MODE_PIN, INPUT_PULLUP);
pinMode(SWITCH_PIN, INPUT_PULLUP); // Set the switch pin as input with internal pull-up resistor
pinMode(CONDENSER_FAN_PIN, OUTPUT);
pinMode(EVAPORATOR_FAN_PIN, OUTPUT);
pinMode(COMPRESSOR_PIN, OUTPUT);
// Initialize OLED display
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;)
;
}
display.display();
delay(2000);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.print("Thermostat");
display.setCursor(0, 10); // Set cursor to the second line
display.print("Initialized");
display.display();
delay(2000);
display.clearDisplay();
}
void loop() {
// Read temperature
currentTemperature = readTemperature();
// Read slider value
sliderValue = analogRead(SLIDER_PIN);
// Map slider value to set point temperature range
setPointTemperature = map(sliderValue, 0, 1023, MIN_TEMP, MAX_TEMP);
// Check the state of the switch
bool switchState = digitalRead(SWITCH_PIN);
// Update power mode based on switch state
if (switchState == LOW) {
powerMode = ON_MODE;
} else {
powerMode = OFF_MODE;
}
// Control air conditioner based on power mode
switch (powerMode) {
case OFF_MODE:
turnOffAC();
break;
case ON_MODE:
if (currentTemperature > setPointTemperature) {
turnOnAC();
} else if (millis() - lastCoolingStartTime >= COOLING_CYCLE_INTERVAL) {
turnOffAC();
}
break;
case AUTO_MODE:
if (currentTemperature > setPointTemperature) {
if (millis() - lastCoolingStartTime >= COOLING_CYCLE_INTERVAL) {
turnOnAC();
}
} else if (currentTemperature <= setPointTemperature - 3) {
turnOffAC();
}
break;
}
// Display temperature readings
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.print("Set Point: ");
display.print((int)setPointTemperature); // Cast setPointTemperature to int to display only the whole number part
display.setCursor(0, 10);
display.print("Current Temp: ");
display.print((int)currentTemperature); // Cast currentTemperature to int to display only the whole number part
display.print(" °F"); // Display the °F symbol for Fahrenheit
display.setCursor(0, 20);
display.print("Power Mode: ");
switch (powerMode) {
case OFF_MODE:
display.print("Off");
break;
case ON_MODE:
display.print("On");
break;
case AUTO_MODE:
display.print("Auto");
break;
}
display.display();
delay(100); // Add a small delay to prevent excessive display updating
}
float readTemperature() {
const float BETA = 3950; // Beta Coefficient of the thermistor
// Read the analog value from the temperature sensor
int analogValue = analogRead(TEMP_SENSOR_PIN);
// Calculate temperature in Celsius
float celsius = 1 / (log(1 / (1023. / analogValue - 1)) / BETA + 1.0 / 298.15) - 273.15;
// Convert Celsius to Fahrenheit
float fahrenheit = celsius * 9 / 5 + 32;
return fahrenheit;
}
void turnOnAC() {
digitalWrite(CONDENSER_FAN_PIN, HIGH);
delay(FAN_DELAY);
digitalWrite(EVAPORATOR_FAN_PIN, HIGH);
delay(FAN_DELAY);
digitalWrite(COMPRESSOR_PIN, HIGH);
delay(COMPRESSOR_DELAY);
lastCoolingStartTime = millis();
}
void turnOffAC() {
digitalWrite(CONDENSER_FAN_PIN, LOW);
delay(FAN_DELAY);
digitalWrite(EVAPORATOR_FAN_PIN, LOW);
delay(FAN_DELAY);
digitalWrite(COMPRESSOR_PIN, LOW);
}