Hi, I seem to have difficulties in creating my "Stopwatch Project" wherein I use 2 buttons to start and stop the clock from running. It counts in seconds and the only way that I can actually start it is by holding the start button, then it counts. Now what I wanted to create was a stopwatch that doesn't need the user to hold the button in order to keep it from running. I want to ask how can I make it run after just one push of a button automatically?
Here is my code:
# include <LiquidCrystal_I2C.h>
# include <Wire.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Stopwatch Variables
int timer = 0;
int counter = 0;
void setup()
{
lcd.init();
lcd.clear();
lcd.backlight();
pinMode(9, INPUT);
pinMode(8, INPUT);
}
void loop()
{
if (digitalRead(9) == HIGH)
{
counter += 10;
delay(10);
if (counter == 400)
{
counter = 0;
timer += 1;
}
lcd.setCursor(0, 0);
lcd.print(timer);
lcd.setCursor(0, 1);
lcd.print("Seconds");
}
if (digitalRead(8) == HIGH)
{
counter = 0;
timer = 0;
lcd.clear();
}
}
I can see the counter starts increasing when Pin#9 is high. If you want to make the increment independent of the button press, I think you have to write the codes for counter increment outside the conditional loop.
Hello beginnerz
Here is a recipe as pseudo code for programming in your project.
Debounce the keys
when the start button has been pressed, then start the timer.
when the start button has been pressed, then stop the timer.
if the reset button has been pressed, then reset the counters.
when the timer is running, display the counter on the LCD.
Have a nice day and enjoy programming in C++ and learning.
MIND THE GAP
PaulRB
August 13, 2022, 3:40pm
4
You need to use a new variable to know if the stopwatch is running.
bool running = false;
A bool variable can only have one of two values; true or false.
Then you can say
if (running)
{
counter += 10;
delay(10);
Next, you have to change the variable between true and false when the appropriate button is pressed.
when the stop button has been pressed, then stop the timer.
If you do all of
paulpaulson:
when the start button has been pressed, then start the timer.
when the start button has been pressed, then stop the timer.
if the reset button has been pressed, then reset the counters.
then what need is there for
?
PaulRB
August 13, 2022, 4:02pm
7
Switch bounce could cause the stopwatch to immediately stop after starting, maybe more than once.
Not if the start button and stop button are two separate buttons.
Maybe my stopwatch example will help:
/////////////////////////////////////
// Stopwatch Example
//
// Written by: John Wasser
/////////////////////////////////////
const byte StartButtonPin = A1; // Button wired from pin to GND
const byte StopResetButtonPin = A2; // Button wired from pin to GND
bool StartButtonWasPressed = false;
bool StopResetButtonWasPressed = false;
unsigned long DebounceTimer = 0;
const unsigned DebounceTime = 10;
bool IsRunning = false;
unsigned long ElapsedTime = 0;
unsigned long LastStartTime = 0;
static void ShowTheTime()
{
static unsigned long lastDisplayTime = 0;
unsigned long displayTime = ElapsedTime;
if (IsRunning)
displayTime += millis() - LastStartTime;
if (displayTime != lastDisplayTime)
{
lastDisplayTime = displayTime;
// This is where you would put your code to display the time
Serial.println(displayTime / 1000.0, 3);
}
}
void setup()
{
Serial.begin(115200);
delay(200);
pinMode(StartButtonPin, INPUT_PULLUP);
pinMode(StopResetButtonPin, INPUT_PULLUP);
}
void loop()
{
unsigned long currentTime = millis();
bool startButtonIsPressed = digitalRead(StartButtonPin) == LOW;
bool stopResetButtonIsPressed = digitalRead(StopResetButtonPin) == LOW;
// State Change Detection and debounce
if (startButtonIsPressed != StartButtonWasPressed &&
currentTime - DebounceTimer > DebounceTime)
{
// Button has changed state
StartButtonWasPressed = startButtonIsPressed;
DebounceTimer = currentTime;
if (startButtonIsPressed)
{
// Just Pressed START
if (!IsRunning)
{
// Starting/Restarting the timer
LastStartTime = currentTime;
IsRunning = true;
Serial.println("Started");
}
else
{
// Pausing the timer
IsRunning = false; // Paused
ElapsedTime += currentTime - LastStartTime;
Serial.println("Paused");
}
}
}
// State Change Detection and debounce
if (stopResetButtonIsPressed != StopResetButtonWasPressed &&
currentTime - DebounceTimer > DebounceTime)
{
// Button has changed state
StopResetButtonWasPressed = stopResetButtonIsPressed;
DebounceTimer = currentTime;
if (stopResetButtonIsPressed)
{
// Just Pressed STOP/RESET
if (IsRunning)
{
// Pausing the timer
IsRunning = false; // Paused
ElapsedTime += currentTime - LastStartTime;
Serial.println("Stopped");
}
else
{
// Was not running so reset everything
ElapsedTime = 0;
IsRunning = false;
Serial.println("Reset");
}
}
}
ShowTheTime();
}
Hello beginnerz
Here comes a simple sketch coded in class-less OOP wrt my a.m. receipe.
# include <LiquidCrystal_I2C.h>
# include <Wire.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Stopwatch Variables
unsigned long timer = 0;
int counter = 0;
enum {Start, Reset};
struct BUTTON
{
int ident;
byte pin;
int stateOld;
unsigned long stamp;
unsigned long duration;
};
BUTTON buttons[]
{
{Start, A0, false, 0, 20},
{Reset, A1, false, 0, 20},
};
void ShowTheTime()
{
lcd.setCursor(0, 0);
lcd.print(timer / 1000.0, 1);
lcd.setCursor(0, 1);
lcd.print("Seconds");
}
void setup()
{
lcd.init();
lcd.clear();
lcd.backlight();
for (auto button_: buttons) pinMode(button_.pin, INPUT_PULLUP); // Button wired from pin to GND
}
void loop()
{
unsigned long currentTime = millis();
static unsigned long stamp;
const unsigned long duration = 100;
static bool startStop = true;
/*
if (digitalRead(9) == HIGH)
{
counter += 10;
delay(10);
if (counter == 400)
{
counter = 0;
timer += 1;
}
lcd.setCursor(0, 0);
lcd.print(timer);
lcd.setCursor(0, 1);
lcd.print("Seconds");
}
if (digitalRead(8) == HIGH)
{
counter = 0;
timer = 0;
lcd.clear();
}
*/
for (auto & button_: buttons)
{
if (currentTime - button_.stamp >= button_.duration)
{
button_.stamp = currentTime;
int stateNew = !digitalRead(button_.pin);
if (button_.stateOld != stateNew)
{
button_.stateOld = stateNew;
if (stateNew)
{
switch (button_.ident)
{
case Start:
startStop = !startStop;
break;
case Reset:
timer = 0;
lcd.clear();
ShowTheTime();
break;
}
}
}
}
}
if (currentTime - stamp >= duration && startStop)
{
stamp = currentTime;
timer += duration;
ShowTheTime();
}
}
Have a nice day and enjoy programming in C++ and learning.
MIND THE GAP
system
Closed
February 10, 2023, 5:19am
12
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.