Programming help newb counter

Hi, Im working on a count down counter. can someone help me fix this code, I got it partially working, but I need it to work when the button is press and held. Thanks

#include <LiquidCrystal.h>

LiquidCrystal lcd(12,11,6,5,4,3);
// this constant won't change:
const int  buttonPin = 2;    // the pin that the pushbutton is attached to
const int ledPin = 13;       // the pin that the LED is attached to

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

void setup() {
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  // initialize the LED as an output:
  pinMode(ledPin, OUTPUT);
  // initialize serial communication:
  Serial.begin(9600);
}


void loop() {
  // 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 went 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 went from on to off:
      Serial.println("off");
    }
    // Delay a little bit to avoid bouncing
  //  delay(50);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;


  // turns on the LED every four button pushes by checking the modulo of the
  // button push counter. the modulo function gives you the remainder of the
  // division of two numbers:
  if (buttonPushCounter % 4 == 0) {
    digitalWrite(ledPin, HIGH);
  } else {
    digitalWrite(ledPin, LOW);
  }

  
  
  
  if (buttonPushCounter ==-1){
    lcd.setCursor(0,1);
    lcd.print("29 LEFT");
  }
  
   if (buttonPushCounter ==-2){
    lcd.setCursor(0,1);
    lcd.print("28 LEFT");
  }
  
  if (buttonPushCounter ==-3){
    lcd.setCursor(0,1);
    lcd.print("27 LEFT");
  }
  
    if (buttonPushCounter ==-4){
    lcd.setCursor(0,1);
    lcd.print("26");
  }
  
    if (buttonPushCounter ==-5){
    lcd.setCursor(0,1);
    lcd.print("25");
  }
  
  if (buttonPushCounter ==-6){
    lcd.setCursor(0,1);
    lcd.print("24");
  }
  
  if (buttonPushCounter ==-7){
    lcd.setCursor(0,1);
    lcd.print("23");
  }
  
  if (buttonPushCounter ==-8){
    lcd.setCursor(0,1);
    lcd.print("22");
  }
  
  if (buttonPushCounter ==-9){
    lcd.setCursor(0,1);
    lcd.print("21");
  }
  
  if (buttonPushCounter ==-10){
    lcd.setCursor(0,1);
    lcd.print("20");
  }
  
  if (buttonPushCounter ==-11){
    lcd.setCursor(0,1);
    lcd.print("19");
  }
  
  if (buttonPushCounter ==-12){
    lcd.setCursor(0,1);
    lcd.print("18");
  }
  
  if (buttonPushCounter ==-13){
    lcd.setCursor(0,1);
    lcd.print("17");
  }
  
  
  if (buttonPushCounter ==-14){
    lcd.setCursor(0,1);
    lcd.print("16");
  }
  
  if (buttonPushCounter ==-15){
    lcd.setCursor(0,1);
    lcd.print("15");
  }
  
  if (buttonPushCounter ==-16){
    lcd.setCursor(0,1);
    lcd.print("14");
  }
  
  if (buttonPushCounter ==-17){
    lcd.setCursor(0,1);
    lcd.print("13");
  }
  if (buttonPushCounter ==-18){
    lcd.setCursor(0,1);
    lcd.print("12");
  }
  
  
  if (buttonPushCounter ==-19){
    lcd.setCursor(0,1);
    lcd.print("11");
  }
  
  if (buttonPushCounter ==-20){
    lcd.setCursor(0,1);
    lcd.print("10");
  }
  
  if (buttonPushCounter ==-21){
    lcd.setCursor(0,1);
    lcd.print("09");
  }
  
  if (buttonPushCounter ==-22){
    lcd.setCursor(0,1);
    lcd.print("08");
  }
  if (buttonPushCounter ==-23){
    lcd.setCursor(0,1);
    lcd.print("07");
  }
    if (buttonPushCounter ==-24){
    lcd.setCursor(0,1);
    lcd.print("06");
  }
    if (buttonPushCounter ==-25){
    lcd.setCursor(0,1);
    lcd.print("05");   
  }
    if (buttonPushCounter ==-26){
    lcd.setCursor(0,1);
    lcd.print("04");
  }
  if (buttonPushCounter ==-27){
    lcd.setCursor(0,1);
    lcd.print("03");
  }
  if (buttonPushCounter ==-28){
    lcd.setCursor(0,1);
    lcd.print("02");
  }
  if (buttonPushCounter ==-29){
    lcd.setCursor(0,1);
    lcd.print("01");
  }
  if (buttonPushCounter ==-30){
    lcd.setCursor(0,1);
    lcd.print("RELOAD AMMO");
  }
}

