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.
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.
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.
#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.
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;
}
}