// https://forum.arduino.cc/t/solved-blinking-indicators/1327297
// https://wokwi.com/projects/416041824859474945
#include "proto_activities.h"
// activities
pa_activity (ButtonRecognizer, pa_ctx_tm(), int pin, bool& was_pressed, bool& was_released) {
pinMode(pin, INPUT_PULLUP);
pa_repeat {
pa_await (digitalRead(pin) == LOW);
was_pressed = true;
pa_pause;
was_pressed = false;
pa_delay_ms (20); // debounce button press
pa_await (digitalRead(pin) == HIGH);
was_released = true;
pa_pause;
was_released = false;
pa_delay_ms (20); // debounce button release
}
} pa_end
pa_activity (Blink, pa_ctx_tm(), bool& show) {
pa_every_ms (500) {
show = !show;
} pa_every_end
} pa_end
pa_activity (Delay_s, pa_ctx_tm(), int s) {
pa_delay_s(s);
} pa_end
pa_activity (StateMachine, pa_ctx_tm(pa_use(Blink); pa_use(Delay_s)), bool was_pressed, bool was_released, bool& show) {
pa_repeat {
// Phase 1
if (!was_pressed) {
pa_when_abort (was_pressed, Blink, show);
}
// Phase 2
show = true;
pa_await (was_released);
// Phase 3
show = false;
pa_when_abort (was_pressed, Delay_s, 3);
}
} pa_end
pa_activity (Indicator, pa_ctx(), int pin, bool show) {
pinMode(pin, OUTPUT);
pa_always {
digitalWrite(pin, show);
} pa_always_end
} pa_end
pa_activity (Handler, pa_ctx(pa_co_res(3); pa_use(ButtonRecognizer); pa_use(StateMachine); pa_use(Indicator); bool was_pressed; bool was_released; bool show),
int button, int indicator) {
pa_co(3) {
pa_with (ButtonRecognizer, button, pa_self.was_pressed, pa_self.was_released);
pa_with (StateMachine, pa_self.was_pressed, pa_self.was_released, pa_self.show);
pa_with (Indicator, indicator, pa_self.show);
} pa_co_end
} pa_end
pa_activity (Main, pa_ctx(pa_co_res(2); pa_use_as(Handler, H1); pa_use_as(Handler, H2))) {
pa_co(2) {
pa_with_as (Handler, H1, 4, 11);
pa_with_as (Handler, H2, 3, 10);
} pa_co_end
} pa_end
pa_use(Main);
// setup and loop
void setup() {
Serial.begin(115200);
setupA7();
}
void loop() {
pa_tick(Main);
delay(10); // ??
loopA7();
}
const int indicator = A0;
const int myBuuton = A1;
//...
enum {PHASE0 = 0, PHASE1, PHASE2};
char *tags[] = {"phase zero", "phase one", "phase two", };
int thePhase = PHASE0;
bool butStateCur = true;
bool butStatePre;
bool ledOn;
unsigned long millisPre = 0;
unsigned long millisCur;
unsigned long phaseStart;
const int phaseDelay = 3000; // delay for phase to timeout
void setupA7() {
// Serial.begin(115200);
Serial.println("\nJello Whirled!\n");
pinMode(indicator, OUTPUT);
pinMode(myBuuton, INPUT_PULLUP);
butStatePre = digitalRead(myBuuton) == LOW;
}
void loopA7() {
millisCur = millis();
//... let us do our own switch handling
bool buttonPressed = false; // until proven otherwise
butStateCur = digitalRead(myBuuton) == LOW;
if (butStatePre != butStateCur) {
if (butStateCur)
buttonPressed = true;
delay(20); // debounce
}
butStatePre = butStateCur;
//...
switch (thePhase) {
case PHASE0 :
ledOn = (millis() / 500) % 2;
if (buttonPressed) {
ledOn = true;
thePhase = PHASE1;
}
break;
case PHASE1 :
if (buttonPressed) {
ledOn = false;
thePhase = PHASE2;
phaseStart = millisCur;
}
break;
case PHASE2 :
// if (buttonPressed) thePhase = PHASE0; // should the button cut short PHASE2?
if (millisCur - phaseStart > phaseDelay) {
thePhase = PHASE0;
}
break;
}
digitalWrite(indicator, ledOn ? HIGH : LOW); // C/C++ ternary operator
static int printedPhase = -1; // no it does not!
if (printedPhase != thePhase) {
Serial.print("entered ");
Serial.println(tags[thePhase]);
printedPhase = thePhase;
}
}
alto777