Hi,
I am facing challenge that when i press button, it skips values not stable might be taking multiple times pressing values. i press single time and changed debounce time in code but not resolved.
please review my code. Its a Clock project with Max7219 and DS3231
/*
DataIn/DIN D12
CLK D11
LOAD/CS D10
SCL A5
SDA A4
SQW
Menu Set Button D3
Increment Button D4
Decrement Button D5
*/
#include <LedControl.h>
#include <DS3231RTC.h>
#include <MyFont.h>
#include <ezButton.h>
byte devices = 4;
byte bright = 5; // Default intensity/brightness (0-15)
LedControl lc = LedControl(12, 11, 10, devices);
// pin 12 is connected to the DataIn on the display
// pin 11 is connected to the CLK on the display
// pin 10 is connected to LOAD on the display
/*****************************************************************/
/* Clock Modes
AM Mode 0
PM Mode 1
24 Hour Mode 2 */
const byte AMhr = 0;
const byte PMhr = 1;
const byte M24hr = 2;
//Clocks
const byte clock0 = 0;
const byte alarm1 = 1;
const byte alarm2 = 2;
/*****************************************************************/
const byte RTC_addr = 0x68; // I2C address of DS3231 RTC
const byte EEPROM_addr = 0x57; // I2C address of AT24C32N EEPROM
const bool INTCN = true; // allows SQW pin to be monitored
bool blinkdots = true;
unsigned long CurrentMillis;
unsigned long PreviousMillis;
byte ClockState;
int Hour, Min, Sec, DOW, DAY, Month, Year, Clockmode;
DateTime NowTime; //create DateTime struct from Library
DS3231RTC Clock(RTC_addr, EEPROM_addr, INTCN);
/*****************************************************************/
ezButton Button_Set_Pin(3); // Button for display Menu and set // Snooze Pin
ezButton Button_Inc_Pin(4); // Button for incrementing Value
ezButton Button_Dec_Pin(5); // Button for decrementing Value
/*****************************************************************/
void GetTime()
{
NowTime = Clock.read(); // get the latest clock values
Sec = NowTime.Second;
Min = NowTime.Minute;
Hour = NowTime.Hour;
DOW = NowTime.Dow; // Day of Week
DAY = NowTime.Day;
Month = NowTime.Month;
Year = NowTime.Year;
Clockmode = NowTime.ClockMode;
/*
Serial.println();
Serial.print("Current Time is ");
Serial.print(Hour);
Serial.print(":");
Serial.print(Min);
Serial.print(":");
Serial.println(Sec);
Serial.print("Today's Date is ");
Serial.print(p2Digits(DAY));
Serial.print("/");
Serial.print(p2Digits(Month));
Serial.print("/");
Serial.println(Year);
Serial.print("Today's Day is ");
Serial.println(dow2Str(DOW));
Serial.print("Clock mode is ");
Serial.println(Clockmode); */
}
/*****************************************************************/
void TimeDisplay()
{
blinkdots = !blinkdots;
MaxDisplay(3, (Hour / 10) + 48, 3);
MaxDisplay(2, (Hour % 10) + 48, 1);
MaxDisplay(1, (Min / 10) + 48, 2);
MaxDisplay(0, (Min % 10) + 48, 0);
}
/*****************************************************************/
void MaxDisplay(byte address, byte character, byte offset)
{
if (character >= 0x20 && character <= 0x7f)
{
for (int a = 0; a < 7; a++)
{
unsigned long c = pgm_read_byte_near(font5x7 + ((character - 0x20) * 8) + a);
unsigned long x = c >> offset;
lc.setRow(address, a, x); //setRow(int addr, int row, byte value)
if (address == 2)
{
if (a == 1)
lc.setLed(2, 1, 7, blinkdots); //setLed(int addr, int row, int column, boolean state)
if (a == 2)
lc.setLed(2, 2, 7, blinkdots);
if (a == 5)
lc.setLed(2, 5, 7, blinkdots);
if (a == 6)
lc.setLed(2, 6, 7, blinkdots);
}
if (address == 1)
{
if (a == 1)
lc.setLed(1, 1, 0, blinkdots); //setLed(int addr, int row, int column, boolean state)
if (a == 2)
lc.setLed(1, 2, 0, blinkdots);
if (a == 5)
lc.setLed(1, 5, 0, blinkdots);
if (a == 6)
lc.setLed(1, 6, 0, blinkdots);
}
}
}
}
/*****************************************************************/
void ChangeMinute(byte i = 0, bool increment = true)
{
/* Increments or decrements the minute by one
* i = 0 Clock
* = 1 Alarm1
* = 2 Alarm2
*/
if (increment == true)
{
Min++;
if (Min > 59)
{
Min = 0;
}
}
else
{
Min--;
if (Min < 0)
{
Min = 59;
}
}
Clock.ChangeMin(Min);
}
/*****************************************************************/
void ChangeHour(byte i = clock0, bool increment = true)
{
switch (Clockmode)
{
case AMhr:
case PMhr:
if (increment == true)
{
Hour++;
if (Hour > 12)
{
Hour = 0;
}
}
else
{
Hour--;
if (Hour < 0)
{
Hour = 12;
}
}
break;
case M24hr:
if (increment == true)
{
Hour++;
if (Hour > 24)
{
Hour = 0;
}
}
else
{
Hour--;
if (Hour < 0)
{
Hour = 23;
}
}
break;
}
Clock.ChangeHour(Clockmode, Hour);
}
void ChangeClockMode(byte i = clock0, bool increment = true)
{
/* Change Clock's Clockmode to AM=0, PM=1 or 24=2
* Limited change of Alarm's Clockmode to AM or PM
* or no change if 24hr
* i = 0 Clock0
* = 1 Alarm1
* = 2 Alarm2
*/
switch (i)
{
case clock0:
if (increment == true)
{
Clockmode += 1;
Clockmode %= 3;
}
else
{
Clockmode -= 1;
Clockmode %= 3;
}
if (Clockmode < 0)
{
Clockmode = 2;
}
//byte(Clockmode);
Clock.ChangeHour(byte(Clockmode), Hour);
break;
}
}
void ChangeDate(byte i = 0, bool increment = true)
{
byte DaysMax = 31;
switch (Month)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
DaysMax = 31;
break;
case 2:
DaysMax = 28;
if ((Year % 4 == 0) && (Year % 100 != 0) || (Year % 400 == 0))
{
//those are the conditions to have a leap year
DaysMax = 29;
}
break;
case 4:
case 6:
case 9:
case 11:
DaysMax = 30;
break;
default:
break;
}
if (increment == true)
{
DAY += 1;
}
if (increment == false)
{
DAY -= 1;
}
if (DAY < 1)
{
DAY = DaysMax;
}
if (DAY > DaysMax)
{
DAY = 1;
}
Clock.ChangeDate(byte(DAY));
}
void ChangeMonth(byte i = 0, bool increment = true)
{
if (increment == true)
{
Month++;
if (Month > 12)
{
Month = 0;
}
}
else
{
Month--;
if (Month < 0)
{
Month = 12;
}
}
Clock.ChangeMonth(Month);
}
/*****************************************************************/
String dow2Str(byte bDow)
{
// Day of week to string or char array. DOW 1=Sunday, 0 is undefined
static const char *str[] = {"---", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
if (bDow > 7)
bDow = 0;
return (str[bDow]);
}
String p2Digits(int numValue)
{
// utility function for digital clock display
// converts int to two digit char array
String str;
if (numValue < 10)
{
str = "0" + String(numValue);
}
else
{
str = String(numValue);
}
return str;
}
/*****************************************************************/
void setup()
{
Serial.begin(9600);
Button_Set_Pin.setDebounceTime(100); // set debounce time to 50 milliseconds
Button_Inc_Pin.setDebounceTime(100); // set debounce time to 50 milliseconds
Button_Dec_Pin.setDebounceTime(100); // set debounce time to 50 milliseconds
Clock.begin();
for (int i = 0; i < devices; i++)
{
lc.shutdown(i, false);
lc.setIntensity(i, bright); //set light intensity 0 - min, 15 - max
lc.clearDisplay(i); //Clear Display
}
}
void loop()
{
Button_Set_Pin.loop();
Button_Inc_Pin.loop();
Button_Dec_Pin.loop();
/* if (Button_Set_Pin.isPressed())
Serial.println("The Menu button is pressed");
if (Button_Set_Pin.isReleased())
Serial.println("The Menu button is released");
if (Button_Inc_Pin.isPressed())
Serial.println("The Increment button is pressed");
if (Button_Inc_Pin.isReleased())
Serial.println("The Increment button is released");
if (Button_Dec_Pin.isPressed())
Serial.println("The Decrement button is pressed");
if (Button_Dec_Pin.isReleased())
Serial.println("The Decrement button is released");
*/
switch (ClockState)
{
case 0:
CurrentMillis = millis();
if (CurrentMillis - PreviousMillis >= 500)
{
PreviousMillis = CurrentMillis;
GetTime();
TimeDisplay();
}
if (Button_Set_Pin.isPressed())
{
ClockState = 1;
}
break;
case 1:
// For Change Hour
MaxDisplay(3, (Hour / 10) + 48, 3);
MaxDisplay(2, (Hour % 10) + 48, 1);
MaxDisplay(1, 32, 2); // for printing Space on screen
MaxDisplay(0, 72, 0); // For printing 'H' on screen
if (Button_Inc_Pin.isPressed())
{
ChangeHour(clock0, true);
}
if (Button_Dec_Pin.isPressed())
{
ChangeHour(clock0, false);
}
if (Button_Set_Pin.isPressed())
{
ClockState = 2;
}
break;
case 2:
// For Change Minutes
MaxDisplay(3, 77, 3);
MaxDisplay(2, 32, 1);
MaxDisplay(1, (Min / 10) + 48, 2);
MaxDisplay(0, (Min % 10) + 48, 0);
if (Button_Inc_Pin.isPressed())
{
ChangeMinute(clock0, true);
}
if (Button_Dec_Pin.isPressed())
{
ChangeMinute(clock0, false);
}
if (Button_Set_Pin.isPressed())
{
ClockState = 3;
}
break;
case 3:
// For Change Brightness
MaxDisplay(3, 66, 3);
MaxDisplay(2, 32, 1);
MaxDisplay(1, (bright / 10) + 48, 2);
MaxDisplay(0, (bright % 10) + 48, 0);
if (Button_Inc_Pin.isPressed())
{
bright++;
if (bright > 15)
{
bright = 0;
}
}
if (Button_Dec_Pin.isPressed())
{
bright--;
if (bright < 0)
{
bright = 15;
}
}
if (Button_Set_Pin.isPressed())
{
ClockState = 4;
}
break;
case 4: // Set Date
MaxDisplay(3, 68, 3);
MaxDisplay(2, 68, 1);
MaxDisplay(1, (DAY / 10) + 48, 2);
MaxDisplay(0, (DAY % 10) + 48, 0);
if (Button_Inc_Pin.isPressed())
{
ChangeDate(clock0, true);
}
if (Button_Dec_Pin.isPressed())
{
ChangeDate(clock0, false);
}
if (Button_Set_Pin.isPressed())
{
ClockState = 5;
}
break;
case 5: // Set Month
MaxDisplay(3, 77, 3);
MaxDisplay(2, 77, 1);
MaxDisplay(1, (Month / 10) + 48, 2);
MaxDisplay(0, (Month % 10) + 48, 0);
if (Button_Inc_Pin.isPressed())
{
ChangeMonth(clock0, true);
}
if (Button_Dec_Pin.isPressed())
{
ChangeMonth(clock0, false);
}
if (Button_Set_Pin.isPressed())
{
ClockState = 6;
}
break;
case 6: // Set Year
MaxDisplay(3, 89, 3);
MaxDisplay(2, 89, 1);
MaxDisplay(1, (Year / 10) + 48, 2);
MaxDisplay(0, (Year % 10) + 48, 0);
if (Button_Inc_Pin.isPressed())
{
Year++;
if (Year > 50)
{
Year = 0;
}
}
if (Button_Dec_Pin.isPressed())
{
Year--;
if (Year < 0)
{
Year = 50;
}
}
if (Button_Set_Pin.isPressed())
{
ClockState = 7;
}
break;
case 7:
// For Change Clock Mode
/* Clock Modes
AM Mode 0
PM Mode 1
24 Hour Mode 2 */
MaxDisplay(3, 67, 3);
MaxDisplay(2, 77, 1);
if (Clockmode == 0) // For print 12hr/AM Format
{
MaxDisplay(1, 65, 2); // A
MaxDisplay(0, 77, 0); // M
}
if (Clockmode == 1) // For print 12hr/AM Format
{
MaxDisplay(1, 80, 2); // P
MaxDisplay(0, 77, 0); // M
}
if (Clockmode == 2) // For print 24hr Format
{
MaxDisplay(1, 2 + 48, 2);
MaxDisplay(0, 4 + 48, 0);
}
if (Button_Inc_Pin.isPressed())
{
ChangeClockMode(clock0, true);
}
if (Button_Dec_Pin.isPressed())
{
ChangeClockMode(clock0, false);
}
if (Button_Set_Pin.isPressed())
{
ClockState = 0;
}
break;
// do something
}
}