#include <EEPROM.h>
#define RELAY1_PIN 12 //0 // ATtiny84 Pin PA0
#define RELAY2_PIN 13 //1 // ATtiny84 Pin PA1
#define RELAY3_PIN 2 // ATtiny84 Pin PA2
#define RELAY4_PIN 3 // ATtiny84 Pin PA3
#define RELAY5_PIN 4 // ATtiny84 Pin PA4
#define BUTTON1 10
#define BUTTON2 9
#define BUTTON3 8
#define BUTTON4 7
#define BUTTON5 6
#define LEARN_LED_PIN 5 // ATtiny84 Pin PA5
unsigned long debounce_delay = 50;
unsigned long last_debounce_time = 0;
bool button1_state = HIGH;
bool button2_state = HIGH;
bool button3_state = HIGH;
bool button4_state = HIGH;
bool button5_state = HIGH;
bool last_button1_state = HIGH;
bool last_button2_state = HIGH;
bool last_button3_state = HIGH;
bool last_button4_state = HIGH;
bool last_button5_state = HIGH;
bool button1_handled = false;
bool button2_handled = false;
bool button3_handled = false;
bool button4_handled = false;
bool button5_handled = false;
bool both_button_pressed = false;
bool button1_pressed = false;
bool button2_pressed = false;
bool button3_pressed = false;
bool button4_pressed = false;
bool button5_pressed = false;
bool learn_mode_enable = false;
bool relay1_status = false;
bool relay2_status = false;
bool relay3_status = false;
bool relay4_status = false;
bool relay5_status = false;
bool led_state = false;
int program_slot = 0;
void setup() {
Serial.begin(115200);
pinMode(BUTTON1, INPUT_PULLUP);
pinMode(BUTTON2, INPUT_PULLUP);
pinMode(BUTTON3, INPUT_PULLUP);
pinMode(BUTTON4, INPUT_PULLUP);
pinMode(BUTTON5, INPUT_PULLUP);
pinMode(RELAY1_PIN, OUTPUT);
pinMode(RELAY2_PIN, OUTPUT);
pinMode(RELAY3_PIN, OUTPUT);
pinMode(RELAY4_PIN, OUTPUT);
pinMode(RELAY5_PIN, OUTPUT);
pinMode(LEARN_LED_PIN, OUTPUT);
}
void loop() {
handleButtons();
if (learn_mode_enable) {
blinkLearnLED();
if (program_slot == 0) {
if (button1_pressed) {
program_slot = 1;
Serial.println("Slot 1 is selected!");
button1_pressed = false;
} else if (button2_pressed) {
program_slot = 2;
Serial.println("Slot 2 is selected!");
button2_pressed = false;
} else if (button3_pressed) {
program_slot = 3;
Serial.println("Slot 3 is selected!");
button3_pressed = false;
} else if (button4_pressed) {
program_slot = 4;
Serial.println("Slot 4 is selected!");
button4_pressed = false;
} else if (button5_pressed) {
program_slot = 5;
Serial.println("Slot 5 is selected!");
button5_pressed = false;
}
} else {
if (both_button_pressed) {
if (program_slot != 0) {
saveRelayChanges(program_slot);
Serial.println("Slot configuration is saved!");
}
program_slot = 0;
learn_mode_enable = false;
relay1_status = false;
relay2_status = false;
relay3_status = false;
relay4_status = false;
relay5_status = false;
digitalWrite(LEARN_LED_PIN, LOW);
both_button_pressed = false;
}
if (button1_pressed) {
relay1_status = changeRelayState(RELAY1_PIN);
button1_pressed = false;
} else if (button2_pressed) {
relay2_status = changeRelayState(RELAY2_PIN);
button2_pressed = false;
} else if (button3_pressed) {
relay3_status = changeRelayState(RELAY3_PIN);
button3_pressed = false;
} else if (button4_pressed) {
relay4_status = changeRelayState(RELAY4_PIN);
button4_pressed = false;
} else if (button5_pressed) {
relay5_status = changeRelayState(RELAY5_PIN);
button5_pressed = false;
}
}
if (both_button_pressed) {
turnOffAll();
digitalWrite(LEARN_LED_PIN, LOW);
learn_mode_enable = false;
both_button_pressed = false;
Serial.println("learn mode off");
}
} else {
if (both_button_pressed) {
turnOffAll();
learn_mode_enable = true;
both_button_pressed = false;
Serial.println("learn mode on");
}
if (button1_pressed) {
loadRelayChanges(1);
Serial.println("Configures loaded for slot 1");
button1_pressed = false;
} else if (button2_pressed) {
loadRelayChanges(2);
Serial.println("Configures loaded for slot 2");
button2_pressed = false;
} else if (button3_pressed) {
loadRelayChanges(3);
Serial.println("Configures loaded for slot 3");
button3_pressed = false;
} else if (button4_pressed) {
loadRelayChanges(4);
Serial.println("Configures loaded for slot 4");
button4_pressed = false;
} else if (button5_pressed) {
loadRelayChanges(5);
Serial.println("Configures loaded for slot 5");
button5_pressed = false;
}
}
}
void handleButtons() {
// Read the current state of the buttons
int current_button1_state = digitalRead(BUTTON1);
int current_button2_state = digitalRead(BUTTON2);
int current_button3_state = digitalRead(BUTTON3);
int current_button4_state = digitalRead(BUTTON4);
int current_button5_state = digitalRead(BUTTON5);
// If any button state has changed, reset the debounce timer
if (current_button1_state != last_button1_state ||
current_button2_state != last_button2_state ||
current_button3_state != last_button3_state ||
current_button4_state != last_button4_state ||
current_button5_state != last_button5_state) {
last_debounce_time = millis();
}
// If the debounce time has passed, read the button states
if ((millis() - last_debounce_time) > debounce_delay) {
// Check if the button states have stabilized and if they have changed
if (current_button1_state != button1_state) {
button1_state = current_button1_state;
button1_handled = false; // Reset handling flag for button1
}
if (current_button2_state != button2_state) {
button2_state = current_button2_state;
button2_handled = false; // Reset handling flag for button2
}
if (current_button3_state != button3_state) {
button3_state = current_button3_state;
button3_handled = false; // Reset handling flag for button3
}
if (current_button4_state != button4_state) {
button4_state = current_button4_state;
button4_handled = false; // Reset handling flag for button4
}
if (current_button5_state != button5_state) {
button5_state = current_button5_state;
button5_handled = false; // Reset handling flag for button5
}
// Handle button logic only after debouncing is done
if (button1_state == LOW && button3_state == LOW && !button1_handled && !button3_handled) {
Serial.println("Both press");
both_button_pressed = true;
button1_handled = true; // Mark as handled to prevent multiple prints
button3_handled = true;
} else {
if (button1_state == LOW && !button1_handled) {
Serial.println("button 1");
button1_pressed = true;
button1_handled = true; // Mark as handled
}
if (button2_state == LOW && !button2_handled) {
Serial.println("button 2");
button2_pressed = true;
button2_handled = true; // Mark as handled
}
if (button3_state == LOW && !button3_handled) {
Serial.println("button 3");
button3_pressed = true;
button3_handled = true; // Mark as handled
}
if (button4_state == LOW && !button4_handled) {
Serial.println("button 4");
button4_pressed = true;
button4_handled = true; // Mark as handled
}
if (button5_state == LOW && !button5_handled) {
Serial.println("button 5");
button5_pressed = true;
button5_handled = true; // Mark as handled
}
}
}
// Save the last button states
last_button1_state = current_button1_state;
last_button2_state = current_button2_state;
last_button3_state = current_button3_state;
last_button4_state = current_button4_state;
last_button5_state = current_button5_state;
}
// change the relay state
bool changeRelayState(int relay_pin) {
bool status = digitalRead(relay_pin);
status = !status;
digitalWrite(relay_pin, status);
return status;
}
// save the relays configuration
void saveRelayChanges(int slot) {
// transfer the 5 relays status on a byte variable to write once.
byte relayStates = 0;
relayStates |= relay1_status << 0;
relayStates |= relay2_status << 1;
relayStates |= relay3_status << 2;
relayStates |= relay4_status << 3;
relayStates |= relay5_status << 4;
EEPROM.update(slot, relayStates);
}
// load the last relays configuration
void loadRelayChanges(int slot) {
// read the 5 relays status on a byte variable from EEPROM
byte relayStates = EEPROM.read(slot);
digitalWrite(RELAY1_PIN, relayStates & (1 << 0));
digitalWrite(RELAY2_PIN, relayStates & (1 << 1));
digitalWrite(RELAY3_PIN, relayStates & (1 << 2));
digitalWrite(RELAY4_PIN, relayStates & (1 << 3));
digitalWrite(RELAY5_PIN, relayStates & (1 << 4));
Serial.print("Relay 1: ");
Serial.println((relayStates & (1 << 0)) ? "ON" : "OFF");
Serial.print("Relay 2: ");
Serial.println((relayStates & (1 << 1)) ? "ON" : "OFF");
Serial.print("Relay 3: ");
Serial.println((relayStates & (1 << 2)) ? "ON" : "OFF");
Serial.print("Relay 4: ");
Serial.println((relayStates & (1 << 3)) ? "ON" : "OFF");
Serial.print("Relay 5: ");
Serial.println((relayStates & (1 << 4)) ? "ON" : "OFF");
}
void turnOffAll() {
digitalWrite(RELAY1_PIN, 0);
digitalWrite(RELAY2_PIN, 0);
digitalWrite(RELAY3_PIN, 0);
digitalWrite(RELAY4_PIN, 0);
digitalWrite(RELAY5_PIN, 0);
}
unsigned long led_blink_time = 0;
void blinkLearnLED() {
if (millis() - led_blink_time > 500) {
led_state = !led_state;
digitalWrite(LEARN_LED_PIN, led_state);
led_blink_time = millis();
}
}
Button 1
Button 2
Button 3
Button 4
Button 5
Relay 1
Relay 2
Relay 3
Relay 4
Relay 5
Button 1 & Button 3
Button 1 Connector Switch
Button 2 Connector Switch
Learn LED