I am working on a stopwatch project and I have a working stopwatch but i want to add a Start/Stop button (Press it and it starts, press it again and it pauses it, and press it again it resumes it.) on D8 and a Reset button (Back to 0) on D9.
Here is the code i have so far:
// Made by Matthew Hinkleman aka gohawks413
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int mil=00;
int sec=00;
int min=00;
int hr=00;
void setup() {
lcd.begin(16,2);
lcd.setCursor(3,1);
lcd.print("Stopwatch");
delay(1000);
lcd.setCursor(2,0);
lcd.print("STARTS IN 5");
delay(1000);
lcd.clear();
lcd.setCursor(2,0);
lcd.print("STARTS IN 4");
delay(1000);
lcd.clear();
lcd.setCursor(2,0);
lcd.print("STARTS IN 3");
delay(1000);
lcd.clear();
lcd.setCursor(2,0);
lcd.print("STARTS IN 2");
delay(1000);
lcd.clear();
lcd.setCursor(2,0);
lcd.print("STARTS IN 1");
delay(1000);
lcd.clear();
lcd.setCursor(0,0);
}
void loop() {
lcd.setCursor(3,2);
lcd.print("Stopwatch");
lcd.setCursor(3,0);
lcd.print(hr);
lcd.setCursor(5,0);
lcd.print(":");
lcd.print(min);
lcd.setCursor(8,0);
lcd.print(":");
lcd.print(sec);
lcd.print(".");
lcd.print(mil);
mil=mil+1;
delay(100);
if(mil == 10){
mil=0;
sec=sec+1;
}
if(sec == 60){
sec=00;
min=min+1;
}else;
if(min == 60){
min=0;
hr=hr+1;
}else;
lcd.clear();
}
Here is a tested demo that uses the state change detection with a button switch to cycle through a series of choices.
// by C Goulding aka groundFungus
const byte buttonPin = 12; // the pin to which the pushbutton is attached
const byte ledPin = 13; // the pin to which the LED is attached
byte mode = 0;
void setup()
{
// initialize the button pin as a input with internal pullup enabled
pinMode(buttonPin, INPUT_PULLUP);
// initialize the LED as an output:
pinMode(ledPin, OUTPUT);
// initialize serial communication:
Serial.begin(115200);
Serial.println("Select mode with push button");
}
void loop()
{
static bool lastButtonState = HIGH;
static unsigned long timer = 0;
unsigned long interval = 50; // check switch 20 times per second
if (millis() - timer >= interval)
{
timer = millis();
// read the pushbutton input pin:
bool buttonState = digitalRead(buttonPin);
// compare the new buttonState to its previous state
if (buttonState != lastButtonState)
{
if (buttonState == LOW)
{
// if the current state is LOW then the button
// went from off to on:
mode++;
if(mode > 2)
{
mode = 0;
}
}
}
// save the current state as the last state,
//for next time through the loop
lastButtonState = buttonState;
}
if (mode == 0)
{
function1();
}
else if(mode == 1)
{
function2();
}
else if(mode == 2)
{
function3();
}
}
void function1()
{
// run code for function 1
static unsigned long timer = 0;
unsigned long interval = 1000;
if (millis() - timer >= interval)
{
timer = millis();
Serial.println("Running function 1");
}
}
void function2()
{
// run code for function 2
static unsigned long timer = 0;
unsigned long interval = 1000;
if (millis() - timer >= interval)
{
timer = millis();
Serial.println("Running function 2");
}
}
void function3()
{
// run code for function 2
static unsigned long timer = 0;
unsigned long interval = 1000;
if (millis() - timer >= interval)
{
timer = millis();
Serial.println("Running function 3");
}
}
You don't use it directly. You read it, play around with it, until you understand the principles. Then you apply those principles in your own code.
But if I were you, I would not add any buttons to your code yet. Do more testing first. Then you will realise that your stopwatch does not keep good time. I suspect you will find that even after 1 or 2 minutes, it will be slow by one or more seconds.
Many beginners have come to the forum with code similar to yours and asked why it does not keep good time. So spend some time using the forum search to find how they solved the problem.
EDIT: Forget using the forum search. I just tried and could find no examples like your code, even though I remember many of them over the years. Like finding a needle in a haystack!
The problem is that you can't use delay() like that to keep your stopwatch accurate. That would only work if all your other code took zero time to run. Unfortunately that's not true.
Arduino has a pretty good stopwatch built-in. It's the millis() function.
So that means your stopwatch is running approximately 10% slow. Your loop() code contains a delay(100), but all the code in loop() combined is taking around 110ms.
You could try reducing your delay to delay(90). You will find that is a big improvement, but my suggested code above is even better because it automatically adjusts the delay() each time to synchronise with millis().
Start with the reset button, because that's really easy. If the button is pressed, your code just needs to set mil, sec, min & hr back to zero. No need for state change detection or debouncing with this button.
The best way to connect a button is to connect it between the Arduino pin and ground. Set the pin mode to INPUT_PULLUP so that the pin does not float when the button is not pressed.
Your code can then read the pin with digitalRead(). If the result is LOW, that means the button is pressed.
Another alternative is to use the Arduino's reset button as your stopwatch reset button. If you want to use an external button, you can connect it between the RST pin and ground.
Why go back to setup()? Do you want to repeat the whole "Thunderbirds are go" sequence?
If you use the Arduino reset button (or an external button connected to the RST pin) then setup() will get run.
If you want to repeat just the countdown and don't want to reset the Arduino, you could move that countdown code to a new function and call it from both setup() and when your reset button is pressed.
What is not good is that black wire on right side of the breadboard. That is connected directly from 5V to ground and will cause a short circuit which could damage the arduino. I think you made a mistake there!
EDIT: actually it won't cause a short circuit. But both buttons will connect to 5V instead of ground, so they will never read LOW.