I don't know why the pushbutton for my stop watch isn't working

I’m trying to write the code for a stop watch. The major part of the code to make the stop watch count was pretty easy but i can’t figure how to stop/pause the timer and also cause it to continue when a button is pressed. The code looks right to me and i have re-checked the button connection numerous times but it still doesn’t work. My theory is , it is probably stuck in the loop and that’s why it isn’t reacting to the buttons but i still need a fresh pair of eyes to see what the problem might be.
thanks

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
const int pushpinreset = 7;
const int pushpinstop = 10;
int hrnum = 0;
int minnum = 0;
int secnum = 0;
int ledpin = 13;
void setup() {
Serial.begin(9600);
display.begin(SSD1306_SWITCHCAPVCC, 0X3C);
display.clearDisplay();
pinMode(13, OUTPUT);
pinMode(pushpinstop, INPUT); //set up smode as an input
pinMode(pushpincontinue, INPUT);//set up cmode as an input
}
void loop() {
int smode = digitalRead(pushpinstop); // read the state of the push button
int cmode = digitalRead(pushpincontinue); //read the state of the push button
for ( int hrnum = 00; hrnum < 24 ; hrnum ++){
display.setTextSize(2); // set text size
display.setTextColor(WHITE);// set text color
display.setCursor(0,0);// set text position
display.display();// display text
delay(30);
display.clearDisplay();
for ( int minnum = 00; minnum < 60; minnum ++){
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(40,0);
display.display();
delay(30);
display.clearDisplay();
for ( int secnum = 00; secnum < 60; secnum ++){
if ( smode == HIGH){
rmode = LOW;
break;
}
if (cmode == HIGH){
pmode = LOW;
continue;
}
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.print(hrnum); display.print(":");display.print(minnum); display.print(":"); display.print(secnum);
display.display();
delay(1000);
display.clearDisplay();
}
}
}
}

watchproject.ino (1.64 KB)

Please post your code between [code] [/code] tags and is easy to copy to a text editor. Also use the AutoFormat tool to indent it consistently.

I have done it for you this time

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4

Adafruit_SSD1306 display(OLED_RESET);
const int pushpinreset = 7;
const int pushpinstop = 10;
int hrnum = 0;
int minnum = 0;
int secnum = 0;
int ledpin = 13;


void setup() {
    Serial.begin(9600);
    display.begin(SSD1306_SWITCHCAPVCC, 0X3C);
    display.clearDisplay();
    pinMode(13, OUTPUT);
    pinMode(pushpinstop, INPUT); //set up smode as an input
    pinMode(pushpincontinue, INPUT);//set up cmode as an input
}


void loop() {
    int smode = digitalRead(pushpinstop); // read the state of the push button
    int cmode = digitalRead(pushpincontinue); //read the state of the push button
    for ( int hrnum = 00; hrnum < 24 ; hrnum ++){
        display.setTextSize(2);   // set text size
        display.setTextColor(WHITE);// set text color
        display.setCursor(0,0);// set text position
        display.display();// display text
        delay(30);
        display.clearDisplay();
        for ( int minnum = 00; minnum < 60; minnum ++){
            display.setTextSize(2);
            display.setTextColor(WHITE);
            display.setCursor(40,0);
            display.display();
            delay(30);
            display.clearDisplay();
            for ( int secnum = 00; secnum < 60; secnum ++){   
                if ( smode == HIGH){
                    rmode = LOW;
                    break;
                }
                if (cmode == HIGH){
                    pmode = LOW;
                    continue;
                }
                display.setTextSize(2);
                display.setTextColor(WHITE);
                display.setCursor(0,0);
                display.print(hrnum); display.print(":");display.print(minnum); display.print(":"); display.print(secnum);
                display.display();
                delay(1000);
                display.clearDisplay();
            }
        }
    }
}

…R

I suspect part of your problem is that you have nested FOR loops and each of them has delay()s. When you add up all the delay time it is probably a long time before the program gets to check for a button press.

You should write code so that loop() can repeat hundreds or thousands of times per second if you want a responsive program.

Replace the FORs with IFs and use other code to increment the relevant variables. That way it will just spend enough time to increment one step for every iteration of loop()

And have a look at how millis() is used to manage timing without blocking in several things at a time

...R

Hi,
Welcome to the forum.

Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

How have you got your buttons wired, I notice you have not turned on PULL_UP resistors.

If your buttons connect digital input to 5V, you need a pull down 10K resisitor on each from digital input to gnd.

If your buttons connect digital input to gnd, you need a pull up 10K resisitor on each from digital input to 5V.

You cannot leave an input open circuit if you are using it, the input will usually hold the state of the last button push, without the resistors.

Tom... :slight_smile:

Thanks , i'll get on it

