In this video I will show you in great detail, how to transform a traditional power strip to a “intelligent” power strip.
Components:
- Power Strip https://bit.ly/3mzSNWm
- 4 channel relay https://bit.ly/37sDkBk
- LCD display 1602 https://bit.ly/39xekvn
- IIC Interface https://bit.ly/39xekvn
- 3x PCB Buttons https://bit.ly/3mxRiIr
- Leds https://bit.ly/3lExfqE
- 220 Ohm Resistors https://bit.ly/3g0stSY
- PCB Board 4x6cm https://bit.ly/3ocpppy
- PCB Connector row https://bit.ly/3lzXe2h
Diagram

Board Scheme:

3D Printer – Case

3D Printer – Power strip supports

Source Code
#include <Wire.h> // Library for I2C communication
#include <LiquidCrystal_I2C.h> // Library for LCD
#include <TimerOne.h>
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);
int PIN_BTN_SELECT = 4;
int PIN_BTN_REMOVE = 3;
int PIN_BTN_ADD = 2;
int PIN_LED_1 = 5;
int PIN_LED_2 = 6;
int PIN_LED_3 = 7;
int PIN_LED_4 = 8;
int PIN_RELAY_1 = 9;
int PIN_RELAY_2 = 10;
int PIN_RELAY_3 = 11;
int PIN_RELAY_4 = 12;
int BLINK_BTN_TIMER = 10;
int BLINK_LED_PIN = -1;
int CURRENT_CONFIG_SOCKET = 0;
int CURRENT_CONFIG_TIME = 1;
int LAST_BTN_SELECT_STATUS = 0;
int LAST_BTN_ADD_STATUS = 0;
int LAST_BTN_REMOVE_STATUS = 0;
int BACKLIGHT_TIMEOUT = 0;
long RELAY_1_TIMEOUT = 0;
long RELAY_2_TIMEOUT = 0;
long RELAY_3_TIMEOUT = 0;
long RELAY_4_TIMEOUT = 0;
void setup() {
pinMode(PIN_BTN_SELECT, INPUT);
pinMode(PIN_BTN_ADD, INPUT);
pinMode(PIN_BTN_REMOVE, INPUT);
pinMode(PIN_LED_1, OUTPUT);
pinMode(PIN_LED_2, OUTPUT);
pinMode(PIN_LED_3, OUTPUT);
pinMode(PIN_LED_4, OUTPUT);
pinMode(PIN_RELAY_1, OUTPUT);
pinMode(PIN_RELAY_2, OUTPUT);
pinMode(PIN_RELAY_3, OUTPUT);
pinMode(PIN_RELAY_4, OUTPUT);
digitalWrite(PIN_RELAY_1, HIGH);
digitalWrite(PIN_RELAY_2, HIGH);
digitalWrite(PIN_RELAY_3, HIGH);
digitalWrite(PIN_RELAY_4, HIGH);
Serial.begin(9600);
lcd.init();
Timer1.initialize(1000000); // 1000000 -> 1 secod (10000 test)
Timer1.attachInterrupt( relaysTimeout ); // attach the service routine here
}
void loop() {
processButtons();
blinkTimer();
backlightTimeout();
//debug();
delay(20);
}
void relaysTimeout() {
if (CURRENT_CONFIG_SOCKET == 0)
{
RELAY_1_TIMEOUT--;
if (RELAY_1_TIMEOUT < 0) {
RELAY_1_TIMEOUT = 0;
}
RELAY_2_TIMEOUT--;
if (RELAY_2_TIMEOUT < 0) {
RELAY_2_TIMEOUT = 0;
}
RELAY_3_TIMEOUT--;
if (RELAY_3_TIMEOUT < 0) {
RELAY_3_TIMEOUT = 0;
}
RELAY_4_TIMEOUT--;
if (RELAY_4_TIMEOUT < 0) {
RELAY_4_TIMEOUT = 0;
}
digitalWrite(PIN_LED_1, RELAY_1_TIMEOUT > 0 ? HIGH : LOW);
digitalWrite(PIN_RELAY_1, RELAY_1_TIMEOUT > 0 ? LOW : HIGH);
digitalWrite(PIN_LED_2, RELAY_2_TIMEOUT > 0 ? HIGH : LOW);
digitalWrite(PIN_RELAY_2, RELAY_2_TIMEOUT > 0 ? LOW : HIGH);
digitalWrite(PIN_LED_3, RELAY_3_TIMEOUT > 0 ? HIGH : LOW);
digitalWrite(PIN_RELAY_3, RELAY_3_TIMEOUT > 0 ? LOW : HIGH);
digitalWrite(PIN_LED_4, RELAY_4_TIMEOUT > 0 ? HIGH : LOW);
digitalWrite(PIN_RELAY_4, RELAY_4_TIMEOUT > 0 ? LOW : HIGH);
}
}
void debug() {
Serial.print(LAST_BTN_SELECT_STATUS);
Serial.print(", ");
Serial.print(LAST_BTN_ADD_STATUS);
Serial.print(", ");
Serial.print(LAST_BTN_REMOVE_STATUS);
Serial.print(" - (");
Serial.print(CURRENT_CONFIG_SOCKET);
Serial.print("|");
Serial.print(CURRENT_CONFIG_TIME);
Serial.println(")");
}
void backlightTimeout() {
bool active = digitalRead(PIN_BTN_SELECT) == HIGH ||
digitalRead(PIN_BTN_ADD) == HIGH ||
digitalRead(PIN_BTN_REMOVE) == HIGH;
if (active) {
BACKLIGHT_TIMEOUT = 100;
}
BACKLIGHT_TIMEOUT--;
if (BACKLIGHT_TIMEOUT < 0) {
BACKLIGHT_TIMEOUT = 0;
lcd.noBacklight();
lcd.noDisplay();
lcd.clear();
lcd.print("- PRESS SELECT -");
setRelayTimeoutConfig();
CURRENT_CONFIG_SOCKET = 0;
BLINK_LED_PIN = -1;
}
else {
lcd.backlight();
lcd.display();
}
}
void blinkTimer() {
if (BLINK_LED_PIN == -1) {
return;
}
BLINK_BTN_TIMER--;
if (BLINK_BTN_TIMER < -10) {
BLINK_BTN_TIMER = 10;
}
if (BLINK_BTN_TIMER > 0) {
digitalWrite(BLINK_LED_PIN, HIGH);
}
else {
digitalWrite(BLINK_LED_PIN, LOW);
}
}
void blinkLed(int pin) {
digitalWrite(BLINK_LED_PIN, HIGH);
BLINK_LED_PIN = pin;
BLINK_BTN_TIMER = 10;
}
void processButtons() {
int btnSelectStatus = digitalRead(PIN_BTN_SELECT);
int btnAddStatus = digitalRead(PIN_BTN_ADD);
int btnRemoveStatus = digitalRead(PIN_BTN_REMOVE);
if (btnSelectStatus == HIGH && LAST_BTN_SELECT_STATUS == LOW) {
setRelayTimeoutConfig(); // Store last config
CURRENT_CONFIG_SOCKET++;
if (CURRENT_CONFIG_SOCKET > 3 /*4*/) {
CURRENT_CONFIG_SOCKET = 1;
}
if (CURRENT_CONFIG_SOCKET == 1) {
blinkLed(PIN_LED_1);
digitalWrite(PIN_LED_2, LOW);
digitalWrite(PIN_LED_3, LOW);
digitalWrite(PIN_LED_4, LOW);
}
if (CURRENT_CONFIG_SOCKET == 2) {
blinkLed(PIN_LED_2);
digitalWrite(PIN_LED_1, LOW);
digitalWrite(PIN_LED_3, LOW);
digitalWrite(PIN_LED_4, LOW);
}
if (CURRENT_CONFIG_SOCKET == 3) {
blinkLed(PIN_LED_3);
digitalWrite(PIN_LED_1, LOW);
digitalWrite(PIN_LED_2, LOW);
digitalWrite(PIN_LED_4, LOW);
}
if (CURRENT_CONFIG_SOCKET == 4) {
blinkLed(PIN_LED_4);
digitalWrite(PIN_LED_1, LOW);
digitalWrite(PIN_LED_2, LOW);
digitalWrite(PIN_LED_3, LOW);
CURRENT_CONFIG_SOCKET = 1;
}
CURRENT_CONFIG_TIME = 1;
displayConfig();
}
if (btnAddStatus == HIGH && LAST_BTN_ADD_STATUS == LOW && CURRENT_CONFIG_SOCKET > 0) {
CURRENT_CONFIG_TIME++;
if (CURRENT_CONFIG_TIME > 8) {
CURRENT_CONFIG_TIME = 8;
}
displayConfig();
}
if (btnRemoveStatus == HIGH && LAST_BTN_REMOVE_STATUS == LOW && CURRENT_CONFIG_SOCKET > 0) {
CURRENT_CONFIG_TIME--;
if (CURRENT_CONFIG_TIME < 0) {
CURRENT_CONFIG_TIME = 0;
}
displayConfig();
}
LAST_BTN_SELECT_STATUS = btnSelectStatus;
LAST_BTN_REMOVE_STATUS = btnRemoveStatus;
LAST_BTN_ADD_STATUS = btnAddStatus;
}
void setRelayTimeoutConfig() {
if (CURRENT_CONFIG_SOCKET == 1) {
if (CURRENT_CONFIG_TIME == 0) {
RELAY_1_TIMEOUT = 0;
}
else if (CURRENT_CONFIG_TIME == 2) {
RELAY_1_TIMEOUT = 30 * 60UL;
}
else if (CURRENT_CONFIG_TIME == 3) {
RELAY_1_TIMEOUT = 60 * 60UL;
}
else if (CURRENT_CONFIG_TIME == 4) {
RELAY_1_TIMEOUT = 120 * 60UL;
}
else if (CURRENT_CONFIG_TIME == 5) {
RELAY_1_TIMEOUT = 240 * 60UL;
}
else if (CURRENT_CONFIG_TIME == 6) {
RELAY_1_TIMEOUT = 480 * 60UL;
}
else if (CURRENT_CONFIG_TIME == 7) {
RELAY_1_TIMEOUT = 1440 * 60UL;
}
else if (CURRENT_CONFIG_TIME == 8) {
RELAY_1_TIMEOUT = 2880 * 60UL;
}
}
if (CURRENT_CONFIG_SOCKET == 2) {
if (CURRENT_CONFIG_TIME == 0) {
RELAY_2_TIMEOUT = 0;
}
else if (CURRENT_CONFIG_TIME == 2) {
RELAY_2_TIMEOUT = 30 * 60UL;
}
else if (CURRENT_CONFIG_TIME == 3) {
RELAY_2_TIMEOUT = 60 * 60UL;
}
else if (CURRENT_CONFIG_TIME == 4) {
RELAY_2_TIMEOUT = 120 * 60UL;
}
else if (CURRENT_CONFIG_TIME == 5) {
RELAY_2_TIMEOUT = 240 * 60UL;
}
else if (CURRENT_CONFIG_TIME == 6) {
RELAY_2_TIMEOUT = 480 * 60UL;
}
else if (CURRENT_CONFIG_TIME == 7) {
RELAY_2_TIMEOUT = 1440 * 60UL;
}
else if (CURRENT_CONFIG_TIME == 8) {
RELAY_2_TIMEOUT = 2880 * 60UL;
}
}
if (CURRENT_CONFIG_SOCKET == 3) {
if (CURRENT_CONFIG_TIME == 0) {
RELAY_3_TIMEOUT = 0;
}
else if (CURRENT_CONFIG_TIME == 2) {
RELAY_3_TIMEOUT = 30 * 60UL;
}
else if (CURRENT_CONFIG_TIME == 3) {
RELAY_3_TIMEOUT = 60 * 60UL;
}
else if (CURRENT_CONFIG_TIME == 4) {
RELAY_3_TIMEOUT = 120 * 60UL;
}
else if (CURRENT_CONFIG_TIME == 5) {
RELAY_3_TIMEOUT = 240 * 60UL;
}
else if (CURRENT_CONFIG_TIME == 6) {
RELAY_3_TIMEOUT = 480 * 60UL;
}
else if (CURRENT_CONFIG_TIME == 7) {
RELAY_3_TIMEOUT = 1440 * 60UL;
}
else if (CURRENT_CONFIG_TIME == 8) {
RELAY_3_TIMEOUT = 2880 * 60UL;
}
}
if (CURRENT_CONFIG_SOCKET == 4) {
if (CURRENT_CONFIG_TIME == 0) {
RELAY_4_TIMEOUT = 0;
}
else if (CURRENT_CONFIG_TIME == 2) {
RELAY_4_TIMEOUT = 30 * 60UL;
}
else if (CURRENT_CONFIG_TIME == 3) {
RELAY_4_TIMEOUT = 60 * 60UL;
}
else if (CURRENT_CONFIG_TIME == 4) {
RELAY_4_TIMEOUT = 120 * 60UL;
}
else if (CURRENT_CONFIG_TIME == 5) {
RELAY_4_TIMEOUT = 240 * 60UL;
}
else if (CURRENT_CONFIG_TIME == 6) {
RELAY_4_TIMEOUT = 480 * 60UL;
}
else if (CURRENT_CONFIG_TIME == 7) {
RELAY_4_TIMEOUT = 1440 * 60UL;
}
else if (CURRENT_CONFIG_TIME == 8) {
RELAY_4_TIMEOUT = 2880 * 60UL;
}
}
}
void displayConfig() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" CONFIG");
lcd.setCursor(0, 1);
lcd.print("#");
if (CURRENT_CONFIG_SOCKET == 1) {
lcd.print("1");
}
else if (CURRENT_CONFIG_SOCKET == 2) {
lcd.print("2");
}
else if (CURRENT_CONFIG_SOCKET == 3) {
lcd.print("3");
}
else if (CURRENT_CONFIG_SOCKET == 4) {
lcd.print("4");
}
lcd.print(": ");
if (CURRENT_CONFIG_TIME == 0) {
lcd.print("Disable");
}
else if (CURRENT_CONFIG_TIME == 1) {
if (CURRENT_CONFIG_SOCKET == 1 && RELAY_1_TIMEOUT > 0) {
lcd.print("(");
lcd.print(RELAY_1_TIMEOUT / 60);
lcd.print(" min)");
}
else if (CURRENT_CONFIG_SOCKET == 2 && RELAY_2_TIMEOUT > 0) {
lcd.print("(");
lcd.print(RELAY_2_TIMEOUT / 60);
lcd.print(" min)");
}
else if (CURRENT_CONFIG_SOCKET == 3 && RELAY_3_TIMEOUT > 0) {
lcd.print("(");
lcd.print(RELAY_3_TIMEOUT / 60);
lcd.print(" min)");
}
else if (CURRENT_CONFIG_SOCKET == 4 && RELAY_4_TIMEOUT > 0) {
lcd.print("(");
lcd.print(RELAY_4_TIMEOUT / 60);
lcd.print(" min)");
}
else {
lcd.print("-------");
}
}
else if (CURRENT_CONFIG_TIME == 2) {
lcd.print("30 min");
}
else if (CURRENT_CONFIG_TIME == 3) {
lcd.print("1 hour");
}
else if (CURRENT_CONFIG_TIME == 4) {
lcd.print("2 hours");
}
else if (CURRENT_CONFIG_TIME == 5) {
lcd.print("4 hours");
}
else if (CURRENT_CONFIG_TIME == 6) {
lcd.print("8 hours");
}
else if (CURRENT_CONFIG_TIME == 7) {
lcd.print("1 day");
}
else if (CURRENT_CONFIG_TIME == 8) {
lcd.print("2 days");
}
// Disable ->
// 30 min -> 30
// 1 hour -> 60
// 2 hour -> 120
// 4 hour -> 240
// 8 hour -> 480
// 1 day -> 1440
// 2 days -> 2880
}
0 Comments