Cant stop code from being run after reset

Hey,

My project:
Make a simple timer that starts at the click of a button. My sketch works, but it starts immediately after reset.
I want the sketch to stop and wait for a button press.

If anyone could help, i would be very grateful:)

Here is my code:

#include <LiquidCrystal.h>

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


#define ledPin  13                  // LED connected to digital pin 13
#define buttonPin 8                 // button on pin 4

int value = LOW;                    // previous value of the LED
int buttonState;                    // variable to store button state
int lastButtonState;                // variable to store last button state
//int blinking;                       // condition for blinking - timer is timing
long interval = 100;                // blink interval - change to suit
long previousMillis = 0;            // variable to store last time LED was updated
long startTime ;                    // start time for stop watch
long elapsedTime ;                  // elapsed time for stop watch
int fractional;                     // variable used to store fractional part of time



void setup()
{
    Serial.begin(9600);
    
      lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("Test");

    pinMode(ledPin, OUTPUT);        

    pinMode(buttonPin, INPUT);       
    digitalWrite(buttonPin, HIGH);   

}

void loop()
{ 
     
      buttonState = digitalRead(buttonPin);

  if (buttonState == HIGH) {     
    
    activate(); 
  } 
  else {
  
    digitalWrite(13, HIGH); 
  }

}





