#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <EEPROM.h>
#include <IRremote.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define FAN_PIN 9
#define ZC_PIN 2
#define BUTTON_INC_PIN 3
#define BUTTON_DEC_PIN 4
#define BUTTON_LIGHT1_PIN 10
#define BUTTON_LIGHT2_PIN 11
#define BUTTON_LIGHT3_PIN 12
#define IR_PIN 8
#define LIGHT1_PIN 5
#define LIGHT2_PIN 6
#define LIGHT3_PIN 7
#define EEPROM_FAN_SPEED_ADDR 0
#define EEPROM_LIGHT1_STATE_ADDR 1
#define EEPROM_LIGHT2_STATE_ADDR 2
#define EEPROM_LIGHT3_STATE_ADDR 3
int fanSpeed = 0;
const int maxSpeed = 255;
const int minSpeed = 0;
volatile bool zeroCrossed = false;
bool light1State = false;
bool light2State = false;
bool light3State = false;
IRrecv irrecv(IR_PIN);
decode_results results;
const unsigned long IR_CODE_FAN_INC = 0xFF629D; // Replace with your IR remote code
const unsigned long IR_CODE_FAN_DEC = 0xFFA857; // Replace with your IR remote code
const unsigned long IR_CODE_LIGHT1_TOGGLE = 0xFF22DD; // Replace with your IR remote code
const unsigned long IR_CODE_LIGHT2_TOGGLE = 0xFF02FD; // Replace with your IR remote code
const unsigned long IR_CODE_LIGHT3_TOGGLE = 0xFFC23D; // Replace with your IR remote code
void setup() {
pinMode(FAN_PIN, OUTPUT);
pinMode(ZC_PIN, INPUT);
pinMode(BUTTON_INC_PIN, INPUT);
pinMode(BUTTON_DEC_PIN, INPUT);
pinMode(BUTTON_LIGHT1_PIN, INPUT);
pinMode(BUTTON_LIGHT2_PIN, INPUT);
pinMode(BUTTON_LIGHT3_PIN, INPUT);
pinMode(LIGHT1_PIN, OUTPUT);
pinMode(LIGHT2_PIN, OUTPUT);
pinMode(LIGHT3_PIN, OUTPUT);
digitalWrite(BUTTON_INC_PIN, LOW);
digitalWrite(BUTTON_DEC_PIN, LOW);
digitalWrite(BUTTON_LIGHT1_PIN, LOW);
digitalWrite(BUTTON_LIGHT2_PIN, LOW);
digitalWrite(BUTTON_LIGHT3_PIN, LOW);
attachInterrupt(digitalPinToInterrupt(ZC_PIN), zeroCrossISR, RISING);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.print("Fan & Light Control");
display.display();
// Retrieve stored values from EEPROM
fanSpeed = EEPROM.read(EEPROM_FAN_SPEED_ADDR);
light1State = EEPROM.read(EEPROM_LIGHT1_STATE_ADDR);
light2State = EEPROM.read(EEPROM_LIGHT2_STATE_ADDR);
light3State = EEPROM.read(EEPROM_LIGHT3_STATE_ADDR);
// Initialize lights and fan to stored states
analogWrite(FAN_PIN, fanSpeed);
digitalWrite(LIGHT1_PIN, light1State ? HIGH : LOW);
digitalWrite(LIGHT2_PIN, light2State ? HIGH : LOW);
digitalWrite(LIGHT3_PIN, light3State ? HIGH : LOW);
irrecv.enableIRIn(); // Start the IR receiver
}
void loop() {
static int lastFanSpeed = fanSpeed;
static bool lastLight1State = light1State;
static bool lastLight2State = light2State;
static bool lastLight3State = light3State;
if (digitalRead(BUTTON_INC_PIN) == HIGH) {
fanSpeed = constrain(fanSpeed + 5, minSpeed, maxSpeed);
delay(200); // Debounce delay
}
if (digitalRead(BUTTON_DEC_PIN) == HIGH) {
fanSpeed = constrain(fanSpeed - 5, minSpeed, maxSpeed);
delay(200); // Debounce delay
}
if (zeroCrossed) {
analogWrite(FAN_PIN, fanSpeed);
zeroCrossed = false;
}
if (digitalRead(BUTTON_LIGHT1_PIN) == HIGH) {
light1State = !light1State;
digitalWrite(LIGHT1_PIN, light1State ? HIGH : LOW);
delay(200); // Debounce delay
}
if (digitalRead(BUTTON_LIGHT2_PIN) == HIGH) {
light2State = !light2State;
digitalWrite(LIGHT2_PIN, light2State ? HIGH : LOW);
delay(200); // Debounce delay
}
if (digitalRead(BUTTON_LIGHT3_PIN) == HIGH) {
light3State = !light3State;
digitalWrite(LIGHT3_PIN, light3State ? HIGH : LOW);
delay(200); // Debounce delay
}
// Check for IR signals
if (irrecv.decode(&results)) {
unsigned long irCode = results.value;
irrecv.resume(); // Receive the next value
if (irCode == IR_CODE_FAN_INC) {
fanSpeed = constrain(fanSpeed + 5, minSpeed, maxSpeed);
} else if (irCode == IR_CODE_FAN_DEC) {
fanSpeed = constrain(fanSpeed - 5, minSpeed, maxSpeed);
} else if (irCode == IR_CODE_LIGHT1_TOGGLE) {
light1State = !light1State;
digitalWrite(LIGHT1_PIN, light1State ? HIGH : LOW);
} else if (irCode == IR_CODE_LIGHT2_TOGGLE) {
light2State = !light2State;
digitalWrite(LIGHT2_PIN, light2State ? HIGH : LOW);
} else if (irCode == IR_CODE_LIGHT3_TOGGLE) {
light3State = !light3State;
digitalWrite(LIGHT3_PIN, light3State ? HIGH : LOW);
}
}
// Save changes to EEPROM
if (fanSpeed != lastFanSpeed) {
EEPROM.write(EEPROM_FAN_SPEED_ADDR, fanSpeed);
lastFanSpeed = fanSpeed;
}
if (light1State != lastLight1State) {
EEPROM.write(EEPROM_LIGHT1_STATE_ADDR, light1State);
lastLight1State = light1State;
}
if (light2State != lastLight2State) {
EEPROM.write(EEPROM_LIGHT2_STATE_ADDR, light2State);
lastLight2State = light2State;
}
if (light3State != lastLight3State) {
EEPROM.write(EEPROM_LIGHT3_STATE_ADDR, light3State);
lastLight3State = light3State;
}
display.clearDisplay();
display.setCursor(0, 0);
display.print("Fan & Light Control");
display.setCursor(0, 20);
display.print("Fan Speed: ");
display.print(fanSpeed);
display.setCursor(0, 40);
display.print("Light 1: ");
display.print(light1State ? "On" : "Off");
display.setCursor(0, 50);
display.print("Light 2: ");
display.print(light2State ? "On" : "Off");
display.setCursor(0, 60);
display.print("Light 3: ");
display.print(light3State ? "On" : "Off");
display.display();
delay(100);
}
void zeroCrossISR() {
zeroCrossed = true;
}