Help increment/deincrement push buttons?

Hello all, I've managed to cobble together from examples I found online a sketch to manipulate two values with four buttons and print their status to LCD. Now I need to limit the range of the values to between 0 and 127. Basically two pairs of up/down counters, where two button take the values up and two buttons take the values down, one pair per value. At the moment I'm having trouble once I go below 1. the up button then starts from double digits e.g. 11 or 21. And for the large project the delays aren't usable so i'm thinking "else".conditions may be needed. The "StatechangeDection" Example is starting to look like a better option.
Here's the code as it is now: (pardon the lack of excerpt -newbie. Will trim in the future)
Any suggestions ?
Thank you in advance.

#include <LiquidCrystal.h>

LiquidCrystal lcd(7,8,9,10,11,12);
const int  buttonPin = 5;    // the pin that the Up pushbutton is attached to
const int  buttonPin1 = 6;    // the pin that the Down pushbutton is attached to
const int  buttonPin2 = 3;    // the pin that the Up pushbutton is attached to
const int  buttonPin3 = 4;    // the pin that the Down pushbutton is attached to

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int button2PushCounter = 0;   // counter for the number of button presses
int buttonState3 = 0;         // current state of the button
int buttonState4 = 0;         // current state of the button
int buttonState5 = 0;         // current state of the button
int buttonState6 = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button
int lastButton2State = 0;     // previous state of the button

void setup() {
// initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  pinMode(buttonPin1, INPUT);
  pinMode(buttonPin2, INPUT);
  pinMode(buttonPin3, INPUT); 

  lcd.begin(16,2);
  lcd.setCursor(0,0);
  lcd.print("PadCutOff:");
  lcd.setCursor(0,1);
  lcd.print("MaxPlTime:");   
}

void loop() {
  // read the pushbutton up input pin:
  buttonState3 = digitalRead(buttonPin3);
  // compare the buttonState to its previous state
  if (buttonState3 != lastButton2State) {
    // if the state has changed, increment the counter
    if (buttonState3 == HIGH)
    {
      button2PushCounter++;
      lcd.setCursor(10,1);
      lcd.print(button2PushCounter);
    }
    delay(50);
  }
  // save the current state as the last state,
  //for next time through the loop   
  lastButton2State = buttonState3;
  // read the pushbutton down input pin:
  buttonState4 = digitalRead(buttonPin2);
  // compare the buttonState to its previous state
  if (buttonState4 != lastButton2State) {
    // if the state has changed, decrement the counter
    if (buttonState4 == HIGH)
    {
      --button2PushCounter;
      lcd.setCursor(10,1);
      lcd.print(button2PushCounter);
    }
    delay(50); 
  }
  // save the current state as the last state,
  //for next time through the loop 
  lastButton2State = buttonState4; 
  // read the pushbutton up input pin:
  buttonState5 = digitalRead(buttonPin);
  // compare the buttonState to its previous state
  if (buttonState5 != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState5 == HIGH)
    {
      buttonPushCounter++;
      lcd.setCursor(10,0);
      lcd.print(buttonPushCounter);
    }
    delay(50);
  }
  // save the current state as the last state,
  //for next time through the loop
  lastButtonState = buttonState5;
  // read the pushbutton down input pin:
  buttonState6 = digitalRead(buttonPin1);
  // compare the buttonState to its previous state
  if (buttonState6 != lastButtonState) {
    // if the state has changed, decrement the counter
    if (buttonState6 == HIGH)
    {
      --buttonPushCounter;
      lcd.setCursor(10,0);
      lcd.print(buttonPushCounter);
    }
    delay(50); 
    // save the current state as the last state,
    //for next time through the loop 
    lastButtonState = buttonState6; 
    //
    //
    if (buttonPushCounter < 126)
    {
      lcd.setCursor(13,0);
      lcd.print("   ");
    }
    if (buttonPushCounter <= 0)
    {
      lcd.setCursor(13,0);
      lcd.print("OFF");
      buttonPushCounter=0;
    }
    if (buttonPushCounter >= 126)
    {
      lcd.setCursor(13,0);
      lcd.print("Max");
      buttonPushCounter=126;
    }
    if (buttonPushCounter <= 0)
    {
      lcd.setCursor(10,0);
      lcd.print("   ");
      buttonPushCounter=0;
    }
    if (buttonPushCounter <= 100)
    {
      lcd.setCursor(10,0);
      lcd.print("   ");
      lcd.setCursor(10,0);
      lcd.print(buttonPushCounter);
    }
  }
  if (button2PushCounter < 126)
  {
    lcd.setCursor(13,1);
    lcd.print("   ");
  }
  if (button2PushCounter <= 0)
  {
    lcd.setCursor(13,1);
    lcd.print("OFF");
    button2PushCounter=0;
  }
  if (button2PushCounter >= 126)
  {
    lcd.setCursor(13,1);
    lcd.print("Max");
    button2PushCounter=126;
  }
  if (button2PushCounter <= 0)
  {
    lcd.setCursor(10,1);
    lcd.print("   ");
    button2PushCounter=0;
  }
  if (button2PushCounter <= 100)
  {
    lcd.setCursor(10,1);
    lcd.print("   ");
    lcd.setCursor(10,1);
    lcd.print(button2PushCounter);
  }
}
   buttonState4 = digitalRead(buttonPin2);
