I have written a code for a stopwatch to run on LCD screen (when button pressed, it starts), but I have used delay(). Is there a way to perform it without delay()?
What is timerMode ? Is that a variable that tells what state the sketch is in ? You could call it "state". Give it a number, such as 1, 2, 3 and don't increment it.
Do you want to start when a button is pressed or when a button is released ? You can already read about the State Change Detection.
Do you want to add a 'pause' button ?
I suppose you know the Blink Without Delay ?
You need two variables. A unsigned long previousMillis as a timestamp when the timer was started. And a variable that tells when the stopwatch is running/active (it can also be a 'state' variable).
//Forum URL https://forum.arduino.cc/t/timer-without-delay/882316?u=larryd
// Version YY/MM/DD Description
// 1.00 20/09/06 If your LCD is parallel wired, comment line with the arrows <-----<<<<<
// 1.01 20/09/09 Functioning sketch
// 1.02 21/07/06 Added LCD pin numbers used by: @millionish
#define switchIsClosed LOW
#define flagIsSet true
#define flagIsReset false
#define enabled true
#define disabled false
//************************************************************************
//select Serial or Parallel LCD option that you have
//************************************************************************
//comment the next line if you have a parallel LCD
//#define serialLCDisBeingUsed // <-----<<<<< <-----<<<<<
#ifdef serialLCDisBeingUsed
#include <Wire.h>
//Use I2C library: https://github.com/duinoWitchery/hd44780
//LCD Reference: https://www.arduino.cc/en/Reference/LiquidCrystal
#include <hd44780.h> //main hd44780 header
//NOTE:
//hd44780_I2Cexp control LCD using I2C I/O expander backpack (PCF8574 or MCP23008)
//hd44780_I2Clcd control LCD with native I2C interface (PCF2116, PCF2119x, etc...)
#include <hd44780ioClass/hd44780_I2Cexp.h> //I2C expander i/o class header
// LCD I2C PCB
// * LCD I2C pin 1 to GND
// * LCD I2C pin 2 to +5V
// * LCD I2C pin 3 SDA, UNO A4
// * LCD I2C pin 4 SCL, UNO A5
//If you do not know what your I2C address is, first run the 'I2C_Scanner' sketch
hd44780_I2Cexp lcd(0x3F);
//hd44780_I2Cexp lcd(0x27);
//************************************************************************
#else
#include <LiquidCrystal.h>
// Common used LCD circuit
// * LCD RS pin 4, to digital pin 7
// * LCD Enable pin 6, to digital pin 6
// * LCD D4 pin 11, to digital pin 5
// * LCD D5 pin 12, to digital pin 4
// * LCD D6 pin 13, to digital pin 3
// * LCD D7 pin 14, to digital pin 2
//
// * LCD pin 1 VSS to GND
// * LCD pin 2 VDD to +5V
// * LCD pin 5 R/W to GND
// * LCD pin 15 'A' to back light resistor (if not on PCB) to +5V
// * LCD pin 16 'K' to GND
//
// * 10K Potentiometer:
// * both ends to ground,
// * wiper to LCD VO, LCD pin 3
//
// R E D D D D
// S N 4 5 6 7
//LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
LiquidCrystal lcd(5, 6, A5, A4, A3, A2);
// N O T E make sure these do not conflict with the pins used below
#endif
//************************************************************************
bool switchFlag = flagIsReset;
byte lastSwitchState;
const byte heartbeatLED = 13;
const byte mySwitch = 2;
//timing stuff
unsigned long heartbeatMillis;
unsigned long switchMillis;
unsigned long startMillis;
unsigned long updateMillis;
//Finite Sate Machine definition
enum Machine {POWERUP, STARTUP, TIMING, LOCKLCD};
Machine SM = POWERUP;
//************************************************************************
void setup()
{
lcd.begin(16, 2); // <-----<<<<< Make changes for the size of the LCD
pinMode(heartbeatLED, OUTPUT);
//turn on internal pull-up resistor
pinMode( mySwitch, INPUT_PULLUP );
} //END of setup()
//************************************************************************
void loop()
{
//***********************
//time to toggle the heartbeatLED ?
if (millis() - heartbeatMillis >= 500)
{
//restart the TIMER
heartbeatMillis = millis();
//toggle the LED
digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
}
//***********************
//time to check the switches ?
if (millis() - switchMillis >= 50)
{
//restart the TIMER
switchMillis = millis();
checkSwitches();
}
//***********************
//check the State Machine
checkMachine();
} //END of loop()
//************************************************************************
void checkSwitches()
{
//***************************************** mySwitch
//
byte state = digitalRead(mySwitch);
//***********************
//has the switch changed state ?
if (lastSwitchState != state)
{
//update to the new state
lastSwitchState = state;
//************
//was the switch pushed ?
if (state == switchIsClosed)
{
switchFlag = flagIsSet;
}
} //END of if (lastSwitchState != state)
} //END of checkSwitches()
//************************************************************************
void checkMachine()
{
//update the state machine
switch (SM)
{
case POWERUP:
lcd.setCursor(0, 0);
// 111111
// 0123456789012345
lcd.print(" STOPWATCH ");
lcd.setCursor(0, 1);
// 111111
// 0123456789012345
lcd.print(" W a i t i n g ");
//next state
SM = STARTUP;
break;
//***********
case STARTUP:
//has the user pressed the switch yet ?
if (switchFlag == flagIsSet)
{
switchFlag = flagIsReset;
//restart the TIMER
startMillis = millis();
//next state
SM = TIMING;
}
break;
//***********
case TIMING:
//time to update the LCD (every 50ms)
if (millis() - updateMillis > 50)
{
//restart the TIMER
updateMillis = millis();
lcd.setCursor(0, 0);
// 111111
// 0123456789012345
lcd.print(" STOPWATCH ");
lcd.setCursor(0, 1);
// 111111
// 0123456789012345
lcd.print("Time: ");
float Time = (float)(millis() - startMillis) / 1000;
lcd.setCursor(6, 1);
// 111111
// 0123456789012345
// Time: ###.##
lcd.print(Time); //2 decimal places
lcd.setCursor(13, 1);
// 111111
// 0123456789012345
// Time: ###.## sec
lcd.print("sec");
}
//has the user pressed the switch yet ?
if (switchFlag == flagIsSet)
{
switchFlag = flagIsReset;
//next state
SM = LOCKLCD;
}
break;
//***********
case LOCKLCD:
//has the user pressed the switch yet ?
if (switchFlag == flagIsSet)
{
switchFlag = flagIsReset;
//next state
SM = POWERUP;
}
break;
} //END of switch/case
} //END of checkMachine()
//*********************************************************************