As a learning process, I examined the code for Blink Without Delay and understand pretty much what each line does. Now I'd like to know a simple way to start it with a momentary button press.
(From my experience in general electronics, I am aware of issues like key bounce. The button is just representative of an input trigger).
I pursued several search results but the OPs all want to do something in addition to blinking an LED. The ensuing discussions and attempts to help quickly muddle up things for a raw beginner like me.
So could you please help by providing a straightforward way to manually start BWoD with a momentary LOW input on a pin?
I've tried a few ideas of my own and can run BWoD while a button is pressed. I'd like to know how to make it keep running after the button is released. The ultimate object is to learn how to control other processes using millis.
Here's my sketch for blinking while pressing a button:
Change the code so that when a button press is detected a boolean variable is set to true
Take the BWoD code out of the test for the button press and make it run only when the boolean is true
Alternatively, test for the button press in setup() using a while loop and only end the while loop when you detect a button press. Put the normal BWoD code in loop()
The following example provides a class object for BWOD and a class object to debounce a pushbutton using BWOD, as well as the blinking and on/off logic.
/* Blink Without Delay and Pushbutton Example
* by @Perehama
*/
class IntervalTimer {
public:
IntervalTimer(unsigned long i);
void synchronizeTimer();
bool intervalComplete();
void setInterval(unsigned long i);
unsigned long elapsedTime();
private:
unsigned long _interval;
unsigned long _timestamp;
};
class PushButton {
public:
PushButton(int pinNumber, unsigned long debounceTime);
void inputPullup() const;
bool isPushed();
unsigned long durationHeld();
void setDebounce(unsigned long i);
private:
IntervalTimer _timer;
int _preState = HIGH;
unsigned char _debounceFlag = 0;
const int _ButtonPin;
const static int _RisingEdge = HIGH - LOW;
const static int _FallingEdge = LOW - HIGH;
};
IntervalTimer::IntervalTimer(const unsigned long i) : _interval(i) {}
void IntervalTimer::synchronizeTimer() {
_timestamp = millis();
}
bool IntervalTimer::intervalComplete() {
if (millis() - _timestamp >= _interval) {
_timestamp += _interval;
return true;
}
return false;
}
void IntervalTimer::setInterval(unsigned long i) {
_interval = i;
}
unsigned long IntervalTimer::elapsedTime() {
unsigned long x = millis() - _timestamp;
return x;
}
PushButton::PushButton(int pinNumber, unsigned long debounceTime) : _timer(debounceTime), _ButtonPin(pinNumber) { }
void PushButton::inputPullup() const {
pinMode(_ButtonPin, INPUT_PULLUP);
}
bool PushButton::isPushed() {
bool b = false;
if (_debounceFlag == 1) {
if (_timer.intervalComplete()) _debounceFlag = 0;
}
else {
int sample = digitalRead(_ButtonPin);
int state = sample - _preState;
if (state == _FallingEdge) {
_timer.synchronizeTimer();
b = true;
_debounceFlag = 1;
}
else if (state == _RisingEdge) {
_timer.synchronizeTimer();
_debounceFlag = 1;
}
_preState = sample;
}
return b;
}
unsigned long PushButton::durationHeld() {
unsigned long u = 0;
if (_preState == LOW) {
u = _timer.elapsedTime();
if (u == 0) u = 1;
}
return u;
}
void PushButton::setDebounce(unsigned long i) {
_timer.setInterval(i);
}
const int ButtonPin = 8;
const int LedPin = LED_BUILTIN;
unsigned char onOffFlag;
unsigned char blinkerBit;
PushButton Button(ButtonPin, 50UL);
IntervalTimer BlinkTimer(500UL);
void setup() {
Button.inputPullup();
pinMode(LedPin, OUTPUT);
}
void loop() {
if (onOffFlag > 0) {
if (Button.isPushed()) {
blinkerBit = onOffFlag = 0;
digitalWrite(LedPin, LOW);
}
else if (BlinkTimer.intervalComplete()) {
blinkerBit ^= 1;
(blinkerBit > 0) ? digitalWrite(LedPin, HIGH) : digitalWrite(LedPin, LOW);
}
}
else {
if (Button.isPushed()) {
BlinkTimer.synchronizeTimer();
blinkerBit = onOffFlag = 1;
digitalWrite(LedPin, HIGH);
}
}
}
The Pin assignment is around line 98.
To help with the debounce, I suggest the following push-button circuit.