Преглед изворни кода

✨ 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
csrutil пре 11 месеци
родитељ
комит
2da50882c0

+ 3 - 0
examples/companion_radio/AbstractUITask.h

@@ -42,5 +42,8 @@ public:
   virtual void msgRead(int msgcount) = 0;
   virtual void newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount) = 0;
   virtual void soundBuzzer(UIEventType bet = UIEventType::none) = 0;
+#ifdef PIN_VIBRATION
+  virtual void triggerVibration() = 0;
+#endif
   virtual void loop() = 0;
 };

+ 5 - 0
examples/companion_radio/MyMesh.cpp

@@ -244,6 +244,11 @@ void MyMesh::onDiscoveredContact(ContactInfo &contact, bool is_new, uint8_t path
   } else {
 #ifdef DISPLAY_CLASS
     if (_ui) _ui->soundBuzzer(UIEventType::newContactMessage);
+    if (_ui) {
+#ifdef PIN_VIBRATION
+      if (is_new) _ui->triggerVibration();
+#endif
+    }
 #endif
   }
 

+ 18 - 0
examples/companion_radio/ui-new/UITask.cpp

@@ -483,6 +483,10 @@ void UITask::begin(DisplayDriver* display, SensorManager* sensors, NodePrefs* no
   buzzer.begin();
 #endif
 
+#ifdef PIN_VIBRATION
+  vibration.begin();
+#endif
+
   ui_started_at = millis();
   _alert_expiry = 0;
 
@@ -519,6 +523,12 @@ switch(bet){
 #endif
 }
 
+#ifdef PIN_VIBRATION
+void UITask::triggerVibration() {
+  vibration.trigger();
+}
+#endif
+
 void UITask::msgRead(int msgcount) {
   _msgcount = msgcount;
   if (msgcount == 0) {
@@ -532,6 +542,10 @@ void UITask::newMsg(uint8_t path_len, const char* from_name, const char* text, i
   ((MsgPreviewScreen *) msg_preview)->addPreview(path_len, from_name, text);
   setCurrScreen(msg_preview);
 
+#ifdef PIN_VIBRATION
+  triggerVibration();
+#endif
+
   if (_display != NULL) {
     if (!_display->isOn()) _display->turnOn();
     _auto_off = millis() + AUTO_OFF_MILLIS;  // extend the auto-off timer
@@ -687,6 +701,10 @@ void UITask::loop() {
 #endif
   }
 
+#ifdef PIN_VIBRATION
+  vibration.loop();
+#endif
+
 #ifdef AUTO_SHUTDOWN_MILLIVOLTS
   if (millis() > next_batt_chck) {
     uint16_t milliVolts = getBattMilliVolts();

+ 9 - 0
examples/companion_radio/ui-new/UITask.h

@@ -11,6 +11,9 @@
 #ifdef PIN_BUZZER
   #include <helpers/ui/buzzer.h>
 #endif
+#ifdef PIN_VIBRATION
+  #include <helpers/ui/vibration.h>
+#endif
 
 #include "../AbstractUITask.h"
 #include "../NodePrefs.h"
@@ -20,6 +23,9 @@ class UITask : public AbstractUITask {
   SensorManager* _sensors;
 #ifdef PIN_BUZZER
   genericBuzzer buzzer;
+#endif
+#ifdef PIN_VIBRATION
+  genericVibration vibration;
 #endif
   unsigned long _next_refresh, _auto_off;
   NodePrefs* _node_prefs;
@@ -72,6 +78,9 @@ public:
   void msgRead(int msgcount) override;
   void newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount) override;
   void soundBuzzer(UIEventType bet = UIEventType::none) override;
+#ifdef PIN_VIBRATION
+  void triggerVibration() override;
+#endif
   void loop() override;
 
   void shutdown(bool restart = false);

+ 43 - 0
src/helpers/ui/vibration.cpp

@@ -0,0 +1,43 @@
+#ifdef PIN_VIBRATION
+#include "vibration.h"
+
+void genericVibration::begin()
+{
+    pinMode(PIN_VIBRATION, OUTPUT);
+    digitalWrite(PIN_VIBRATION, LOW);
+    duration = 0;
+}
+
+void genericVibration::trigger()
+{
+    duration = millis();
+    digitalWrite(PIN_VIBRATION, HIGH);
+}
+
+void genericVibration::loop()
+{
+    if (isVibrating()) {
+        if ((millis() / 1000) % 2 == 0) {
+            digitalWrite(PIN_VIBRATION, LOW);
+        } else {
+            digitalWrite(PIN_VIBRATION, HIGH);
+        }
+
+        if (millis() - duration > VIBRATION_TIMEOUT) {
+            stop();
+        }
+    }
+}
+
+bool genericVibration::isVibrating()
+{
+    return duration > 0;
+}
+
+void genericVibration::stop()
+{
+    duration = 0;
+    digitalWrite(PIN_VIBRATION, LOW);
+}
+
+#endif // ifdef PIN_VIBRATION

+ 34 - 0
src/helpers/ui/vibration.h

@@ -0,0 +1,34 @@
+#pragma once
+
+#ifdef PIN_VIBRATION
+
+#include <Arduino.h>
+
+/*
+ * Vibration motor control class
+ *
+ * Provides vibration feedback for events like new messages and new contacts
+ * Features:
+ * - 1-second vibration pulse
+ * - 5-second nag timeout (cooldown between vibrations)
+ * - Non-blocking operation
+ */
+
+#ifndef VIBRATION_TIMEOUT
+#define VIBRATION_TIMEOUT 5000  // 5 seconds default
+#endif
+
+class genericVibration
+{
+  public:
+    void begin();       // set up vibration pin
+    void trigger();     // trigger vibration if cooldown has passed
+    void loop();        // non-blocking timer handling
+    bool isVibrating(); // returns true if currently vibrating
+    void stop();        // stop vibration immediately
+
+  private:
+    unsigned long duration;
+};
+
+#endif // ifdef PIN_VIBRATION