Here's a sketch I wrote for a timer application. When a switch is closed momentarily, a pulse is sent to LED2 and LED1 is turned on for N seconds. At the end of that time, send another pulse to LED2 and turn off LED1. If the switch is closed again while running, the timer operation is terminated immediately. To calibrate a different run time, hold the switch closed longer than 2 seconds. That starts LED1 blinking once per second. Press the switch again during the Nth blink, where N = the desired run time in seconds. That saves the run time in EEPROM and uses the new value thereafter.
// 6/22/19
const int SW1 = 0; // manual input
const int LED1 = 1; // simulates timer output signal
const int LED2 = 2; // simulates auxiliary pulse output signal
unsigned long longTime = 2000; // >2000 mS ON defines long SW1 press
unsigned long SW1on = 0; // time when SW1 pressed
unsigned long SW1off = 0; // time when SW1 released
unsigned long runTime = 0; // duration of timer output signal to LED1
unsigned long nowTime = 0; // millis() readings during calibration procedure
#include <EEPROM.h>
void setup() {
pinMode(SW1, INPUT_PULLUP);
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
digitalWrite(LED1, HIGH); //initialize LED1 off
digitalWrite(LED2, HIGH); //initialize LED2 off
}
void loop() {
while (digitalRead(SW1) == LOW) {} // don't start anything while SW1 is closed
while (digitalRead(SW1) == HIGH) {} // don't start loop until SW1 closes
SW1on = millis(); // save SW1 closed time
while (digitalRead(SW1) == LOW) {} // wait until SW1 opens
SW1off = millis(); // save SW1 opened time
if ((SW1off - SW1on) > longTime) { // was it a long switch press ?
runTime = 0; // yes, prepare to calibrate
goto calibrate; } // go calibrate
runTime = EEPROM.read(0); // fetch saved runTime seconds
pulse(); // blink LED2
digitalWrite (LED1, LOW); // turn on LED1
SW1off = millis() + (1000 * runTime); // convert runTime from seconds to milliseconds
while ((millis()<= SW1off)&&(digitalRead(SW1)==HIGH)){}
// do nothing until time's up, unless there's another SW1 closure to abort
pulse(); // blink LED2
digitalWrite (LED1, HIGH); // turn off LED1
while (digitalRead(SW1) == LOW) { } // do nothing until SW1 opens
return;
calibrate: // recalibrate runTime following long switch press
digitalWrite (LED1, HIGH); // turn off LED1
delay (200); // leave it off for 0.2 sec
digitalWrite (LED1, LOW); // turn on LED1 for 0.8 sec
runTime ++; // add 1-sec to runTime
nowTime = millis(); // get current time
while ((millis()<(nowTime+800))&&(digitalRead(SW1)==HIGH)){}
// wait until end of 1 second unless SW1 pressed to terminate calibration
if (millis() >= (nowTime + 800)) // end of a second ?
goto calibrate; // yes, loop again
digitalWrite (LED1, HIGH); // done cal, turn off LED1
EEPROM.write(0, runTime); // save new runTime in EEPROM
while (digitalRead(SW1) == LOW) { } // wait until SW1 is open
}
void pulse(){ // function for sending short pulse to LED2
digitalWrite (LED2, LOW);
delay (100);
digitalWrite (LED2, HIGH);
delay (100);
}
The sketch works fine, but I also need another version that has a run time of several minutes, and calibrating that by counting seconds is too time consuming. I've tried to write a version that operates this way: If the system is idle, holding the switch longer than 2 seconds starts calibration, which is then done with short switch presses where each press represents 1 minute of run time. Calibration is terminated by again holding the switch longer than 2 seconds, or by no switch activity for 10 seconds. If at least one press has been counted the count is saved to EEPROM and the new run time is used thereafter.
This sketch (my first and only attempt at Arduino programming) took many hours of tedious work to weed out the syntax errors by trial-and-error recompiling to get all the semicolons, parenthesis, and curly brackets right. I've been trying very hard to write the faster calibrate version, so far without success. As you can tell I'm not a very skilled programmer. But at 88 years of age I don't have time to learn C++. I'm going to continue trying to write the faster version, but if there's anyone who thinks it might be fun to take a shot at, and help out an old fart, be my guest.