Simple loop not working as expected

I have taken a program for an LCD that prints Hello world and displays seconds increasing from boot.

I have modified this to try to make a timer that controls a solenoid while a circuit is closed and for 'x' seconds after the circuit is opened

I am trying to make a countdown timer that will start from a preset value. I modified the loop to start at 9 and decrease by one and display on the LCD. I also added a Serial.Println to see what was happening and I added a LED to come on at the end.

IT is not doing what I expected (my expectations may be wrong). I wanted it to stop after one loop and the LED to stay on.

The loop continues, countdown starts at 9 and goes to 1 and then starts again. When I had the LED to turn on with the IF statement if i was less than one it would not come on, changed to i<2 and it does light up until loop restarts and i is >2, I understand this.

So why does countdown not go to 0 and why does it keep starting over.
Also when watching the serial console, the LED seems to light when 9 is output and not when 1 is output, I am assuming this is a timing issue.

Thank you for any help!

/*
  LiquidCrystal Library - Hello World

 Demonstrates the use a 16x2 LCD display.  The LiquidCrystal
 library works with all LCD displays that are compatible with the
 Hitachi HD44780 driver. There are many of them out there, and you
 can usually tell them by the 16-pin interface.

 This sketch prints "Hello World!" to the LCD
 and shows the time.

  The circuit:
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * LCD R/W pin to ground
 * LCD VSS pin to ground
 * LCD VCC pin to 5V
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)

 Library originally added 18 Apr 2008
 by David A. Mellis
 library modified 5 Jul 2009
 by Limor Fried (http://www.ladyada.net)
 example added 9 Jul 2009
 by Tom Igoe
 modified 22 Nov 2010
 by Tom Igoe

 This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/LiquidCrystal
 */

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  
// LED output -- added by me
  pinMode(8, OUTPUT);
  
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("Post Flow Time:");
}

void loop() {
  Serial.begin(9600);
 
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);

  // countdown and output to serial:
  for (int i=9; i>=1; i--) {
    lcd.setCursor(0, 1);
    lcd.print(i);
 // Print to console for info
    Serial.print("i is :");
    Serial.println(i);

    delay(1000);

    // read timer and light LED of time is less that 1
    if (i<2) {
      digitalWrite(8, HIGH);
    } else {
      digitalWrite(8, LOW);
    }
  }
  
}

So why does countdown not go to 0 and why does it keep starting over.

because
A) you didn't ask it to
B) because the loop function loops.

And don't keep reinitialising the serial interface; that's silly - put it in setup.

++Karma; // For posting your code correctly on your first post.

  for (int i=9; i>=1; i--) {

What number do you think this stops at?

TheMemberFormerlyKnownAsAWOL:
because
A) you didn't ask it to
B) because the loop function loops.

And don't keep reinitialising the serial interface; that's silly - put it in setup.

Ok I fixed the serial initialize, and I guess you have realized that I am not a programmer, just a hack.

I know what sequence I need things to happen in and how to mostly wire the circuit, it the programs I struggle with. This diagram is the circuit I am working towards.

PerryBebbington:
++Karma; // For posting your code correctly on your first post.

  for (int i=9; i>=1; i--) {

What number do you think this stops at?

Well I do read the stickied posts!!

Now I see the reason it was stopping at 1 and not zero.
How do I get it to stop after one loop and wait for the trigger or button press that I have added to this version?

/*
  LiquidCrystal Library - Hello World

 Demonstrates the use a 16x2 LCD display.  The LiquidCrystal
 library works with all LCD displays that are compatible with the
 Hitachi HD44780 driver. There are many of them out there, and you
 can usually tell them by the 16-pin interface.

 This sketch prints "Hello World!" to the LCD
 and shows the time.

  The circuit:
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * LCD R/W pin to ground
 * LCD VSS pin to ground
 * LCD VCC pin to 5V
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)

 Library originally added 18 Apr 2008
 by David A. Mellis
 library modified 5 Jul 2009
 by Limor Fried (http://www.ladyada.net)
 example added 9 Jul 2009
 by Tom Igoe
 modified 22 Nov 2010
 by Tom Igoe

 This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/LiquidCrystal
 */

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  // LED output
  pinMode(8, OUTPUT);
  Serial.begin(9600);
  
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("Post Flow Time:");

  //wait for button press to start
  const byte buttonPin = 7;
    pinMode(buttonPin, INPUT_PULLUP);
    while (digitalRead(buttonPin) == HIGH)
  {}
}

void loop() {
  
 
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  // countdown and output to serial:
  for (int i=9; i>=0; i--) {
    lcd.setCursor(0, 1);
    lcd.print(i);
    Serial.print("i is :");
    Serial.println(i);
    delay(1000);
    // read timer and light LED of time is less that 1
    if (i<2) {
      digitalWrite(8, HIGH);
    } else {
      digitalWrite(8, LOW);
    }
  }
  
}