// compare the buttonState to its previous state
   if (buttonState4 != lastButton2State) {

Which button is is? 2 or 4?

buttonState3 goes up buttonState4 goes down using "button2state", buttonState5 goes up buttonState6 goes down using "buttonstate"
I used this post as a guide. http://forum.arduino.cc/index.php/topic,129170.0.html

Pitchoilcan:
buttonState3 goes up buttonState4 goes down using "button2state", buttonState5 goes up buttonState6 goes down using "buttonstate"
I used this post as a guide. http://forum.arduino.cc/index.php/topic,129170.0.html

How can you store the last button state for two different buttons in one variable?

I suspect that as you go from 3-digit to 2-digit to 1-digit numbers you are not clearing the unused parts of the field. Change:

      lcd.setCursor(10,0);
      lcd.print(buttonPushCounter);

to:

      lcd.setCursor(10,0);
      lcd.print("   ");  // Clear a three character field
      lcd.setCursor(10,0);
      lcd.print(buttonPushCounter);

lcd.print(" "); // Clear a three character field

cool, makes sense. I'll try that.
as for

How can you store the last button state for two different buttons in one variable?

I thought it was a sort of balancing act the between ++/--'s.

I was able to get to MAX 127, cleared the unused characters with

lcd.print(" ");

but comming up from -1 causes a problem. Also when coming down from 127 I get up to 999 after 100 coming down. So clearly this isn't the best way of doing this. Like I said before the larger project for which this intended has no delay (is a musical instrument) and the timer prescaler isn't the default ,in order to maximize the analog reads. So "delay's" are no good. Can I poll the button pins, put the values 0-127 in an array and do the increment/deincrement that way and what might that code look like?
something more like

 int countVal = 0;
  currentUpState = digitalRead(2); // read the Up pushbutton input pin
  if (currentUpState != lastUpButtonState) {
    countVal = 1;
    lastUpButtonState = currentUpState;
  }
  currentDownState = digitalRead(3); // read the Down pushbutton input pin
  if (currentDownState != lastDownButtonState) {
    countVal = -1;
    lastDownButtonState = currentDownState;
  }
  if (countVal) {
    count += countVal;
    count = constrain(count,0,5);
  for (int i = 4; i < 9; i++) {
      digitalWrite(i, i < count ? HIGH : LOW);
      analogWrite(9, aVals[i-4]);
}

I have tested this code but found it while researching it topic .
Source:

Up Down Counter

. Up Down Counter. - Programming Questions - Arduino Forum

If you need to stay within some boundaries, you should program those.
After debouncing a key press, you should do what that key press is meant to do.
Immediately after that you should check to see that took you beyond your boundaries.
So something like this:

     if (buttonState5 == HIGH)
     {
      buttonPushCounter++;
      if (buttonPushCounter > 127) {        // This is new
        buttonPushCounter = 127;            // So is this
      }
      lcd.setCursor(10,0);
      lcd.print(buttonPushCounter);
     }

When printing, you should erase all characters you have printed last.
So if you go down from 100 (3 characters wide) and you print 99 without erasing the old content first, you'll end up with a 990 displayed (so not 999).
To get rid of that, you should print 3 spaces, which was what johnwasser told.
There isn't much more to it.

2 AM, bedtime is long due.
Maybe i'll have some other thoughts after some sleep.

How then do I prevent going from 0 to -1 when hitting the down bottom from the start. At run the counter starts at 1 if i hit the down button once or twice I'm at - 1 and that where it stops. Going up from there still double digits. :frowning: I'm able to get up to 127 MAX from 1 and down no problem.

By setting it back to zero in case you go below zero.
There's no difference here, except for the direction you're going.

The double digits will always end with "1" and last until you get to 10.
Do you always print 3 spaces before printing a new value ?

When I try

lcd.print(" "); // Clear a three character field

before printing a new value it messes up where the value is printed, and the value only flashes momentarily at column 14 (not 10), then the field is blank. I'm thinking it's best not to go below zero. Please note the code in the original post reflects the current state of the sketch, all modifications added. Every thing works nicely once I don't go below zero (the off position), oh and I haven'r really solved the problem of counting down from 127 though i understand why it goes to 990. But putting if<100, if<10 seems like a lot coding maybe too much.

Your sketch is printing a value (that is never erased), and a text directly next to it if the minimum or maximum is reached.
That text will be erased if the value isn't min or max.

So the value is printed to position 10, and a text or 3 spaces to position 13.
This would result in something like this (each line is a different situation, put in code tags to not mess up alignment):

0  OFF
1      
12    
126MAX

Is that really what you meant to do ?
And this way you aren't cleaning up the numbers you're printing.
So counting down does not display what you would expect.
You would go from 100 to 990, and 89 steps later from 100 to 900.

If you like to show correct numbers, you should erase those too before you write a new number.
And if you want to line the number up correctly (instead of always lined up to the left), you should check if you're over 9 and if you're over 99 and add a space or two accordingly (or move the cursor x extra positions).

So the value is printed to position 10, and a text or 3 spaces to position 13.
This would result in something like this (each line is a different situation, put in code tags to not mess up alignment):

padCutOff:0  OFF //Row 0

padCutOff:1      
padCutOff:12    
padCutOff:127MAX //Row 0

MaxPlTime:0  OFF //Row 1
MaxPlTime:1      
MaxPlTime:12    
MaxPlTime:127MAX //Row 1

This is what i'm trying to do.
Pondering.............

    if (buttonPushCounter >= 126)
    {
      lcd.setCursor(13,0);
      lcd.print("Max");
      buttonPushCounter=126;
    }

That first line checks to see if you are at 126 or larger.
The second last line will add "Max" if you are at 126 or larger.
The last line then resets it to 126.
So you'll never see 127.

"PadCutOff:" is 10 positions, but counting starts at 0 and you'll be done printing that text at position 9.
So actually there should be a space or rather undefined character (meaning whatever is already at that position):

PadCutOff: 127MAX

It seems you didn't keep that in mind, and are writing to the 17th position of your 16 position LCD because you are planning on using exactly 16 characters.

So you'll never see 127.

but I do.
At the moment it prints

PadCutOff:127MAX

which is what I want.
adding

 if (button2PushCounter <= 0)
  {
    lcd.setCursor(10,1);
    lcd.print("   ");
    button2PushCounter=0;
  }

and

if (buttonPushCounter <= 0)
    {
      lcd.setCursor(10,0);
      lcd.print("   ");
      buttonPushCounter=0;
    }

helps with returning up from zero.

Now pondering: how to fix if<100 from to 990......

Indeed you do see that 127.
And that is because you are printing the value immediately after increasing or decreasing that value (lines 46 and 64).
Much later you're doing some more processing, which was what i was mentioning.
Perhaps you should reshuffle your code a bit so things are easier to oversee (meaning: put the prints next to each other and do the processing before you print, not halfway the printing).

how to fix if<100 from to 990

It's the same difference.
Erase (print spaces and return to the start position) immediately before you print a new value.

Ok this is what I have now. it's work more or less OK. But I'm sure I'll have to redo it do remove the delays and have a continuous read. but for now it works
added

if (button2PushCounter <= 100)
  {
    lcd.setCursor(10,1);
    lcd.print("   ");
    lcd.setCursor(10,1);
    lcd.print(button2PushCounter);
  }

and

 if (buttonPushCounter <= 100)
  {
    lcd.setCursor(10,0);
    lcd.print("   ");
    lcd.setCursor(10,0);
    lcd.print(buttonPushCounter);
  }

Thanks much people. :slight_smile:

i dunno...

you use polling method to read the button, and
you put delay() in your loop(), and
you're saying it runs too slow.

interesting......

pondering.......

  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button
      // wend from off to on:
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes:  ");
      Serial.println(buttonPushCounter);
    } 
    else {
      // if the current state is LOW then the button
      // wend from on to off:
      Serial.println("off"); 
    }
  }
  // save the current state as the last state, 
  //for next time through the loop
  lastButtonState = buttonState;

You now solved the transition from =>100 to <100.
But you are checking to see if you are going below 100.
If you go < 10, you are also < 100 and that is why that works in that case too.
There is no need at all to do that check to see you've gone < 100.
Any time you are going to write to your LCD, you can first erase the old content of that part.

About those delays: ask yourself why those are there.
What's the purpose of the delay in line 49, 66, 79, 98 ?
I can guess why they were there in the example you got them from (debouncing), but that seems to be gone now.
If you're not sure you can dump those lines, you can simply //comment them out and see what happens.

By the way: debounce is a good thing, and you should study that a bit.
It will prevent accidental multiple increments/decrements upon a single keypress.
You could count a number of unchanged buttonStates (if it would change, the count needs to be reset) to reach this.
That will speed up your code, as the delays will be gone.

This comment isn't exactly what you are doing:
// if the state has changed, increment the counter
You only want to increment if the state goes or is HIGH, and that is actually what you are doing.
You don't also want to increment if it goes back to LOW.

Perhaps you should reshuffle your code a bit so things are easier to oversee (meaning: put the prints next to each other and do the processing before you print, not halfway the printing).

Check :%