void activate()
{
      
 
    buttonState = digitalRead(buttonPin);               

    if (buttonPin == HIGH){    
       // if true then found a new button press while clock is not running - start the clock

       startTime = millis();                                   // store the start time
       delay(5);                                               // short delay to debounce switch
       lastButtonState = buttonState;                          // store buttonState in lastButtonState, to compare next time

    }

    else if (lastButtonState == HIGH){     
       // if true then found a new button press while clock is running - stop the clock and report

         elapsedTime =   millis(); //- startTime;              // store elapsed time
         lastButtonState = buttonState;                     // store buttonState in lastButtonState, to compare next time

  lcd.setCursor(0,1);

  lcd.print("   ");
        // routine to report elapsed time 
         lcd.print( (int)(elapsedTime / 1000L));         // divide by 1000 to convert to seconds - then cast to an int to print

         lcd.print(".");                             // print decimal point

         
        fractional = (int)(elapsedTime % 1000L);

        if (fractional == 0)
           lcd.print("000");      
        else if (fractional < 10)    
           lcd.print("00");       
        else if (fractional < 100)
           lcd.print("0");        

        lcd.println(fractional);  // print fractional part of time 

    }

    else{
       lastButtonState = buttonState;                         // store buttonState in lastButtonState, to compare next time

Does your button have a pull down resistor? That is not the proper way to debounce a button, look at the debounce example. Also you never turn the LED off.

Yes it has a pulldown resistor.

The led part of the sketch is obsolete, and will be removed.

It might not be the right way to debounce, but the code in the activate() function works.

Its the part in the void loop() that wont stop the activate() function that is bothering me...

Well if it keeps going to the activate function, then it is seeing that the button is high, otherwise it will not do that if statement. Check your wiring again just to be sure.

You where correct. The butten is HIGH when not pressed and LOW when pressed.

I changed the code to:

void loop()
{ 
     
      buttonState = digitalRead(buttonPin);

  if (buttonState == LOW) {     
    
    
    activate(); 
  } 
  else {
  
    digitalWrite(13, HIGH); 
  }

}

But it still wont stop the code from being run…

Did you change the button logic in activate() as well?

Please re-pot your entire code.

I noticed that your not using a latch. It is possible that if you press the button the first time, your not giving it time to go back HIGH, so it is carring over to the activate function.

How can i implement a latch?

byte lastbuttonState = 0; // new global variable

void loop() {
buttonState = digitalRead(buttonPin);
// normal debounce code here

  if(buttonState != lastbuttonState) {
    activate();
    lastbuttonState = buttonState;
   } 
}

Alternative:

byte lastbuttonState = 0; // new global variable
byte buttonState2 = 0;
void loop() {

buttonState1 = digitalRead(buttonPin);
delay(20);
buttonState2 = digitalRead(buttonPin);

  if(buttonState1 == buttonState2) {
    if(buttonState2 != lastbuttonState) {
     activate();
     lastbuttonState = buttonState2;
    }
  } 
}

dont forget the setup()

Webca: I want the sketch to stop and wait for a button press.

The simplest way to do that is to put a loop in setup() that reads the switch state repeatedly until the button press is detected.

HazardsMind

I ill try that tomorrow, and i will let you know how it goes..

And thanks for all your help:)

Your new initialization code:

byte lastbuttonState = 0; // new global variable

initializes to the button being pressed in the new scheme, yes?

Please post your entire code...

MaJiG: Your new initialization code:

byte lastbuttonState = 0; // new global variable

initializes to the button being pressed in the new scheme, yes?

Please post your entire code...

My code? It's just a snippet from his code that I made. Just replace his loop function with one of mine.

No, I meant Webca.

I didnt get it to work :frowning:

Here is my code:

#include <LiquidCrystal.h>

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


#define ledPin  13                  // LED connected to digital pin 13
#define buttonPin 9                 // button on pin 4

int value = LOW;                    // previous value of the LED
int buttonState;                    // variable to store button state
int lastButtonState;                // variable to store last button state
long interval = 100;                // blink interval - change to suit
long previousMillis = 0;            // variable to store last time LED was updated
long startTime ;                    // start time for stop watch
long elapsedTime ;                  // elapsed time for stop watch
int fractional;                     // variable used to store fractional part of time

byte lastbuttonState2 = 0; // new global variable
byte buttonState1 = 0;
byte buttonState2 = 0;

void setup()
{
    Serial.begin(9600);
    
      lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("Test");

    pinMode(ledPin, OUTPUT);         // sets the digital pin as output

    pinMode(buttonPin, INPUT);       // not really necessary, pins default to INPUT anyway
    digitalWrite(buttonPin, HIGH);   // turn on pullup resistors. Wire button so that press shorts pin to ground.

}

void loop()
{ 
  
   
buttonState1 = digitalRead(buttonPin);
delay(20);
buttonState2 = digitalRead(buttonPin);

  if(buttonState1 == buttonState2) {
    if(buttonState2 != lastButtonState) {
     activate();
     lastButtonState = buttonState2;
    }
  }

    

}


void activate()
{
      
    buttonState = digitalRead(buttonPin);                   // read the button state and store

    if (buttonState == HIGH){     
       // if true then found a new button press while clock is not running - start the clock

       startTime = millis();                                   // store the start time
       delay(5);                                               // short delay to debounce switch
       lastButtonState = buttonState;                          // store buttonState in lastButtonState, to compare next time

    }

    else if (buttonState == LOW){     
       // if true then found a new button press while clock is running - stop the clock and report

         elapsedTime =   millis(); - startTime;              // store elapsed time
         lastButtonState = buttonState;                     // store buttonState in lastButtonState, to compare next time

  lcd.setCursor(0,1);

  lcd.print("   ");
        // routine to report elapsed time 
         lcd.print( (int)(elapsedTime / 1000L));         // divide by 1000 to convert to seconds - then cast to an int to print

         lcd.print(".");                             


        fractional = (int)(elapsedTime % 1000L);


        if (fractional == 0)
           lcd.print("000");     
        else if (fractional < 10)    
           lcd.print("00");       
        else if (fractional < 100)
           lcd.print("0");        

        lcd.println(fractional);  // print fractional part of time 

    }

    else{
       lastButtonState = buttonState;                         // store buttonState in lastButtonState, to compare next time
    }


}

Try using a global boolean variable to keep track of whether the clock is running. Check for a button press. When you detect one, check for whether the clock is running. If it is, show the elapsed time, otherwise note millis. In both cases, set the boolean appropriately for the new situation. You should be able to make the whole thing much simpler this way.

What exactly should it be showing? With your code as of now, when the button is pressed, you see the change in time. However when I took out the " ; " in this line "elapsedTime = millis(); - startTime;" and when I just press the button, I get a readout of between 0.064 - 0.083. BUT, if I hold the button, the counter continues to accumulate and I get +3.250 when held for 3 seconds.

Which one is correct?

Added: change the println to just print for the last line, println(fractional) => print(fractional). println gives you junk on the end.

PeterH:

Webca: I want the sketch to stop and wait for a button press.

The simplest way to do that is to put a loop in setup() that reads the switch state repeatedly until the button press is detected.

But that would work and it's -much- too simple.

HazardsMind-

It has to be like this " elapsedTime = millis(); - startTime; ".

It is supposed to be a regular timer that works in the "background" and when i press the button i get a readout of how far it has come

These variables - int lastButtonState; // variable to store last button state probably should be int lastButtonState = 0; byte lastbuttonState2 = 0; // new global variable - I think you created this one, and thought you used it when you really just wanted to initialize lastButtonState. byte buttonState1 = 0; byte buttonState2 = 0;

and this little bit of code -

buttonState1 = digitalRead(buttonPin); // so the button isn't pressed here delay(20); buttonState2 = digitalRead(buttonPin); // and the button isn't pressed here

if(buttonState1 == buttonState2) { // then this is true because not pressed == not pressed if(buttonState2 != lastButtonState) { // and since lastButtonState was never initialized we don't know what it might be so this can be true also. activate(); // and activate() runs because every condition passed. lastButtonState = buttonState2; } }