-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathBlinkSlowFastManualRoutine.ino
183 lines (157 loc) · 4.59 KB
/
BlinkSlowFastManualRoutine.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
/*
* This sketch is the same as BlinkSlowFastRoutine except that it uses custom
* Coroutine classes. The custom classes are able to support additional
* variables and methods which allow the coroutines to communicate with each
* other.
*/
#include <Arduino.h>
#include <AceRoutine.h>
using namespace ace_routine;
#ifdef LED_BUILTIN
const int LED = LED_BUILTIN;
#else
// Some ESP32 boards do not define LED_BUILTIN. Sometimes they have more than
// 1. Replace this with the proper pin number.
const int LED = 5;
#endif
// Replace with the pin of your button.
const int BUTTON_PIN = 2;
// If the LED of your board is wired in reverse, flip these values.
const int LED_ON = HIGH;
const int LED_OFF = LOW;
/** A coroutine that blinks the LED fast. */
class BlinkFastCoroutine : public Coroutine {
public:
void enable(bool enable) { enabled = enable; }
int runCoroutine() override {
COROUTINE_LOOP() {
if (enabled) {
Serial.print("F1 ");
digitalWrite(LED, LED_ON);
COROUTINE_DELAY(200);
Serial.print("F1a ");
Serial.print("F0 ");
digitalWrite(LED, LED_OFF);
COROUTINE_DELAY(200);
Serial.print("F0a ");
} else {
Serial.print("F ");
COROUTINE_DELAY(400);
}
}
}
private:
bool enabled = false;
};
/** A coroutine that blinks the LED slowly. */
class BlinkSlowCoroutine : public Coroutine {
public:
void enable(bool enable) { enabled = enable; }
int runCoroutine() override {
COROUTINE_LOOP() {
if (enabled) {
digitalWrite(LED, LED_ON);
Serial.print("S1 ");
COROUTINE_DELAY(500);
Serial.print("S1a ");
Serial.print("S0 ");
digitalWrite(LED, LED_OFF);
COROUTINE_DELAY(500);
Serial.print("S0a ");
} else {
Serial.print("S ");
COROUTINE_DELAY(1000);
}
}
}
private:
bool enabled = false;
};
/**
* A coroutine that reads a digitalRead(), performs a primitive debouncing
* by waiting 20 ms in a non-blocking manner, so that the other coroutines
* continue to run while waiting. Clicking on a button (BUTTON_PIN) cycles
* through the LED blinking pattern:
*
* * Blink both
* * Blink fast only
* * Blink slow only
*
* You probably shouldn't use a button debouncing code like this in your real
* project. Consider using https://github.com/bxparks/AceButton instead.
*/
class ButtonCoroutine : public Coroutine {
public:
ButtonCoroutine(
BlinkFastCoroutine& blinkFastCoroutine,
BlinkSlowCoroutine& blinkSlowCoroutine
):
blinkFast(blinkFastCoroutine),
blinkSlow(blinkSlowCoroutine)
{}
int runCoroutine() override {
COROUTINE_BEGIN();
configureBlinkers();
COROUTINE_YIELD();
while (true) {
buttonState = digitalRead(BUTTON_PIN);
if (prevButtonState == HIGH && buttonState == LOW) {
// primitive debouncing
COROUTINE_DELAY(20);
buttonState = digitalRead(BUTTON_PIN);
if (prevButtonState == HIGH && buttonState == LOW) {
blinkState++;
if (blinkState >= 3) {
blinkState = 0;
}
configureBlinkers();
}
}
prevButtonState = buttonState;
COROUTINE_DELAY(20);
}
COROUTINE_END();
}
protected:
static const int BLINK_STATE_SLOW = 0;
static const int BLINK_STATE_FAST = 1;
static const int BLINK_STATE_BOTH = 2;
void configureBlinkers() {
if (blinkState == BLINK_STATE_BOTH) {
Serial.println("both");
blinkFast.enable(true);
blinkSlow.enable(true);
} else if (blinkState == BLINK_STATE_FAST) {
Serial.println("fast");
blinkSlow.enable(false);
blinkFast.enable(true);
} else if (blinkState == BLINK_STATE_SLOW) {
Serial.println("slow");
blinkSlow.enable(true);
blinkFast.enable(false);
}
}
private:
BlinkFastCoroutine& blinkFast;
BlinkSlowCoroutine& blinkSlow;
int buttonState = HIGH;
int prevButtonState = HIGH;
int blinkState = BLINK_STATE_BOTH;
};
// Create instances of the coroutines, and hook them up
BlinkFastCoroutine blinkFast;
BlinkSlowCoroutine blinkSlow;
ButtonCoroutine buttonCoroutine(blinkFast, blinkSlow);
void setup() {
#if ! defined(EPOXY_DUINO)
delay(1000);
#endif
Serial.begin(115200);
while (!Serial); // Leonardo/Micro
pinMode(LED, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
CoroutineScheduler::setup();
}
void loop() {
CoroutineScheduler::loop();
}