need it to work when the button is press and held.

How fast do you want the counter to decrement ?

  if (buttonPushCounter ==-1){
    lcd.setCursor(0,1);
    lcd.print("29 LEFT");
  }
  
   if (buttonPushCounter ==-2){
    lcd.setCursor(0,1);
    lcd.print("28 LEFT");
  }

If you look carefully you will see that there is a fixed relationship between the value of buttonPushCounter and the number you print. I hope that you realise that you can print numbers, not just text, on the LCD.

thanks for the reply UKHeliBob

So when the button is held, counts down 50 per second.. I wanted to change the code from 10,000 to 0 decremented by 50 per second of the push button being held.

I wanted to change the code from 10,000 to 0 decremented by 50 per second of the push button being held.

Then, the state change detection example is not a good starting point. You are NOT concerned about doing something only when the switch BECOMES pressed or BECOMES released. You want to do something when the switch IS pressed. So, write the appropriate code.

You will need to know when the switch BECOMES pressed, so you know when the one second mark passes, when the two second mark passes, etc.

Not all of your code will be in the block where you detect that the switch has become pressed.

You are NOT interested in the number of times the switch becomes pressed, so quit counting them.

This is what i got so far.. Do I control the rate of decrement by dividing it by 50 and putting a new int value on the declaration?

#include <LiquidCrystal.h>

LiquidCrystal lcd(12,11,6,5,4,3);
// this constant won't change:
const int  buttonPin = 2;    // the pin that the pushbutton is attached to

// the pin that the LED is attached to

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button



void setup() {
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  // initialize the LED as an output:

  
  // initialize serial communication:
  Serial.begin(9600);
}


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

  // compare the buttonState to its previous state
  
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button went from off to on:
      buttonPushCounter  ++;
      
      Serial.println(10000 - buttonPushCounter);
     
    
    // Delay a little bit to avoid bouncing
  //  delay(50);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;

}

Do I control the rate of decrement by dividing it by 50 and putting a new int value on the declaration?

"it" is a pronoun with no referent. I have no idea what you think you need to divide by 50, or why you want to change the rate of decrement.

You measure how long the switch has been pressed. If it is greater than 1 second, subtract 50 from some value and reset the switch pressed time to now.

How do you decrement by specific value.. Im trying to decrement it by 50 for every 1 second... I got the counter to count down by 1 second and now I only need to subtract it by 50 to get the value I need when button is pressed.

#include <LiquidCrystal.h>

LiquidCrystal lcd(12,11,6,5,4,3);
// this constant won't change:
const int  buttonPin = 2;    // the pin that the pushbutton is attached to

// the pin that the LED is attached to

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button
int value =0;  //Set value for subracted buttonstate



void setup() {
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  // initialize the LED as an output:

  
  // initialize serial communication:
  Serial.begin(9600);
}


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

  // compare the buttonState to its previous state
  
    if (buttonState == HIGH) {
      buttonPushCounter  ++;
      value=10000 - buttonPushCounter;
      delay(1000);
      Serial.println(value);
      
      
      lcd.setCursor(7,1);
      lcd.print(value);
      if (value<1){
     lcd.setCursor(0,1);   
     lcd.print("RELOAD");
        delay (100);
        exit(0);
       
      }
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;
 

}