You already have

 //wait for button press to start
  const byte buttonPin = 7;
    pinMode(buttonPin, INPUT_PULLUP);
    while (digitalRead(buttonPin) == HIGH)
  {}

move

 const byte buttonPin = 7;

to before setup() where it belongs, move

    pinMode(buttonPin, INPUT_PULLUP);

to setup()

and move

 //wait for button press to start
    while (digitalRead(buttonPin) == HIGH)
  {}

to the beginning or end of loop().

Thank you all for the kind direction pointing!

I have most of what I am trying to do working, but I will make another post if I have more questions.

Again Thank you for the help.

odnt-42:
Well I do read the stickied posts!!

Now if you could just find a way to make all the other new folk do the same you'd please an awful lot of us!

OK, So I do appreciate the assistance yesterday on my little project.

I have added and fixed a few things and now it is close to what I need it to do, but I think it is probably not the cleanest way of doing it. (Specifically the while statements waiting for button press.)

Now it waits for a button press and LED turns on, and if button stays depressed then LED stays on until button is released and then timer starts for 5 sec and led turns off.

This is what I want it to do, but, I would like to check if button is released BUT pressed again before timer expires, then reset timer and stay on until button is released again.

Also the countdown default is set to 5 sec, but how would I add the ability to have a second switch that allows the selection of 4 values (5s, 7s, 10s, 14s) while waiting for a button press?

Thank you

/*
  Post Flow Gas timer curcuit
  
  This is to add a post flow timeer functionality to a 
  stick welding power source that does not have gas flow control built in.
  
  This is to be triggered from an external source such as the pedal controls of the welder
  In this design the trigger is the 24VAC power that comes from the front panel plug for the foot pedal.
  When the pedal is depressed the contact closure toggles the electrode 'HOT' and 24VAC goes high.
  When the circuit senses the 24VAC it will open the soleniod allowing gas to flow.
  The 24VAC stays high as long as the pedal is depressed and goes 'LOW' when the pedal is released and power to the electrode is removed.
  When the 24VAC goes 'LOW' the circuit timer will start and will keep the solenoid open for a preset number of seconds (Post Flow).
  After the preset time the solenoid will close and the circuit will reset for the next cycle / pedal press.

  Other conditions, if pedal is released timer should start, unless the pedal is pressed again before timer runs out then timer shoud reset to
  preset time and continue to wait for pedal release.
  
 

  The circuit:
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * LCD R/W pin to ground
 * LCD VSS pin to ground
 * LCD VCC pin to 5V
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)

*/

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

// Set pin 7 to 'buttonPin' this will be trigger from optocupler
const byte buttonPin = 7;

  // set timer variable
  int sec = 5;


void setup() {
  
  // LED output
  pinMode(8, OUTPUT);
  // set serial speed
  Serial.begin(9600);
  // set buttonPin 
  pinMode(buttonPin, INPUT_PULLUP);

  //set LED on until timer stops
  //digitalWrite(8, HIGH);
  
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  
  // Print a message to the LCD.
  lcd.print("Post Flow Sec");

  // Print timer setting to LCD
  lcd.setCursor(15,0);
  lcd.print(sec);
  
}

void loop() {

//wait for button press to start
      while (digitalRead(buttonPin) == HIGH)
  {}
      while (digitalRead(buttonPin) == LOW)
  {
        digitalWrite(8, HIGH);
}
   
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  // countdown and output to serial:
  for (int i=sec; i>=0; i--) {
    lcd.setCursor(0, 1);
    lcd.print(i);
  // Print countdown to console for information
    Serial.print("i is :");
    Serial.println(i);
  // set timer step approx 1 sec  
    delay(1000);
    
  // read timer and light LED of time is less that 1
    if (i<1) {
      digitalWrite(8, LOW);
    } else {
      digitalWrite(8, HIGH);
    }

  }
}

The questions you ask are asked every day on this forum. You should be doing a little more research on your own before asking for more help. Look for the forum sticky posts describing "doing more than one thing at the same time" or words to that effect. Also take a look at the "state change" example sketch and figure out how that can help you.

@odnt-42, please do not cross-post. Threads merged.

Sorry, I guess I don't understand. I do not think this was a cross-post as it was a different question from the first one that was solved and about a piece I don't understand.

PaulRB:
The questions you ask are asked every day on this forum. You should be doing a little more research on your own before asking for more help. Look for the forum sticky posts describing "doing more than one thing at the same time" or words to that effect. Also take a look at the "state change" example sketch and figure out how that can help you.

The issue is not if it has been posted before or not, my problem is that I am not a programmer and I will freely admit that. I ask questions because I do not know what methods would work or not. I understand the logic of what I want to do, I just don't know the programming piece. I teach people every day, and when new people get hired that have absolutely no construction knowledge, I have to teach basics and start to point them in the right direction otherwise they are totally lost, not knowing what they don't know.