Hi i had some help here earlier and made the appropriate changes. First i changed all my ‘for’ loops to ‘if’ and changed my delays and started using millis() but the pushbuttons even though they read ( i’ve have checked it countless times) don’t affect the code as i want it to. I’m using internal INPUT_PULLUPs so my board connection is pretty simple. I want one button(rmode) to reset the timer when it is pressed and the other (smode) to pause the timer at the moment it is pressed
help would be appreciated
thanks.

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
const int pushpinreset = 7;
const int pushpinstop = 10;
 int hrnum = 0;
 int minnum = 0;
 int secnum = 0;
 int millnum = 0;
int ledpin = 13;
unsigned long pMillis = 0;
const long interval = 1000;
void setup() {
 Serial.begin(9600);
 display.begin(SSD1306_SWITCHCAPVCC, 0X3C);
 display.clearDisplay();
 pinMode(13, OUTPUT);
 pinMode(pushpinstop, INPUT_PULLUP); //set up smode as an input 
 pinMode(pushpinreset, INPUT_PULLUP);//set up mode as an input 
}
void loop() {
  unsigned long cMillis = millis();
int smode = digitalRead(pushpinstop); // read the state of the push button 
int rmode = digitalRead(pushpinreset); //read the state of the push button  
if ((cMillis - pMillis == interval) && ( secnum < 60)){  
pMillis = cMillis;
   while  (smode = LOW ){ //while smode is pressed 
  secnum = secnum; // secnum stays the same 
  hrnum = hrnum ; //hrnum stays the same
  minnum  = minnum ; // minnum stays the same
   }  
   while (rmode = LOW){ //while rmode is pressed 
    secnum = 0;     //all set to zero
    minnum = 0 ;
    hrnum = 0; 
   }             
secnum = secnum + 1;    //if cMillis is equal to 1 second increment secnum by 1
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.print(hrnum); display.print(":");display.print(minnum); display.print(":"); display.print(secnum); 
display.display();
display.clearDisplay();
 }
     
  if ( secnum == 60){        
     secnum = 0; 
     minnum = minnum + 1; 
    }       
  if (minnum == 60){
    minnum = 0;
    hrnum = hrnum = 1;
 }
}

i had some help here earlier

So why have you started a new thread?

The biggest problem is this (and its brother)

while  (smode = LOW ){

because there is nothing within the WHILE to change smode and get it out of the WHILE. Change those WHILEs to IFs.

This is not very reliable either because you might miss the exact moment

if ((cMillis - pMillis == interval) && ( secnum < 60)){

change it to

if ((cMillis - pMillis >= interval) && ( secnum < 60)){

…R

I made some further changes and added a piece of code to switch the LED when the button code is activated but i’m pretty sure that piece of code isn’t working and i don’t know why.

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
const int pushpinreset = 7;
const int pushpinstop = 10;
 int hrnum = 0;
 int minnum = 0;
 int secnum = 0;
 int millnum = 0;
int ledpin = 13;
unsigned long pMillis = 0;
const long interval = 1000;
void setup() {
 Serial.begin(9600);
 display.begin(SSD1306_SWITCHCAPVCC, 0X3C);
 display.clearDisplay();
 pinMode(13, OUTPUT);
 pinMode(pushpinstop, INPUT_PULLUP); //set up smode as an input 
 pinMode(pushpinreset, INPUT_PULLUP);//set up mode as an input 
}
void loop() {
  unsigned long cMillis = millis();
int smode = digitalRead(pushpinstop); // read the state of the push button 
int rmode = digitalRead(pushpinreset); //read the state of the push button 
 if  ( ( secnum < 60) && (smode = LOW )){ //while smode is pressed 
  digitalWrite(13,HIGH);
  secnum = secnum; // secnum stays the same 
  hrnum = hrnum ; //hrnum stays the same
  minnum  = minnum ; // minnum stays the same
   }  
   if (( secnum < 60) &&(rmode = LOW)){//while rmode is pressed 
   digitalWrite( 13, LOW);
    secnum = 0;     //all set to zero
    minnum = 0 ;
    hrnum = 0; 
   }           

 
if ((cMillis - pMillis >= interval) && ( secnum < 60)){  
pMillis = cMillis;
    
secnum = secnum + 1;    //if cMillis is equal to 1 second increment secnum by 1
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.print(hrnum); display.print(":");display.print(minnum); display.print(":"); display.print(secnum); 
display.display();
display.clearDisplay();
 }
     
  if ( secnum == 60){        
     secnum = 0; 
     minnum = minnum + 1; 
    }       
  if (minnum == 60){
    minnum = 0;
    hrnum = hrnum = 1;
 }
}
 if  ( ( secnum < 60) && (smode = LOW )){
 if (( secnum < 60) &&(rmode = LOW))

In both these conditional statements smode and rmode need to be followed by ==.

thanks can't believe it was something so little