Hello !
I already have this counter code I got here with 3 buttons for
- Normal increment (1,2,3,4,5. . . . . . )
- Normal Decrement (5,4,3,2....)
- Decade Increment (1,11,21,31,. . . ) or (41,31,21,11......)
Holding third button and pressing Up or Down key causes a decade of count
All Set
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
#include <TM1637Display.h>
#define CLK 3
#define DIO 2
TM1637Display display = TM1637Display (CLK, DIO);
#include<Keypad.h>
char customKey=0;
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char hexaKeys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {A15, A14, A13, A12}; //row pinouts of the keypad
byte colPins[COLS] = {A11, A10, A9, A8}; //column pinouts of the keypad
Keypad kpd = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); //initialize an instance of class NewKeypad
const byte LockInd = 47;
signed long count = 1; // Changed to 0 so that COUNTUP starts with 1
int IN4 = 4;
int IN5 = 5;
int IN6 = 6;
const unsigned long shortWaitTime = 20;
const unsigned long longWaitTime = 150;
struct pressButtonType
{
byte Pin;
unsigned long lastChange;
int lastState;
int state;
boolean pressed();
};
boolean pressButtonType::pressed()
{
int state = digitalRead(pressButtonType::Pin);
if (state != pressButtonType::lastState) {
pressButtonType::lastChange = millis();
pressButtonType::lastState = state;
}
if (state != pressButtonType::state && millis() - pressButtonType::lastChange > 50) {
pressButtonType::state = state;
};
return !pressButtonType::state;
}
enum CountStates {idle, COUNTUP, COUNTDOWN, COUNTUPDEC, COUNTDOWNDEC};
CountStates actState = idle;
CountStates lastState = idle;
signed long StartCountUpDec = 1; // Used by COUNTUPDEC when the counting limit has been reached
signed long StartCountDownDec = 500; // Used by COUNTDOWNDEC when the counting limit has been reached
pressButtonType but4 = {IN4, 0, HIGH};
pressButtonType but5 = {IN5, 0, HIGH};
pressButtonType but6 = {IN6, 0, HIGH};
unsigned long startTime;
bool holding = false;
bool longPress = false;
int keyHeld;
String msg;
unsigned long startHold = 0;
uint16_t intervalLongPress = 1000;
unsigned long startRepeat = 0;
uint16_t intervalRepeat = 100;
void setup() {
Serial.begin(9600);
lcd.init();
lcd.backlight();
display.setBrightness(4);
pinMode (LockInd, OUTPUT);
digitalWrite(LockInd,LOW);
pinMode(4, INPUT_PULLUP);
pinMode(5, INPUT_PULLUP);
pinMode(6, INPUT_PULLUP);
Serial.print(count);
}
String ActStartNo = String(count);
boolean Error = false;
void loop() {
StateMachine();
static String StartNo = "";
}
void StateMachine()
{
static unsigned long lastActionTime = 0;
static unsigned long WaitTime = longWaitTime;
switch (actState)
{
case idle : if (but4.pressed())
{
actState = COUNTUP;
};
if (but5.pressed())
{
actState = COUNTDOWN;
};
if (but6.pressed() && but4.pressed())
{
actState = COUNTUPDEC;
StartCountUpDec = (count % 10); // Sets the COUNTUPDEC start value to actual (count modulo 10)
// Which is the last decimal of count (e.g. 8 for 18)
if (count + 10 >= 500)
count = StartCountDownDec;
}
if (but6.pressed() && but5.pressed())
{
actState = COUNTDOWNDEC;
StartCountDownDec = 500 + (count % 10);
if (count - 10 <= 1)
count = StartCountDownDec;
};
WaitTime = longWaitTime;
break;
case COUNTUP :
if (but5.pressed()) WaitTime = shortWaitTime;
else WaitTime = longWaitTime;
if (but4.pressed() && millis()-lastActionTime >= WaitTime)// || case 'C')
{
lastActionTime = millis();
if(count<500)
{
count=count+1;
lcd.setCursor(11,1);
lcd.print(" "); // Deleting previous data in row 2 on the left side only!
lcd.setCursor(11,1);
lcd.print(count);
display.showNumberDec(count);
Serial.print(count);
}
else
{
count=1;
lcd.setCursor(11,1);
lcd.print(" "); // Deleting previous data in row 2 on the left side only!
lcd.setCursor(11,1);
lcd.print(count);
display.showNumberDec(count);
Serial.print(count);
}
}
if (!but4.pressed() && !but5.pressed()) actState = idle;
break;
case COUNTDOWN :
if (but4.pressed()) WaitTime = shortWaitTime;
else WaitTime = longWaitTime;
if (but5.pressed() && millis()-lastActionTime >= WaitTime)
{
lastActionTime = millis();
if(count>1)
{
count=count-1;
lcd.setCursor(11,1);
lcd.print(" "); // Deleting previous data in row 2 on the left side only!
lcd.setCursor(11,1);
lcd.print(count);
display.showNumberDec(count);
Serial.print(count);
}
else
{
count=500;
lcd.setCursor(11,1);
lcd.print(" "); // Deleting previous data in row 2 on the left side only!
lcd.setCursor(11,1);
lcd.print(count);
display.showNumberDec(count);
Serial.print(count);
}
//Serial.println(count);
}
if (!but4.pressed() && !but5.pressed()) actState = idle;
break;
//*
case COUNTUPDEC :
if (but5.pressed()) WaitTime = shortWaitTime;
else WaitTime = longWaitTime;
if (but4.pressed() && millis()-lastActionTime >= WaitTime)
{
lastActionTime = millis();
//if(count+10<100) // Added (+10) do avoid counting over 100
if(count<=500)
{
count=count+10;
lcd.setCursor(11,1);
lcd.print(" "); // Deleting previous data in row 2 on the left side only!
lcd.setCursor(11,1);
lcd.print(count);
display.showNumberDec(count);
Serial.print(count);
}
else
{
count=StartCountUpDec; // Reset count
lcd.setCursor(11,1);
lcd.print(" "); // Deleting previous data in row 2 on the left side only!
lcd.setCursor(11,1);
lcd.print(count);
display.showNumberDec(count);
Serial.print(count);
}
//Serial.println(count);
}
if (!but4.pressed() && !but5.pressed()) actState = idle;
break;
case COUNTDOWNDEC :
if (but4.pressed()) WaitTime = shortWaitTime;
else WaitTime = longWaitTime;
if (but5.pressed() && millis()-lastActionTime >= WaitTime)
{
lastActionTime = millis();
if(count>=1)
// if(count>=1)// && count<=444)
{
count=count-10;
lcd.setCursor(11,1);
lcd.print(" "); // Deleting previous data in row 2 on the left side only!
lcd.setCursor(11,1);
lcd.print(count);
display.showNumberDec(count);
Serial.print(count);
}
else
{
//count=StartCountDownDec;
count=500; // Reset count
lcd.setCursor(11,1);
lcd.print(" "); // Deleting previous data in row 2 on the left side only!
lcd.setCursor(11,1);
lcd.print(count);
display.showNumberDec(count);
Serial.print(count);
}
//Serial.println(count);
}
if (!but4.pressed() && !but5.pressed()) actState = idle;
break;
default : actState = idle;
break;
} // END of switch (actState)
}// End of void StateMachine()
.
.
..
.
It has a range from 1 to 500 for count
For a decade count while holding 3rd button(6) and pressing Upkey(4)
When it reaches to 491 its next count is 1 then 11 then 21 and so on . . .
but before going to 1 it shows 501 once then proceed to 1
Same thing for
492 => 502 => 2
493 => 503 => 3
But for slow press one by one it works very well
Now coming to Down key for decade
But when we try to proceed in backward direction say from 41
it counts like
41 => 31 => 21 => 11 => 491
It jumps 491 to 11 directly without taking '1' in the list
For other numbers like
43 => 33 => 23 => 13 => 3 => -7 => 500
One -7 gets an entry
and any other count directly comes to 500 and then 490 480 470 . . . like that
I mean to say
Too many wrong functions are there in the operation while doing a hold or fast count
The decade count should be like just a normal one :-
Up Count be like
Suppose from 483 ,493 ,3 ,13, 23 . . . like that
or
475 , 485 , 495 , 5 , 15 , 25 , 35 . . . like that
and
Down Count be like
Suppose 26 , 16 , 6 , 496 , 486 . . . . like that
or
41 , 31 , 21 , 11 , 1 , 491 , 481 , 471 . . . . like that
Please Guide
In case of any query please ask to make operational things clear !!