Up or DOwn DECADE Count issue

Hello !

I already have this counter code I got here with 3 buttons for

  1. Normal increment (1,2,3,4,5. . . . . . )
  2. Normal Decrement (5,4,3,2....)
  3. 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 !!

Are you sure your buttons are properly debounced?

means how ?
In terms of software
or Hardware ?

It doesn't matter how you do it - it just needs to be done!

2 Likes

OK , So what changes it needs to get the target ?

I didn't understand the use of this "if" in "case COUNTUPDEC :"

if (count <= 500)
{
count = count + 10;
...................

If it goes from 491 to 500, it will have 501 to 510.

And this one in " case COUNTDOWNDEC :"

if (count >= 1)
{
count = count - 10;
.......................

If it goes from 1 to 10 , it will have -9 to 0.

Ya exactly I too got confused with that thing

Its for a decade count actually but it goes that I don't have any idea

Please if possible would you please correct that decade up and down script please !!

I don't quite understand your need, but see if it's like this:

(I modified and reduced some routines of your code).

" Counter - Wokwi ESP32, STM32, Arduino Simulator

O yess yess yess yess yess !!!

The exactly thing I want to have
All the way great it is

Actually its a kind of counter which can be used in any of the application

Answer for how to get an example thing is

Bank counter or token machine
An ATM, Query machine, pass book printing

Any building where limit of people say 300 are only allowed so we can bound a timer which can count 300 people and make a beep of
All seat engaged

That bounded number can be entered with help of such counters
or a keypad can also be included in addition to this one

Just example I am giving

Sir Thanks from my bottom of Heart :blush:

If we want to go for a range of some out of box figure say 1 - 444

In Decade UpCount
When counter reaches 435 it ll jump directly to 5
Same for
436 to 6
437 to 7
438 to 8
439 to 9
440 to 10

In Decade DownCount
When counter reaches 5 it ll jump directly to 435
Same for
6 to 436
7 to 437
8 to 438
9 to 439
10 to 440

For learning purpose I want a design from you if you can Sir
Please !!!

Correct

Ya Sir
For that purpose I am working with such designs

It can be helpful in many ways !!

Ya Sir please have me the 1-444 range counter code
If possible !!!
Thanks once again

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.