Here are two sketches made to do the same thing.
There is a blinking LED.
Push the button top stop the blinking.
Push it again to restart the blinking.
The first sketch uses delay().
The second sketch uses millis().
I have not tested these but they do compile. Help find "features"?
There's not much code here....
Sketch 1
// BlockedSketchLedAndButton by GoForSmoke 03/08/24
// compiles, untested so far
// expect: ground pin 7 to toggle blink off/on
// expect this to take a while to notice button action.
// this is a Before Sketch. The After Sketch does not Block Execution.
const byte debounce = 10; // ms delay
const byte blinkPin = 13;
const byte buttonPin = 7;
byte buttonStateNow, buttonStatePrev;
byte blinkState;
word blinkInterval = 500;
const word interval = 500;
void setup()
{
pinMode( blinkPin, OUTPUT ); // LOW by default
// blinkState = 0; // by default
pinMode( buttonPin, INPUT_PULLUP );
buttonStateNow = buttonStatePrev = 1;
}
void blink()
{
if ( blinkInterval > 0 ) // button toggled to ON by default
{
blinkState = !blinkState; // 0 <==> 1
digitalWrite( blinkPin, blinkState ); // led ON
delay( blinkInterval );
}
}
void button()
{
buttonStateNow = digitalRead( buttonPin );
if ( buttonStateNow == 0 && buttonStatePrev == 1 ) // press detected
{
delay( debounce );
if ( blinkInterval > 0 )
{
blinkInterval = 0; // stop blinking
blinkState = 0;
digitalWrite( blinkPin, blinkState );
}
else
{
blinkInterval = interval; // blink at interval
}
}
else if ( buttonStateNow == 1 && buttonStatePrev == 0 ) // release detected
{
delay( debounce );
}
buttonStatePrev = buttonStateNow;
}
void loop()
{
button();
blink();
}
Sketch 2
// UnblockedSketchLedAndButton by GoForSmoke 03/08/24
// compiles, untested so far
// expect: ground pin 7 to toggle blink off/on
const byte blinkPin = 13;
const byte buttonPin = 7;
byte buttonStateNow, buttonStatePrev;
const word debounce = 10; // ms delay
word debounceStart; // interval is debounce above
byte blinkState;
unsigned long blinkStart, blinkInterval = 500;
const unsigned long interval = 500;
void setup()
{
pinMode( blinkPin, OUTPUT ); // LOW by default
// blinkState is 0 by default
pinMode( buttonPin, INPUT_PULLUP );
buttonStateNow = buttonStatePrev = 1;
}
void blink()
{
static unsigned long waitStart, waitMs;
if ( blinkInterval == 0 )
{
return;
}
if ( waitMs > 0 ) // if-timer runs when set then turns itself off
{
if ( millis() - waitStart >= waitMs ) // see if wait is over
{
waitMs = 0; // wait is over, turn wait off!
}
}
else
{
blinkState = !blinkState; // 0 <==> 1
digitalWrite( blinkPin, blinkState ); // led ON
waitMs = blinkInterval;
waitStart = millis();
}
return;
}
void button()
{
static byte State = 0; // local variable only the function uses
static unsigned long waitStart, waitMs; // local vars
if ( waitMs > 0 ) // if-timer for state machine delays
{
if ( millis() - waitStart >= waitMs )
{
waitMs = 0;
}
}
else
{
switch ( State )
{
case 0 :
buttonStateNow = digitalRead( buttonPin );
if ( buttonStateNow == 0 && buttonStatePrev == 1 ) // press detected
{
waitMs = debounce;
waitStart = millis();
State = 1;
}
else if ( buttonStateNow == 1 && buttonStatePrev == 0 ) // release detected
{
waitMs = debounce;
waitStart = millis();
}
buttonStatePrev = buttonStateNow;
break;
case 1 :
if ( blinkInterval > 0 )
{
blinkInterval = 0; // stop blinking
digitalWrite( blinkPin, LOW );
}
else
{
blinkInterval = interval; // blink at interval
}
State = 0;
break;
}
}
return;
}
void loop()
{
button();
blink();
}