Skip to content

Commit 2da5088

Browse files
committed
✨ feat: add vibration feedback support for UI events
- Add genericVibration class with 5-second cooldown and 1-second pulse - Integrate vibration triggers for new messages and contact discoveries - Add conditional compilation support with PIN_VIBRATION guard - Implement abstract interface for vibration in UITask system
1 parent d86851b commit 2da5088

File tree

6 files changed

+112
-0
lines changed

6 files changed

+112
-0
lines changed

examples/companion_radio/AbstractUITask.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,8 @@ class AbstractUITask {
4242
virtual void msgRead(int msgcount) = 0;
4343
virtual void newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount) = 0;
4444
virtual void soundBuzzer(UIEventType bet = UIEventType::none) = 0;
45+
#ifdef PIN_VIBRATION
46+
virtual void triggerVibration() = 0;
47+
#endif
4548
virtual void loop() = 0;
4649
};

examples/companion_radio/MyMesh.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,11 @@ void MyMesh::onDiscoveredContact(ContactInfo &contact, bool is_new, uint8_t path
244244
} else {
245245
#ifdef DISPLAY_CLASS
246246
if (_ui) _ui->soundBuzzer(UIEventType::newContactMessage);
247+
if (_ui) {
248+
#ifdef PIN_VIBRATION
249+
if (is_new) _ui->triggerVibration();
250+
#endif
251+
}
247252
#endif
248253
}
249254

examples/companion_radio/ui-new/UITask.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,10 @@ void UITask::begin(DisplayDriver* display, SensorManager* sensors, NodePrefs* no
483483
buzzer.begin();
484484
#endif
485485

486+
#ifdef PIN_VIBRATION
487+
vibration.begin();
488+
#endif
489+
486490
ui_started_at = millis();
487491
_alert_expiry = 0;
488492

@@ -519,6 +523,12 @@ switch(bet){
519523
#endif
520524
}
521525

526+
#ifdef PIN_VIBRATION
527+
void UITask::triggerVibration() {
528+
vibration.trigger();
529+
}
530+
#endif
531+
522532
void UITask::msgRead(int msgcount) {
523533
_msgcount = msgcount;
524534
if (msgcount == 0) {
@@ -532,6 +542,10 @@ void UITask::newMsg(uint8_t path_len, const char* from_name, const char* text, i
532542
((MsgPreviewScreen *) msg_preview)->addPreview(path_len, from_name, text);
533543
setCurrScreen(msg_preview);
534544

545+
#ifdef PIN_VIBRATION
546+
triggerVibration();
547+
#endif
548+
535549
if (_display != NULL) {
536550
if (!_display->isOn()) _display->turnOn();
537551
_auto_off = millis() + AUTO_OFF_MILLIS; // extend the auto-off timer
@@ -687,6 +701,10 @@ void UITask::loop() {
687701
#endif
688702
}
689703

704+
#ifdef PIN_VIBRATION
705+
vibration.loop();
706+
#endif
707+
690708
#ifdef AUTO_SHUTDOWN_MILLIVOLTS
691709
if (millis() > next_batt_chck) {
692710
uint16_t milliVolts = getBattMilliVolts();

examples/companion_radio/ui-new/UITask.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
#ifdef PIN_BUZZER
1212
#include <helpers/ui/buzzer.h>
1313
#endif
14+
#ifdef PIN_VIBRATION
15+
#include <helpers/ui/vibration.h>
16+
#endif
1417

1518
#include "../AbstractUITask.h"
1619
#include "../NodePrefs.h"
@@ -20,6 +23,9 @@ class UITask : public AbstractUITask {
2023
SensorManager* _sensors;
2124
#ifdef PIN_BUZZER
2225
genericBuzzer buzzer;
26+
#endif
27+
#ifdef PIN_VIBRATION
28+
genericVibration vibration;
2329
#endif
2430
unsigned long _next_refresh, _auto_off;
2531
NodePrefs* _node_prefs;
@@ -72,6 +78,9 @@ class UITask : public AbstractUITask {
7278
void msgRead(int msgcount) override;
7379
void newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount) override;
7480
void soundBuzzer(UIEventType bet = UIEventType::none) override;
81+
#ifdef PIN_VIBRATION
82+
void triggerVibration() override;
83+
#endif
7584
void loop() override;
7685

7786
void shutdown(bool restart = false);

src/helpers/ui/vibration.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#ifdef PIN_VIBRATION
2+
#include "vibration.h"
3+
4+
void genericVibration::begin()
5+
{
6+
pinMode(PIN_VIBRATION, OUTPUT);
7+
digitalWrite(PIN_VIBRATION, LOW);
8+
duration = 0;
9+
}
10+
11+
void genericVibration::trigger()
12+
{
13+
duration = millis();
14+
digitalWrite(PIN_VIBRATION, HIGH);
15+
}
16+
17+
void genericVibration::loop()
18+
{
19+
if (isVibrating()) {
20+
if ((millis() / 1000) % 2 == 0) {
21+
digitalWrite(PIN_VIBRATION, LOW);
22+
} else {
23+
digitalWrite(PIN_VIBRATION, HIGH);
24+
}
25+
26+
if (millis() - duration > VIBRATION_TIMEOUT) {
27+
stop();
28+
}
29+
}
30+
}
31+
32+
bool genericVibration::isVibrating()
33+
{
34+
return duration > 0;
35+
}
36+
37+
void genericVibration::stop()
38+
{
39+
duration = 0;
40+
digitalWrite(PIN_VIBRATION, LOW);
41+
}
42+
43+
#endif // ifdef PIN_VIBRATION

src/helpers/ui/vibration.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#pragma once
2+
3+
#ifdef PIN_VIBRATION
4+
5+
#include <Arduino.h>
6+
7+
/*
8+
* Vibration motor control class
9+
*
10+
* Provides vibration feedback for events like new messages and new contacts
11+
* Features:
12+
* - 1-second vibration pulse
13+
* - 5-second nag timeout (cooldown between vibrations)
14+
* - Non-blocking operation
15+
*/
16+
17+
#ifndef VIBRATION_TIMEOUT
18+
#define VIBRATION_TIMEOUT 5000 // 5 seconds default
19+
#endif
20+
21+
class genericVibration
22+
{
23+
public:
24+
void begin(); // set up vibration pin
25+
void trigger(); // trigger vibration if cooldown has passed
26+
void loop(); // non-blocking timer handling
27+
bool isVibrating(); // returns true if currently vibrating
28+
void stop(); // stop vibration immediately
29+
30+
private:
31+
unsigned long duration;
32+
};
33+
34+
#endif // ifdef PIN_VIBRATION

0 commit comments

Comments
 (0)