Increment/decrement a 4 digit number with rollovers?

Hi All,

Im not actually wanting help with code at present, but rather suggestions of technique, from which I can then go away and play with the code to see if I can make it work,

Heres the premise -

I will have a 4 digit decimal number displayed on an LCD, and also saved as a variable to be used for other purposes. I will have three buttons - UP, DOWN, and SELECT.

The SELECT button will be used to determine the position of a cursor beneath one of the four digits.

Whichever digit the cursor is under, is the number to be incremented (by the UP button) or decremented (by the DOWN) button.

Now, the inc/dec for a number isnt too much of a trouble,

but, theres a bit more to it! If the selected number rolls over, I need the next number to inc/dec by one, i.e. if incrementing the second digit, it rolls over 9 to 0, then the first must increment. Likewise for decrement, if the second for example rolls over 0 to 9 then the third must decrement by 1

Essentially like a tally counter, up or down, but with the position being worked on selectable. If the whole number rolls over, ie 9999 to 0000 or 0000 to 9999, then thats fine.

It seems to me there is probably a very simple way of implementing this, but I cant think how

Ive searched for examples of code, but I can only find inc/dec methods without the selectable digit

As I say, Im only looking for direction to a technique to then go and study

Cheers

G7MRV:
Ive searched for examples of code, but I can only find inc/dec methods without the selectable digit

Yeah and you’re not going to find that. You’re going to have to think of your number as 4 individual 1 digit numbers. Use some if statements to check for the rollover conditions and trigger one of the other digits to increment or decrement. It would probably make sense to keep the 4 digits in an array so you don’t have to rewrite the code four times.

Another approach...

  • Your count range would easily fit into an unsigned int (word).
  • Each down press decrements the count by -1, -10, -100, -1000 for each cursor position.
  • Each up press increments the count by +1, +10, +100, +1000 for each cursor position.
  • Detect "when just pressed" to adjust the count once per press.
  • Detect "press and hold" to repeatedly adjust the count at (example) 500ms intervals.
  • No need to worry about digit to digit carry/borrow.
  • Only need to ensure count stops at min (0) and max (9999).

Delta_G: Yeah and you're not going to find that. You're going to have to think of your number as 4 individual 1 digit numbers. Use some if statements to check for the rollover conditions and trigger one of the other digits to increment or decrement. It would probably make sense to keep the 4 digits in an array so you don't have to rewrite the code four times.

Ah, well thats how i'd been looking at it - a shed load of IFs

oh well, if thats the way so be it, had hoped there would be some clever trick I wasnt aware of!

G7MRV: Ah, well thats how i'd been looking at it - a shed load of IFs

oh well, if thats the way so be it, had hoped there would be some clever trick I wasnt aware of!

You could do it the way dlloyd suggested. I had thought of that but for some reason I can't now remember thought it might not fit your requirements.

You don't need a shedload of if statements if you know how to use an array. You only need to work that code out once. Test for roll past 9 and test for roll past 0. Those would be the only two tests involved.

Now that dlloyd has pointed out that you can just increment and decrement a single integer, I'll suggest an alternative UI.

You could program an accelerating inc/dec step and just use two buttons. If you get the acceleration right this could be faster as well as more intuitive and fewer buttons.

jimmer: Now that dlloyd has pointed out that you can just increment and decrement a single integer, I'll suggest an alternative UI.

You could program an accelerating inc/dec step and just use two buttons. If you get the acceleration right this could be faster as well as more intuitive and fewer buttons.

No that wouldnt work for the final system, which is part of a communications transceiver. The number is the operating frequency of the radio. The up/down buttons will be replaced by a rotary encoder , but its necessary to be able to select which part of the frequency to adjust

Ive used radios with just an encoder and variable tuning speeds and its extremely tedious

Having a few ifs to read 4 buttons and increment 4 variables isn't all that tedious.

if (digitalRead(onesButton) == LOW){
updateNeeded = 1;
ones = ones +1;
if (ones == 10){
   ones = 0;
   tens = tens +1;
   if (tens == 10){
   tens = 0;
   hundreds = hundreds +1;
   if (hundreds == 10){
      hundreds = 0;
      thousands = thousands +1;
      if (thousands == 10){
        thousands = 0;
      }
     }
    }
   }
 }
if (digitalRead(tensButton) == LOW){
updateNeeded = 1;
tens = tens +1;
   if (tens == 10){
   tens = 0;
   hundreds = hundreds +1;
   if (hundreds == 10){
      hundreds = 0;
      thousands = thousands +1;
      if (thousands == 10){
        thousands = 0;
      }
     }
    }
   }
if (digitalRead(hundredsButton) == LOW){
updateNeeded = 1;
hundreds = hundreds +1;
   if (hundreds == 10){
      hundreds = 0;
      thousands = thousands +1;
      if (thousands == 10){
        thousands = 0;
      }
     }
    }
if (digitalRead(thousandsButton) == LOW){
updateNeeded = 1;
      thousands = thousands +1;
      if (thousands == 10){
        thousands = 0;
      }
     }
// and add some debouncing if needed
    
if (updateNeeded == 1){
updateNeeded = 0;
// send data to the display
}