/*
* Smart Plug for mobile Charger created by A.V.Pradeep
*
* Last modified version: V2.0
*
* Last updated Time: 22-02-2024 at 11:45
*
* For more details, visit https://esp32io.com/tutorials/esp32-tm1637-4-digit-7-segment-display
*/
#include <TM1637Display.h>
#include <ezButton.h>
#include "EEPROM.h"
#pragma region Declarations
#define LED1 33
#define LED2 32
#define LED3 21
#define LED4 18
#define LED5 19
#define LED6 15
#define LED7 2
#define CLK 22 // The ESP32 pin GPIO22 connected to CLK
#define DIO 23 // The ESP32 pin GPIO23 connected to DIO
ezButton button1(25); // create ezButton object that attach to pin 6;
ezButton button2(26); // create ezButton object that attach to pin 7;
ezButton button3(27); // create ezButton object that attach to pin 8;
ezButton button4(14); // create ezButton object that attach to pin 8;
ezButton button5(13); // create ezButton object that attach to pin 6;
#define SHORT_PRESS_TIME 500 // 500 milliseconds
#define LONG_PRESS_TIME 1000 // 1000 milliseconds
unsigned long pressedTime = 0;
unsigned long releasedTime = 0;
unsigned long PrevMillis = 0;
bool Blink = true;
uint8_t data[] = {0x0, 0x0, 0x0, 0x0}; // variable for blinking the digits
bool isPressing = false;
bool isLongDetected = false;
int CurrentButton = 0; // last button pressed
int lastState = LOW; // the previous state from the input pin
int currentState; // the current reading from the input pin
int defaultTime = 45; // initial time if not saved previously
int Mode = 0;
int CurrntPos = 4; // start from right most
int HoursTens = 0; // Hours left digit
int HoursOnes = 1; // hours rifght digit
int MinutesTens = 1; //minutes left digit
int MinutesOnes = 0; //minutes right digit
int Sec_Count = 0 ;
int Min_Count = 0 ;
int Hrs_Count = 0;
int ChargeMinutes = (HoursTens*10 + HoursOnes)*60 + (MinutesTens*10 + MinutesOnes);
// create a display object of type TM1637Display
TM1637Display display = TM1637Display(CLK, DIO);
#pragma endregion Declarations
void _DisplayData()
{
// display.showNumberDec(defaultTime, false); // Expect: 0045
if (Mode == 1)
{
HoursTens = (ChargeMinutes/60)/10;
HoursOnes = (ChargeMinutes/60)%10;
MinutesTens = (ChargeMinutes%60)/10;
MinutesOnes = (ChargeMinutes%60)%10;
}
data[0]= display.encodeDigit(HoursTens);
data[1]= display.encodeDigit(HoursOnes);
data[2]= display.encodeDigit(MinutesTens);
data[3]= display.encodeDigit(MinutesOnes);
display.setSegments(data);
}
void _UpdateSegments() // Update only selected digit or segments
{
uint8_t TmpData[] = {0x0, 0x0, 0x0, 0x0};
switch(CurrntPos)
{
case 1: //leftmost digit ie tens of hours
TmpData[0] = display.encodeDigit(HoursTens);
break;
case 2: // hours ones
TmpData[0] = display.encodeDigit(HoursOnes);
break;
case 3: // Tens of Minutes
TmpData[0] = display.encodeDigit(MinutesTens);
break;
case 4: // Ones of Minutes
TmpData[0] = display.encodeDigit(MinutesOnes);
break;
}
if (Blink)
{
TmpData[0] = 0x00;
}
display.setSegments(TmpData, 1, CurrntPos-1);
}
void _PosChange(int tmp) //
{
if (tmp == 1) // increment by one
{
CurrntPos = CurrntPos+1;
if (CurrntPos >4) // exceeded the maximum right position of 4
{
CurrntPos = 4; // limit the position
}
}
else
{
CurrntPos = CurrntPos-1;
if (CurrntPos <1) // exceeded the maximum left position of 1
{
CurrntPos = 1; // limit the position
}
}
Serial.print("Current Position: ");
Serial.println(CurrntPos);
_DisplayData();
}
void _DigitChange(int tmp) //
{
switch(CurrntPos)
{
case 1: //leftmost digit ie tens of hours
HoursTens = _ChangeValue(tmp, HoursTens);
break;
case 2: // hours ones
HoursOnes = _ChangeValue(tmp, HoursOnes);
break;
case 3: // Tens of Minutes
MinutesTens = _ChangeValue(tmp, MinutesTens);
break;
case 4: // Ones of Minutes
MinutesOnes = _ChangeValue(tmp, MinutesOnes);
break;
}
_DisplayData();
}
int _ChangeValue(int tmp, int digit)
{
if (tmp == 2 ) // decrease the vaue
{
digit = digit - 1;
if (digit < 0)
{
digit = 9;
}
}
else // tmp==1 ie; increment the value
{
digit = digit + tmp;
if (digit > 9)
{
digit = 0;
}
}
return digit;
}
void _StartCharging() // "Select" button is pressed during default mode
{
Mode= 1; // manual charging mode
ChargeMinutes = ((HoursTens*10 + HoursOnes)*60) + (MinutesTens*10) + MinutesOnes;
Serial.print("ChargeMinutes: ");
Serial.println( ChargeMinutes );
}
void _CheckTime() // "Select" button is pressed
{
Sec_Count = Sec_Count + 1;
if (Sec_Count == 10) // it should be 300 in actual practice
{
Sec_Count = 0;
Min_Count = Min_Count + 1;
ChargeMinutes = ChargeMinutes -1;
_DisplayData();
Serial.print("Ellapsed Minutes: ");
Serial.println(Min_Count);
}
if (ChargeMinutes == 0)
{
Mode = 5; // OFF mode
const uint8_t SEG_OFF[] = {
0x00, // blank
SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F, // O
SEG_A | SEG_E | SEG_F | SEG_G , // F
SEG_A | SEG_E | SEG_F | SEG_G // F
};
display.setSegments(SEG_OFF); // show "OFF" on display
}
//Serial.println( "\n ");
}
void _Pressing(int ButtNo)
{
CurrentButton = ButtNo;
pressedTime = millis();
isPressing = true;
isLongDetected = false;
}
void _Releasing(int ButtNo)
{
isPressing = false;
releasedTime = millis();
CurrentButton = ButtNo;
long pressDuration = releasedTime - pressedTime;
if ( pressDuration < SHORT_PRESS_TIME )
_Short_Pressed();
}
void _Short_Pressed()
{
//Serial.print("A short press is detected on Button:");
switch (CurrentButton)
{
case 1:
_DigitChange(1); // increase the value
//Serial.println(CurrentButton);
break;
case 2:
_DigitChange(2); // decrease the value
//Serial.println(CurrentButton);
break;
case 3:
//Serial.println(CurrentButton);
_PosChange(2); // update position- 1 to right shift, any other values to left shift
break;
case 4:
//Serial.println(CurrentButton);
_PosChange(1); // update position- 1 to right shift, any other values to left shift
break;
case 5:
_StartCharging(); // start charging
//Serial.println(CurrentButton);
break;
default:
//statements here
break;
}
}
void _Long_Pressed()
{
Serial.print("A looong press is detected on Button");
isLongDetected = true;
switch (CurrentButton)
{
case 1:
digitalWrite(LED2, HIGH);
digitalWrite(LED3, HIGH);
//Serial.println(CurrentButton);
break;
case 2:
digitalWrite(LED2, HIGH);
digitalWrite(LED4, HIGH);
//Serial.println(CurrentButton);
break;
case 3:
digitalWrite(LED2, HIGH);
digitalWrite(LED5, HIGH);
//Serial.println(CurrentButton);
break;
case 4:
digitalWrite(LED2, HIGH);
digitalWrite(LED6, HIGH);
//Serial.println(CurrentButton);
break;
case 5:
digitalWrite(LED2, HIGH);
digitalWrite(LED7, HIGH);
//Serial.println(CurrentButton);
break;
default:
// statements
break;
}
}
void setup()
{
Serial.begin(115200); // Any baud rate should work
Serial.println("Initializing...\n");
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
pinMode(LED4, OUTPUT);
pinMode(LED5, OUTPUT);
pinMode(LED6, OUTPUT);
pinMode(LED7, OUTPUT);
button1.setDebounceTime(50); // set debounce time to 50 milliseconds
button2.setDebounceTime(50); // set debounce time to 50 milliseconds
button3.setDebounceTime(50); // set debounce time to 50 milliseconds
button4.setDebounceTime(50); // set debounce time to 50 milliseconds
button5.setDebounceTime(50); // set debounce time to 50 milliseconds
display.clear();
display.setBrightness(7); // set the brightness to 7 (0:dimmest, 7:brightest)
// displayed 15:30
display.showNumberDecEx(45, 0b11100000, false, 4, 0);
delay(100);
display.clear();
Serial.println("...\n");
Serial.println("Setup completed...\n");
Serial.println("...\n");
PrevMillis = millis();
_DisplayData();
// _Save_Time(); // one time use
// _GetLastTime(); // get last saved time for charging
}
void loop()
{
button1.loop();
button2.loop();
button3.loop();
button4.loop();
button5.loop();
if (button1.isPressed())
{
_Pressing(1); // call _Pressing() function
}
else if (button2.isPressed())
{
_Pressing(2); // call _Pressing() function
}
else if (button3.isPressed())
{
_Pressing(3); // call _Pressing() function
}
else if (button4.isPressed())
{
_Pressing(4); // call _Pressing() function
}
else if (button5.isPressed())
{
_Pressing(5); // call _Pressing() function
}
if (button1.isReleased())
{
_Releasing(1); // call _Releasing() function
}
else if (button2.isReleased())
{
_Releasing(2); // call _Releasing() function
}
else if (button2.isReleased())
{
_Releasing(2); // call _Releasing() function
}
else if (button3.isReleased())
{
_Releasing(3); // call _Releasing() function
}
else if (button4.isReleased())
{
_Releasing(4); // call _Releasing() function
}
else if (button5.isReleased())
{
_Releasing(5); // call _Releasing() function
}
if (isPressing == true && isLongDetected == false) {
long pressDuration = millis() - pressedTime;
if ( pressDuration > LONG_PRESS_TIME )
_Long_Pressed();
}
if (millis() - PrevMillis >200)
{
PrevMillis = millis();
Blink = !Blink; // flip the blink from true to false and vice versa
if (Mode == 1) // current mode is Manually selected charging mode
{
_CheckTime();
}
}
//_DisplayData(); // display the data on LED display
if (Mode == 0)
_UpdateSegments();
}