arduino-audio-tools
Loading...
Searching...
No Matches
AudioActions.h
Go to the documentation of this file.
1#pragma once
2
7
8#ifndef TOUCH_LIMIT
9#define TOUCH_LIMIT 20
10#endif
11
12#ifndef DEBOUNCE_DELAY
13#define DEBOUNCE_DELAY 500
14#endif
15
16namespace audio_tools {
17
18#if defined(IS_MIN_DESKTOP)
19extern void pinMode(int, int);
20extern int digitalRead(int);
21#endif
22
23
30 public:
38
40 struct Action {
41 Action() = default;
42 virtual ~Action() {}
44 void (*actionOn)(bool pinStatus, digital_pin_t pin, void* ref) = nullptr;
45 void (*actionOff)(bool pinStatus, digital_pin_t pin, void* ref) = nullptr;
46 void* ref = nullptr;
47 unsigned long debounceTimeout = 0;
49 bool lastState = true;
50 bool enabled = true;
51
55 bool (*read_cb)(digital_pin_t, void*) = nullptr;
56 void* read_cb_ref = nullptr;
57
58 // public methods
59 virtual int id() { return GPIO_TO_INT(pin); }
60 virtual bool readValue() {
61#if defined(USE_TOUCH_READ)
62 bool result;
63 if (this->activeLogic == ActiveTouch) {
64 int value = touchRead(this->pin);
65 result = value <= touchLimit;
66 if (result) {
67 // retry to confirm reading
68 value = touchRead(this->pin);
69 result = value <= touchLimit;
70 LOGI("touch pin: %d value %d (limit: %d) -> %s", this->pin, value,
71 touchLimit, result ? "true" : "false");
72 }
73 } else {
74 result = readPin(this->pin);
75 }
76 return result;
77#else
78 return this->readPin(this->pin);
79#endif
80 }
81
82 virtual void process() {
83 if (this->enabled) {
84 bool value = readValue();
85 if (this->actionOn != nullptr && this->actionOff != nullptr) {
86 // we have on and off action defined
87 if (value != this->lastState) {
88 // LOGI("processActions: case with on and off");
89 // execute action -> reports active instead of pin state
90 if ((value && this->activeLogic == ActiveHigh) ||
91 (!value && this->activeLogic == ActiveLow)) {
92 this->actionOn(true, this->pin, this->ref);
93 } else {
94 this->actionOff(false, this->pin, this->ref);
95 }
96 this->lastState = value;
97 }
98 } else if (this->activeLogic == ActiveChange) {
99 bool active = value;
100 if (value != this->lastState && millis() > this->debounceTimeout) {
101 if (this->actionOn != nullptr)
102 this->actionOn(active, this->pin, this->ref);
103 this->lastState = value;
104 this->debounceTimeout = millis() + debounceDelayValue;
105 }
106 } else {
107 bool active = (this->activeLogic == ActiveLow) ? !value : value;
108 if (active &&
109 (active != this->lastState || millis() > this->debounceTimeout)) {
110 if (this->actionOn != nullptr)
111 this->actionOn(active, this->pin, this->ref);
112 this->lastState = active;
113 this->debounceTimeout = millis() + debounceDelayValue;
114 }
115 }
116 }
117 }
118
119 protected:
121 if (read_cb) {
122 return read_cb(pin, read_cb_ref);
123 } else {
124 return (bool)::digitalRead(pin);
125 }
126 }
127 };
128
134
136 virtual ~AudioActions() { clear(); }
137
140
143 void (*actionOn)(bool pinStatus, digital_pin_t pin, void* ref),
144 ActiveLogic activeLogic = ActiveLow, void* ref = nullptr) {
145 add(pin, actionOn, nullptr, activeLogic, ref);
146 }
147
150 void (*actionOn)(bool pinStatus, digital_pin_t pin, void* ref),
151 void (*actionOff)(bool pinStatus, digital_pin_t pin, void* ref),
152 ActiveLogic activeLogicPar = ActiveLow, void* ref = nullptr) {
153 LOGI("ActionLogic::add pin: %d / logic: %d", GPIO_TO_INT(pin),
155
156 if (pin != GPIO_NONE) {
157 // setup pin mode
159
160 // add value
161 Action* p_action = new Action();
162 if (p_action == nullptr) {
163 LOGE("Failed to allocate Action for pin %d", GPIO_TO_INT(pin));
164 return;
165 }
166 p_action->pin = pin;
167 p_action->actionOn = actionOn;
168 p_action->actionOff = actionOff;
169 p_action->activeLogic = activeLogicPar;
170 p_action->ref = ref;
171 p_action->debounceDelayValue = debounceDelayValue;
172 p_action->touchLimit = touchLimit;
173 p_action->read_cb = read_cb;
174 p_action->read_cb_ref = read_cb_ref;
175
177 } else {
178 LOGW("pin %d -> Ignored", GPIO_TO_INT(pin));
179 }
180 }
181
183 void setEnabled(digital_pin_t pin, bool enabled) {
185 if (p_action) {
186 p_action->enabled = enabled;
187 }
188 }
189
197 if (actions.empty()) return;
198 if (use_pin_interrupt) {
199 if (!interrupt_pending) return;
200 interrupt_pending = false;
202 } else {
203 static int pos = 0;
204 auto action = actions[pos];
205 if (action != nullptr && action->enabled) action->process();
206 pos++;
207 if (pos >= actions.size()) {
208 pos = 0;
209 }
210 }
211 }
212
215 for (Action* action : actions) {
216 if (action == nullptr || !action->enabled) continue;
217 action->process();
218 }
219 }
220
223 for (Action* action : actions) {
224 if (action != nullptr && action->id() == id) {
225 return action;
226 }
227 }
228 return nullptr;
229 }
230
232 for (Action* action : actions) {
233 if (action != nullptr && action->pin == pin) {
234 return action;
235 }
236 }
237 return nullptr;
238 }
239
241 int findActionIdx(int id) {
242 int pos = 0;
243 for (Action* action : actions) {
244 if (action == nullptr) continue;
245 if (action->id() == id) {
246 return pos;
247 }
248 pos++;
249 }
250 return -1;
251 }
252
254 void setDebounceDelay(int value) { debounceDelayValue = value; }
256 void setTouchLimit(int value) { touchLimit = value; }
258 void setUsePinInterrupt(bool active) {
259 use_pin_interrupt = active;
260 for (Action* action : actions) {
261 if (action == nullptr) continue;
263 }
264 }
266 void setPinMode(bool active) { use_pin_mode = active; }
267
268 void clear() {
269 for (Action* act : actions) {
270 delete (act);
271 }
272 actions.reset();
273 }
274
277 void* ref = nullptr) {
279 read_cb_ref = ref;
280 }
281
282 protected:
283 inline static AudioActions* selfAudioActions = nullptr;
286 bool use_pin_interrupt = false;
287 bool use_pin_mode = true;
288 volatile bool interrupt_pending = false;
290 bool (*read_cb)(digital_pin_t, void*) = nullptr;
291 void* read_cb_ref = nullptr;
292
294 if (p == nullptr) {
295 LOGE("insertAction: refusing to add nullptr");
296 return;
297 }
298 int idx = findActionIdx(p->id());
299 if (idx >= 0) {
300 delete (actions[idx]);
301 actions[idx] = p;
302 } else {
303 actions.push_back(p);
304 }
305 }
306
307#if defined(IS_ZEPHYR)
309
310 static void audioActionsISRZephyr(const struct device* dev,
311 struct gpio_callback* cb, uint32_t pins) {
312 (void)dev;
313 (void)cb;
314 (void)pins;
315 if (selfAudioActions != nullptr)
317 }
318
323 int ret;
324
326 if (ret != 0) {
327 LOGE("Error %d: failed to enable interrupt", ret);
328 return;
329 }
330
332
334 }
335#else
336 static void audioActionsISR() {
337 if (selfAudioActions != nullptr)
339 }
340
341#endif
342
344 if (!use_pin_interrupt) return;
345#if defined(ARDUINO) && (!defined(IS_MIN_DESKTOP) && !defined(IS_DESKTOP))
347#elif defined(IS_ZEPHYR)
348 setupISR(pin);
349#endif
350 }
351
353 if (use_pin_mode) {
354 if (logic == ActiveLow) {
355 pinMode(pin, INPUT_PULLUP);
356 LOGI("pin %d -> INPUT_PULLUP", GPIO_TO_INT(pin));
357 } else {
358 pinMode(pin, INPUT);
359 LOGI("pin %d -> INPUT", GPIO_TO_INT(pin));
360 }
361 }
362 setupInterrupt(pin);
363 }
364};
365
366} // namespace audio_tools
#define INPUT
Definition Arduino.h:34
#define INPUT_PULLUP
Definition Arduino.h:42
#define GPIO_TO_INT(pin)
Definition Arduino.h:249
#define DEBOUNCE_DELAY
Definition AudioActions.h:13
#define TOUCH_LIMIT
Definition AudioActions.h:9
#define LOGW(...)
Definition AudioLoggerIDF.h:29
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGE(...)
Definition AudioLoggerIDF.h:30
A simple class to assign functions to gpio pins e.g. to implement a simple navigation control or volu...
Definition AudioActions.h:29
int findActionIdx(int id)
Determines the action for the pin/id.
Definition AudioActions.h:241
ActiveLogic
Defines the logic for the action execution.
Definition AudioActions.h:32
@ ActiveTouch
Definition AudioActions.h:36
@ ActiveLow
Definition AudioActions.h:33
@ ActiveHigh
Definition AudioActions.h:34
@ ActiveChange
Definition AudioActions.h:35
int debounceDelayValue
Definition AudioActions.h:284
AudioActions(bool useInterrupt=false)
Default constructor.
Definition AudioActions.h:130
static void audioActionsISRZephyr(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
Definition AudioActions.h:310
static AudioActions * selfAudioActions
Definition AudioActions.h:283
void setTouchLimit(int value)
Defines the touch limit (Default 20)
Definition AudioActions.h:256
void add(digital_pin_t pin, void(*actionOn)(bool pinStatus, digital_pin_t pin, void *ref), void(*actionOff)(bool pinStatus, digital_pin_t pin, void *ref), ActiveLogic activeLogicPar=ActiveLow, void *ref=nullptr)
Adds an action.
Definition AudioActions.h:149
void setupInterrupt(digital_pin_t pin)
Definition AudioActions.h:343
virtual ~AudioActions()
deletes all actions
Definition AudioActions.h:136
void setupPin(digital_pin_t pin, ActiveLogic logic)
Definition AudioActions.h:352
volatile bool interrupt_pending
Definition AudioActions.h:288
void setEnabled(digital_pin_t pin, bool enabled)
enable/disable pin actions
Definition AudioActions.h:183
void setDebounceDelay(int value)
Defines the debounce delay.
Definition AudioActions.h:254
bool use_pin_interrupt
Definition AudioActions.h:286
void insertAction(Action *p)
Definition AudioActions.h:293
void processActions()
Execute all actions if the corresponding pin is low. To minimize the runtime: With each call we proce...
Definition AudioActions.h:196
void add(Action &action)
Adds an Action.
Definition AudioActions.h:139
void setReadCallback(bool(*read_cb_par)(digital_pin_t, void *), void *ref=nullptr)
Sets a callback function to read the pin state.
Definition AudioActions.h:276
void processAllActions()
Execute all actions.
Definition AudioActions.h:214
bool use_pin_mode
Definition AudioActions.h:287
void setupISR(digital_pin_t button)
Setup GPIO interrupt for a given pin.
Definition AudioActions.h:322
int touchLimit
Definition AudioActions.h:285
void clear()
Definition AudioActions.h:268
Vector< Action * > actions
Definition AudioActions.h:289
void setUsePinInterrupt(bool active)
Use interrupts instead of processActions() call in loop.
Definition AudioActions.h:258
bool(* read_cb)(digital_pin_t, void *)
Definition AudioActions.h:290
void * read_cb_ref
Definition AudioActions.h:291
Action * findActionByPin(digital_pin_t pin)
Definition AudioActions.h:231
static struct gpio_callback button_cb_data
Definition AudioActions.h:308
Action * findActionById(int id)
Determines the action for the pin/id.
Definition AudioActions.h:222
void add(digital_pin_t pin, void(*actionOn)(bool pinStatus, digital_pin_t pin, void *ref), ActiveLogic activeLogic=ActiveLow, void *ref=nullptr)
Adds an action.
Definition AudioActions.h:142
void setPinMode(bool active)
setup pin mode when true
Definition AudioActions.h:266
Vector implementation which provides the most important methods as defined by std::vector....
Definition Vector.h:21
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
gpio_dt_spec digital_pin_t
Zephyr GPIO spec as digital_pin_t.
Definition Arduino.h:266
static gpio_dt_spec GPIO_NONE
GPIO_NONE is no pin defined.
Definition Arduino.h:269
void pinMode(digital_pin_t pin, int mode)
Definition Arduino.h:282
int digitalRead(digital_pin_t pin)
Definition Arduino.h:324
uint32_t millis()
Returns the milliseconds since the start.
Definition Arduino.h:256
size_t writeData(Print *p_out, T *data, int samples, int maxSamples=512)
Definition AudioTypes.h:508
Action definition per pin.
Definition AudioActions.h:40
ActiveLogic activeLogic
Definition AudioActions.h:48
void * ref
Definition AudioActions.h:46
int debounceDelayValue
determines the value for the action
Definition AudioActions.h:53
digital_pin_t pin
Definition AudioActions.h:43
bool lastState
Definition AudioActions.h:49
bool readPin(digital_pin_t pin)
Definition AudioActions.h:120
virtual void process()
Definition AudioActions.h:82
void(* actionOn)(bool pinStatus, digital_pin_t pin, void *ref)
Definition AudioActions.h:44
unsigned long debounceTimeout
Definition AudioActions.h:47
bool enabled
Definition AudioActions.h:50
virtual int id()
Definition AudioActions.h:59
int touchLimit
Definition AudioActions.h:54
virtual ~Action()
Definition AudioActions.h:42
void(* actionOff)(bool pinStatus, digital_pin_t pin, void *ref)
Definition AudioActions.h:45
bool(* read_cb)(digital_pin_t, void *)
Definition AudioActions.h:55
void * read_cb_ref
Definition AudioActions.h:56
virtual bool readValue()
Definition AudioActions.h:60