The basics are all explained in the tutorials and also the included sketches on arduino. It doesn’t really matter what is is you want to switch off or on, an led, a bit of code etc the same basic approach is required. It is generally expected that you do a bit of your own research so, for example, you might say ‘I have read the tutorial on x and don’t understand y can you explain’ is better than can you tell me how to do x and y.
Look at the button tutorials which will lead you on a journey through debouncing, state machines, millis etc

State change added to while loop waiting for button press.

On loading the program to uno or on reset with the reset button, the preset timer value 'sec=5', is incremented by 1. So after the timer starts out a 6 and not 5.

If buttonPin2 is pressed value of 'sec' is incremented by one each time.
When buttonPin1 is pressed and timer counts down to zero and resets to the value it started at( if started at 7, it returns to 7) and does not increment.

The added 1 to the timer value 'sec' only happens once at boot/reset.

I do not see where it is being incremented other than when buttonPin2 is pressed.

/*
  Post Flow Gas timer curcuit
  
  This is to add a post flow timeer functionality to a 
  stick welding power source that does not have gas flow control built in.
  
  This is to be triggered from an external source such as the pedal controls of the welder
  In this design the trigger is the 24VAC power that comes from the front panel plug for the foot pedal.
  When the pedal is depressed the contact closure toggles the electrode 'HOT' and 24VAC goes high.
  When the circuit senses the 24VAC it will open the soleniod allowing gas to flow.
  The 24VAC stays high as long as the pedal is depressed and goes 'LOW' when the pedal is released and power to the electrode is removed.
  When the 24VAC goes 'LOW' the circuit timer will start and will keep the solenoid open for a preset number of seconds (Post Flow).
  After the preset time the solenoid will close and the circuit will reset for the next cycle / pedal press.

  Other conditions, if pedal is released timer should start, unless the pedal is pressed again before timer runs out then timer shoud reset to
  preset time and continue to wait for pedal release.
  
 

  The circuit:
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * LCD R/W pin to ground
 * LCD VSS pin to ground
 * LCD VCC pin to 5V
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)
 * buttonPin1 (pin 7) - starts timer - will be replaced with optocoupler
 * buttonPin2 (pin 9) - increments timer

*/

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

// Set pin 7 to 'buttonPin' this will be trigger from optocupler
const byte buttonPin1 = 7;
const int buttonPin2 = 9;

  // set timer variable at startup
int sec = 5;

int buttonState      = 0;
int lastButtonState  = 0;

void setup() {
  
  // LED output
  pinMode(8, OUTPUT);
  // set serial speed
  Serial.begin(9600);
  
  // set buttonPins 
  pinMode(buttonPin1, INPUT_PULLUP);
  pinMode(buttonPin2, INPUT_PULLUP); 

  //set LED on until timer stops
  //digitalWrite(8, HIGH);
  
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  
  // Print a message to the LCD.
  lcd.print("Post Flow Sec");

  // Print timer setting to LCD
  lcd.setCursor(15,0);
  lcd.print(sec);
  
}

void loop() {

 

//wait for button press to start
      while (digitalRead(buttonPin1) == HIGH)
  {
    
    // Read buttonPin1 for timer value set
      buttonState = digitalRead(buttonPin2);

    //check if button is pressed
      if (buttonState != lastButtonState) {

    // Change state of buttonState if buttonPin2 is pressed
      if (buttonState ==1) {

   // Add 1 to timer time
      sec++;
   // If timer reaches xx then reset to start time =5
      if(sec>10) sec=5;    

   // slight delay
      delay(15);
  }
  
  lastButtonState = buttonState;
  Serial.print("timer is set to: ");
  Serial.println(sec);

   // Print timer setting changes to LCD
  lcd.setCursor(15,0);
  lcd.print(sec);
}    
    
    }
      while (digitalRead(buttonPin1) == LOW)
  {
      //buttonPin1 press detected
        digitalWrite(8, HIGH);
}
   
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
    lcd.setCursor(0, 1);
  
  // countdown and output to serial:
  for (int i=sec; i>=0; i--) {
    lcd.setCursor(0, 1);
    lcd.print(i);
  // Print countdown to console for information
    Serial.print("i is :");
    Serial.println(i);
  // set timer step approx 1 sec  
    delay(1000);
    
  // read timer and light LED of time is less that 1
    if (i<1) {
      digitalWrite(8, LOW);
    } else {
      digitalWrite(8, HIGH);
    }

  }
}

Because 0 is LOW, not HIGH. And your buttons are LOW when pressed.

 int lastButtonState  = 0;

And then when this code executes...

 if (buttonState != lastButtonState) {
    // Change state of buttonState if buttonPin2 is pressed
      if (buttonState ==1) {

...buttonState is HIGH/1 because the button is not pressed. So both conditions are true, therefore sec gets incremented.

Edit: Really you should compare with HIGH/LOW for button states, not 1 and 0.
Or if it helps any...

#define PRESSED LOW
#define RELEASED HIGH