Browse Source

Merge 275d85d155 into adc631f315

pull/2665/merge
Mark Jocas 16 hours ago
committed by GitHub
parent
commit
f03ec5677c
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 11
      docs/faq.md
  2. 4
      examples/companion_radio/AbstractUITask.h
  3. 20
      examples/companion_radio/ui-new/UITask.cpp
  4. 1
      examples/companion_radio/ui-new/UITask.h
  5. 20
      examples/companion_radio/ui-orig/UITask.cpp
  6. 1
      examples/companion_radio/ui-orig/UITask.h
  7. 20
      examples/companion_radio/ui-tiny/UITask.cpp
  8. 1
      examples/companion_radio/ui-tiny/UITask.h
  9. 15
      src/helpers/ui/buzzer.cpp
  10. 1
      src/helpers/ui/buzzer.h

11
docs/faq.md

@ -65,6 +65,7 @@ A list of frequently-asked questions and answers for MeshCore
- [5.14. Q: Are there projects built around MeshCore?](#514-q-are-there-projects-built-around-meshcore)
- [5.15. Q: Are there client applications for Windows or Mac?](#515-q-are-there-client-applications-for-windows-or-mac)
- [5.16. Q: Are there any resources that compare MeshCore to other LoRa systems?](#516-q-are-there-any-resources-that-compare-meshcore-to-other-lora-systems)
- [5.17. Q: What do the buzzer tones on my companion radio mean?](#517-q-what-do-the-buzzer-tones-on-my-companion-radio-mean)
- [6. Troubleshooting](#6-troubleshooting)
- [6.1. Q: My client says another client or a repeater or a room server was last seen many, many days ago.](#61-q-my-client-says-another-client-or-a-repeater-or-a-room-server-was-last-seen-many-many-days-ago)
- [6.2. Q: A repeater or a client or a room server I expect to see on my discover list (on T-Deck) or contact list (on a smart device client) are not listed.](#62-q-a-repeater-or-a-client-or-a-room-server-i-expect-to-see-on-my-discover-list-on-t-deck-or-contact-list-on-a-smart-device-client-are-not-listed)
@ -661,10 +662,20 @@ Both the Windows and Mac versions of the client app are fully unlocked and are f
### 5.16. Q: Are there any resources that compare MeshCore to other LoRa systems?
**A:** Here is a list of MeshCore comparison resources:
- MeshCore vs Meshtastic by austinmesh.org: <https://www.austinmesh.org/learn/meshcore-vs-meshtastic>
- The Comms Channel on YouTube: <https://www.youtube.com/watch?v=guDoKGs02Us>
- MeshCore Advantages by MCarper: <https://github.com/mikecarper/meshfirmware/blob/main/MeshCoreAdvantages.md>
- MeshCore vs Meshtastic by austinmesh.org: <https://www.austinmesh.org/learn/meshcore-vs-meshtastic>
### 5.17. Q: What do the buzzer tones on my companion radio mean?
Other events (incoming direct message, channel message, ack, advert sent) keep their own short fixed signatures.
**A:** On companion-radio devices the buzzer plays distinct tones so you can tell actions apart by ear, which is especially useful on button-only devices like the T1000-E.
Toggle confirmations follow a simple convention: **ascending pitch = enabled**, **descending pitch = disabled**, and the **number of notes matches the number of button presses** that triggered the action. So a triple-press to toggle the buzzer plays 3 notes (ascending on, descending off), a quadruple-press to toggle GPS plays 4 notes, and so on.
Other events (incoming direct message, channel message, ack, advert sent) keep their own short fixed signatures.
---

4
examples/companion_radio/AbstractUITask.h

@ -19,7 +19,8 @@ enum class UIEventType {
channelMessage,
roomMessage,
newContactMessage,
ack
ack,
advertSent
};
class AbstractUITask {
@ -42,5 +43,6 @@ 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 notify(UIEventType t = UIEventType::none) = 0;
virtual void notifyToggle(int count, bool enabled) {}
virtual void loop() = 0;
};

20
examples/companion_radio/ui-new/UITask.cpp

@ -457,7 +457,7 @@ public:
return true;
}
if (c == KEY_ENTER && _page == HomePage::ADVERT) {
_task->notify(UIEventType::ack);
_task->notify(UIEventType::advertSent);
if (the_mesh.advert()) {
_task->showAlert("Advert sent!", 1000);
} else {
@ -632,6 +632,9 @@ switch(t){
case UIEventType::ack:
buzzer.play("ack:d=32,o=8,b=120:c");
break;
case UIEventType::advertSent:
buzzer.play("Advert:d=8,o=6,b=180:c,e,g,c7");
break;
case UIEventType::roomMessage:
case UIEventType::newContactMessage:
case UIEventType::none:
@ -648,6 +651,12 @@ switch(t){
#endif
}
void UITask::notifyToggle(int count, bool enabled) {
#if defined(PIN_BUZZER)
buzzer.playToggle(count, enabled);
#endif
}
void UITask::msgRead(int msgcount) {
_msgcount = msgcount;
@ -937,11 +946,11 @@ void UITask::toggleGPS() {
if (strcmp(_sensors->getSettingValue(i), "1") == 0) {
_sensors->setSettingValue("gps", "0");
_node_prefs->gps_enabled = 0;
notify(UIEventType::ack);
notifyToggle(4, false);
} else {
_sensors->setSettingValue("gps", "1");
_node_prefs->gps_enabled = 1;
notify(UIEventType::ack);
notifyToggle(4, true);
}
the_mesh.savePrefs();
showAlert(_node_prefs->gps_enabled ? "GPS: Enabled" : "GPS: Disabled", 800);
@ -957,8 +966,11 @@ void UITask::toggleBuzzer() {
#ifdef PIN_BUZZER
if (buzzer.isQuiet()) {
buzzer.quiet(false);
notify(UIEventType::ack);
notifyToggle(3, true);
} else {
// play the off-tone before muting so the user hears the confirmation
notifyToggle(3, false);
while (buzzer.isPlaying()) buzzer.loop();
buzzer.quiet(true);
}
_node_prefs->buzzer_quiet = buzzer.isQuiet();

1
examples/companion_radio/ui-new/UITask.h

@ -95,6 +95,7 @@ public:
void msgRead(int msgcount) override;
void newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount) override;
void notify(UIEventType t = UIEventType::none) override;
void notifyToggle(int count, bool enabled) override;
void loop() override;
void shutdown(bool restart = false);

20
examples/companion_radio/ui-orig/UITask.cpp

@ -103,6 +103,9 @@ switch(t){
case UIEventType::ack:
buzzer.play("ack:d=32,o=8,b=120:c");
break;
case UIEventType::advertSent:
buzzer.play("Advert:d=8,o=6,b=180:c,e,g,c7");
break;
case UIEventType::roomMessage:
case UIEventType::newContactMessage:
case UIEventType::none:
@ -114,6 +117,12 @@ switch(t){
// Serial.println((int) t);
}
void UITask::notifyToggle(int count, bool enabled) {
#if defined(PIN_BUZZER)
buzzer.playToggle(count, enabled);
#endif
}
void UITask::msgRead(int msgcount) {
_msgcount = msgcount;
if (msgcount == 0) {
@ -392,7 +401,7 @@ void UITask::handleButtonDoublePress() {
MESH_DEBUG_PRINTLN("UITask: double press triggered, sending advert");
// ADVERT
#ifdef PIN_BUZZER
notify(UIEventType::ack);
notify(UIEventType::advertSent);
#endif
if (the_mesh.advert()) {
MESH_DEBUG_PRINTLN("Advert sent!");
@ -410,9 +419,12 @@ void UITask::handleButtonTriplePress() {
#ifdef PIN_BUZZER
if (buzzer.isQuiet()) {
buzzer.quiet(false);
notify(UIEventType::ack);
notifyToggle(3, true);
sprintf(_alert, "Buzzer: ON");
} else {
// play the off-tone before muting so the user hears the confirmation
notifyToggle(3, false);
while (buzzer.isPlaying()) buzzer.loop();
buzzer.quiet(true);
sprintf(_alert, "Buzzer: OFF");
}
@ -431,11 +443,11 @@ void UITask::handleButtonQuadruplePress() {
if (strcmp(_sensors->getSettingName(i), "gps") == 0) {
if (strcmp(_sensors->getSettingValue(i), "1") == 0) {
_sensors->setSettingValue("gps", "0");
notify(UIEventType::ack);
notifyToggle(4, false);
sprintf(_alert, "GPS: Disabled");
} else {
_sensors->setSettingValue("gps", "1");
notify(UIEventType::ack);
notifyToggle(4, true);
sprintf(_alert, "GPS: Enabled");
}
break;

1
examples/companion_radio/ui-orig/UITask.h

@ -67,6 +67,7 @@ public:
void msgRead(int msgcount) override;
void newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount) override;
void notify(UIEventType t = UIEventType::none) override;
void notifyToggle(int count, bool enabled) override;
void loop() override;
void shutdown(bool restart = false);

20
examples/companion_radio/ui-tiny/UITask.cpp

@ -399,7 +399,7 @@ public:
return true;
}
if (c == KEY_ENTER && _page == HomePage::ADVERT) {
_task->notify(UIEventType::ack);
_task->notify(UIEventType::advertSent);
if (the_mesh.advert()) {
_task->showAlert("Advert sent!", 1000);
} else {
@ -486,6 +486,9 @@ switch(t){
case UIEventType::ack:
buzzer.play("ack:d=32,o=8,b=120:c");
break;
case UIEventType::advertSent:
buzzer.play("Advert:d=8,o=6,b=180:c,e,g,c7");
break;
case UIEventType::roomMessage:
case UIEventType::newContactMessage:
case UIEventType::none:
@ -502,6 +505,12 @@ switch(t){
#endif
}
void UITask::notifyToggle(int count, bool enabled) {
#if defined(PIN_BUZZER)
buzzer.playToggle(count, enabled);
#endif
}
void UITask::msgRead(int msgcount) {
_msgcount = msgcount;
@ -809,11 +818,11 @@ void UITask::toggleGPS() {
if (strcmp(_sensors->getSettingValue(i), "1") == 0) {
_sensors->setSettingValue("gps", "0");
_node_prefs->gps_enabled = 0;
notify(UIEventType::ack);
notifyToggle(4, false);
} else {
_sensors->setSettingValue("gps", "1");
_node_prefs->gps_enabled = 1;
notify(UIEventType::ack);
notifyToggle(4, true);
}
the_mesh.savePrefs();
showAlert(_node_prefs->gps_enabled ? "GPS: Enabled" : "GPS: Disabled", 800);
@ -829,8 +838,11 @@ void UITask::toggleBuzzer() {
#ifdef PIN_BUZZER
if (buzzer.isQuiet()) {
buzzer.quiet(false);
notify(UIEventType::ack);
notifyToggle(3, true);
} else {
// play the off-tone before muting so the user hears the confirmation
notifyToggle(3, false);
while (buzzer.isPlaying()) buzzer.loop();
buzzer.quiet(true);
}
_node_prefs->buzzer_quiet = buzzer.isQuiet();

1
examples/companion_radio/ui-tiny/UITask.h

@ -103,6 +103,7 @@ public:
void msgRead(int msgcount) override;
void newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount) override;
void notify(UIEventType t = UIEventType::none) override;
void notifyToggle(int count, bool enabled) override;
void loop() override;
void shutdown(bool restart = false);

15
src/helpers/ui/buzzer.cpp

@ -44,6 +44,21 @@ void genericBuzzer::shutdown() {
play(shutdown_song);
}
void genericBuzzer::playToggle(int count, bool enabled) {
static const char *notes[] = {"c", "e", "g", "c7", "e7", "g7"};
const int max_notes = (int)(sizeof(notes) / sizeof(notes[0]));
if (count < 1) count = 1;
if (count > max_notes) count = max_notes;
A static buffer as the library can't play two melodies at once anyway.
static char melody[64];
int n = snprintf(melody, sizeof(melody), "Tg:d=8,o=6,b=180:");
for (int i = 0; i < count && n < (int)sizeof(melody); i++) {
int idx = enabled ? i : (count - 1 - i);
n += snprintf(melody + n, sizeof(melody) - n, "%s%s", i ? "," : "", notes[idx]);
}
play(melody);
}
void genericBuzzer::quiet(bool buzzer_state) {
_is_quiet = buzzer_state;
#ifdef PIN_BUZZER_EN

1
src/helpers/ui/buzzer.h

@ -21,6 +21,7 @@ class genericBuzzer
public:
void begin(); // set up buzzer port
void play(const char *melody); // Generic play function
void playToggle(int count, bool enabled); // play toggle tone
void loop(); // loop driven-nonblocking
void startup(); // play startup sound
void shutdown(); // play shutdown sound

Loading…
Cancel
Save