#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();
}
}
nano:12
nano:11
nano:10
nano:9
nano:8
nano:7
nano:6
nano:5
nano:4
nano:3
nano:2
nano:GND.2
nano:RESET.2
nano:0
nano:1
nano:13
nano:3.3V
nano:AREF
nano:A0
nano:A1
nano:A2
nano:A3
nano:A4
nano:A5
nano:A6
nano:A7
nano:5V
nano:RESET
nano:GND.1
nano:VIN
nano:12.2
nano:5V.2
nano:13.2
nano:11.2
nano:RESET.3
nano:GND.3
led6:A
led6:C
relay1:VCC
relay1:GND
relay1:IN
relay1:NC
relay1:COM
relay1:NO
relay2:VCC
relay2:GND
relay2:IN
relay2:NC
relay2:COM
relay2:NO
relay3:VCC
relay3:GND
relay3:IN
relay3:NC
relay3:COM
relay3:NO
relay4:VCC
relay4:GND
relay4:IN
relay4:NC
relay4:COM
relay4:NO
relay5:VCC
relay5:GND
relay5:IN
relay5:NC
relay5:COM
relay5:NO
r1:1
r1:2
r2:1
r2:2
r3:1
r3:2
r4:1
r4:2
r6:1
r6:2
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r
btn2:1.l
btn2:2.l
btn2:1.r
btn2:2.r
btn3:1.l
btn3:2.l
btn3:1.r
btn3:2.r
btn4:1.l
btn4:2.l
btn4:1.r
btn4:2.r
btn5:1.l
btn5:2.l
btn5:1.r
btn5:2.r
sw1:1
sw1:2
sw1:3
sw2:1
sw2:2
sw2:3
btn6:1.l
btn6:2.l
btn6:1.r
btn6:2.r
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