I'm not exactly sure what you're talking about but why not try changing:
value=10000 - buttonPushCounter;
to
value=10000 - (buttonPushCounter * 50) ;

Steve

thanks.. I was making it harder than it suppose to.. many thanks

Have you tried using timers?
You can make a timer that generates an interrupt each second. In the interrupthandler you can decrement by 50.
You can make a timer that counts at a certain rate, while the butten is pressed. That way you can count "exact" the time that passed since the button was pressed. If it's longer than it's overflow value you'll need a temp variable to count the overflows.

  • no ugly delay()'s

is there a way to return to initial 10000 making the program start over again after a specific button is pressed? Simulating a weapon system being reloaded and ready to fire again.

Or a timer will be best for this application?

jayded70:
is there a way to return to initial 10000 making the program start over again after a specific button is pressed? Simulating a weapon system being reloaded and ready to fire again.

Or a timer will be best for this application?

if (the reset button is pressed)
{
  set the counter variable to 10000
}

or timers
you'll have to implement the setup, enable and disable of the timer.

#include <Arduino.h>

const uint8_t btn_pin = 2;
volatile uint8_t btn_flag;
volatile uint16_t btn_cntr;
const uint16_t btn_max = 10000;
const uint8_t btn_decr = 50;

void setup() {
	
	Serial.begin(9600);

	DDRB = 0;			//set port b as input
	setup_T0();

	btn_flg = 0;
	flag_btn = 0;
       btn_cntr = btn_max;

}

void loop() {
	
	// wait till pin goes high
	while (!PINB2) {}

	enable_T0()

	// wait till pin goes low
	while (PINB2) {

		if (btn_flag) {

			btn_flag = 0;
			display(btn_cntr)

		}
		
		if (btn_cntr > btn_max) {

			// btn_cntr has gone from 10000 to smaller than 0
		}

	}

	disable_T0();

}

// interrupt handler of T0, change x
ISR(TIMER0_COMPx_vect) {
	
	btn_cntr -= btn_decr;
	btn_flag = 1;

}

And according to attachInterrupt() - Arduino Reference you can attach an interrupt handler to 2 pins (i assume you use an UNO). Than you can omit the 2 while loops and just check for flag in the main loop.
You could even use the 2 compare registers of the timer and change bit of code, so everything happens in the handlers and the main loop keeps updating the display

@UKHeliBob

Tried what you said, no luck... Please advice thanks..

#include <LiquidCrystal.h>

LiquidCrystal lcd(12,11,6,5,4,7
                 );
// this constant won't change:
const int  buttonPin = 2;    // the pin that the pushbutton is attached to
const int buttonPin2=3; // Set Reset Button
// the pin that the LED is attached to

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonPushCounter2=0;
int buttonState = 0; // current state of the button
int buttonState2 = 0;

int lastButtonState = 0;     // previous state of the button
int value =0;  //Set value for subracted buttonstate
int val=0;


void setup() {
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  // initialize the LED as an output:
pinMode(buttonPin2, INPUT);
  
  // initialize serial communication:
  Serial.begin(9600);
}


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

  // compare the buttonState to its previous state
  
    if (buttonState == HIGH) {
      buttonPushCounter  ++;
      value=10000 -(buttonPushCounter*25);// Adjusted rate of fire decrement to 50rounds/s
      delay(500);
      Serial.println(value);
        lcd.setCursor(7,1);
      lcd.print(value);
      if (value<100){
        lcd.clear();
         lcd.setCursor(0,1);   
        lcd.print("RELOAD");}
      
      
    
      if(buttonState2=HIGH){
        value=10000;}
     
  
      
      
           
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;
      
    }

Actually maybe making an external reset switch for the arduino will also do the job.

Tried what you said, no luck

Luck plays no part in programming. Skill is FAR more important.

One necessary skill is being able to describe what that code actually does, and how that differs from what you want. You need to work on acquiring that skill.

jayded70:
@UKHeliBob

Tried what you said, no luck... Please advice thanks..

    if (buttonState2 = HIGH)

BONG !