mirror of
https://github.com/meshtastic/firmware.git
synced 2025-09-06 03:29:17 +00:00

Some checks are pending
CI / setup (check) (push) Waiting to run
CI / setup (esp32) (push) Waiting to run
CI / setup (esp32c3) (push) Waiting to run
CI / setup (esp32c6) (push) Waiting to run
CI / setup (esp32s3) (push) Waiting to run
CI / setup (nrf52840) (push) Waiting to run
CI / setup (rp2040) (push) Waiting to run
CI / setup (rp2350) (push) Waiting to run
CI / setup (stm32) (push) Waiting to run
CI / version (push) Waiting to run
CI / check (push) Blocked by required conditions
CI / build-esp32 (push) Blocked by required conditions
CI / build-esp32s3 (push) Blocked by required conditions
CI / build-esp32c3 (push) Blocked by required conditions
CI / build-esp32c6 (push) Blocked by required conditions
CI / build-nrf52840 (push) Blocked by required conditions
CI / build-rp2040 (push) Blocked by required conditions
CI / build-rp2350 (push) Blocked by required conditions
CI / build-stm32 (push) Blocked by required conditions
CI / build-debian-src (push) Waiting to run
CI / package-pio-deps-native-tft (push) Waiting to run
CI / test-native (push) Waiting to run
CI / docker-deb-amd64 (push) Waiting to run
CI / docker-deb-amd64-tft (push) Waiting to run
CI / docker-alp-amd64 (push) Waiting to run
CI / docker-alp-amd64-tft (push) Waiting to run
CI / docker-deb-arm64 (push) Waiting to run
CI / docker-deb-armv7 (push) Waiting to run
CI / gather-artifacts (esp32) (push) Blocked by required conditions
CI / gather-artifacts (esp32c3) (push) Blocked by required conditions
CI / gather-artifacts (esp32c6) (push) Blocked by required conditions
CI / gather-artifacts (esp32s3) (push) Blocked by required conditions
CI / gather-artifacts (nrf52840) (push) Blocked by required conditions
CI / gather-artifacts (rp2040) (push) Blocked by required conditions
CI / gather-artifacts (rp2350) (push) Blocked by required conditions
CI / gather-artifacts (stm32) (push) Blocked by required conditions
CI / release-artifacts (push) Blocked by required conditions
CI / release-firmware (esp32) (push) Blocked by required conditions
CI / release-firmware (esp32c3) (push) Blocked by required conditions
CI / release-firmware (esp32c6) (push) Blocked by required conditions
CI / release-firmware (esp32s3) (push) Blocked by required conditions
CI / release-firmware (nrf52840) (push) Blocked by required conditions
CI / release-firmware (rp2040) (push) Blocked by required conditions
CI / release-firmware (rp2350) (push) Blocked by required conditions
CI / release-firmware (stm32) (push) Blocked by required conditions
CI / publish-firmware (push) Blocked by required conditions
168 lines
4.8 KiB
C++
168 lines
4.8 KiB
C++
#include "buzz.h"
|
|
#include "NodeDB.h"
|
|
#include "configuration.h"
|
|
|
|
#if !defined(ARCH_ESP32) && !defined(ARCH_RP2040) && !defined(ARCH_PORTDUINO)
|
|
#include "Tone.h"
|
|
#endif
|
|
|
|
#if !defined(ARCH_PORTDUINO)
|
|
extern "C" void delay(uint32_t dwMs);
|
|
#endif
|
|
|
|
struct ToneDuration {
|
|
int frequency_khz;
|
|
int duration_ms;
|
|
};
|
|
|
|
// Some common frequencies.
|
|
#define NOTE_C3 131
|
|
#define NOTE_CS3 139
|
|
#define NOTE_D3 147
|
|
#define NOTE_DS3 156
|
|
#define NOTE_E3 165
|
|
#define NOTE_F3 175
|
|
#define NOTE_FS3 185
|
|
#define NOTE_G3 196
|
|
#define NOTE_GS3 208
|
|
#define NOTE_A3 220
|
|
#define NOTE_AS3 233
|
|
#define NOTE_B3 247
|
|
#define NOTE_CS4 277
|
|
|
|
const int DURATION_1_8 = 125; // 1/8 note
|
|
const int DURATION_1_4 = 250; // 1/4 note
|
|
const int DURATION_1_2 = 500; // 1/2 note
|
|
const int DURATION_3_4 = 750; // 1/4 note
|
|
const int DURATION_1_1 = 1000; // 1/1 note
|
|
|
|
void playTones(const ToneDuration *tone_durations, int size)
|
|
{
|
|
if (config.device.buzzer_mode == meshtastic_Config_DeviceConfig_BuzzerMode_DISABLED ||
|
|
config.device.buzzer_mode == meshtastic_Config_DeviceConfig_BuzzerMode_NOTIFICATIONS_ONLY) {
|
|
// Buzzer is disabled or not set to system tones
|
|
return;
|
|
}
|
|
#ifdef PIN_BUZZER
|
|
if (!config.device.buzzer_gpio)
|
|
config.device.buzzer_gpio = PIN_BUZZER;
|
|
#endif
|
|
if (config.device.buzzer_gpio) {
|
|
for (int i = 0; i < size; i++) {
|
|
const auto &tone_duration = tone_durations[i];
|
|
tone(config.device.buzzer_gpio, tone_duration.frequency_khz, tone_duration.duration_ms);
|
|
// to distinguish the notes, set a minimum time between them.
|
|
delay(1.3 * tone_duration.duration_ms);
|
|
}
|
|
}
|
|
}
|
|
|
|
void playBeep()
|
|
{
|
|
ToneDuration melody[] = {{NOTE_B3, DURATION_1_8}};
|
|
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
|
|
}
|
|
|
|
void playLongBeep()
|
|
{
|
|
ToneDuration melody[] = {{NOTE_B3, DURATION_1_1}};
|
|
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
|
|
}
|
|
|
|
void playGPSEnableBeep()
|
|
{
|
|
ToneDuration melody[] = {{NOTE_C3, DURATION_1_8}, {NOTE_FS3, DURATION_1_4}, {NOTE_CS4, DURATION_1_4}};
|
|
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
|
|
}
|
|
|
|
void playGPSDisableBeep()
|
|
{
|
|
ToneDuration melody[] = {{NOTE_CS4, DURATION_1_8}, {NOTE_FS3, DURATION_1_4}, {NOTE_C3, DURATION_1_4}};
|
|
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
|
|
}
|
|
|
|
void playStartMelody()
|
|
{
|
|
ToneDuration melody[] = {{NOTE_FS3, DURATION_1_8}, {NOTE_AS3, DURATION_1_8}, {NOTE_CS4, DURATION_1_4}};
|
|
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
|
|
}
|
|
|
|
void playShutdownMelody()
|
|
{
|
|
ToneDuration melody[] = {{NOTE_CS4, DURATION_1_8}, {NOTE_AS3, DURATION_1_8}, {NOTE_FS3, DURATION_1_4}};
|
|
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
|
|
}
|
|
|
|
void playChirp()
|
|
{
|
|
// A short, friendly "chirp" sound for key presses
|
|
ToneDuration melody[] = {{NOTE_AS3, 20}}; // Very short AS3 note
|
|
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
|
|
}
|
|
|
|
void playBoop()
|
|
{
|
|
// A short, friendly "boop" sound for button presses
|
|
ToneDuration melody[] = {{NOTE_A3, 50}}; // Very short A3 note
|
|
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
|
|
}
|
|
|
|
void playLongPressLeadUp()
|
|
{
|
|
// An ascending lead-up sequence for long press - builds anticipation
|
|
ToneDuration melody[] = {
|
|
{NOTE_C3, 100}, // Start low
|
|
{NOTE_E3, 100}, // Step up
|
|
{NOTE_G3, 100}, // Keep climbing
|
|
{NOTE_B3, 150} // Peak with longer note for emphasis
|
|
};
|
|
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
|
|
}
|
|
|
|
// Static state for progressive lead-up notes
|
|
static int leadUpNoteIndex = 0;
|
|
static const ToneDuration leadUpNotes[] = {
|
|
{NOTE_C3, 100}, // Start low
|
|
{NOTE_E3, 100}, // Step up
|
|
{NOTE_G3, 100}, // Keep climbing
|
|
{NOTE_B3, 150} // Peak with longer note for emphasis
|
|
};
|
|
static const int leadUpNotesCount = sizeof(leadUpNotes) / sizeof(ToneDuration);
|
|
|
|
bool playNextLeadUpNote()
|
|
{
|
|
if (leadUpNoteIndex >= leadUpNotesCount) {
|
|
return false; // All notes have been played
|
|
}
|
|
|
|
// Use playTones to handle buzzer logic consistently
|
|
const auto ¬e = leadUpNotes[leadUpNoteIndex];
|
|
playTones(¬e, 1); // Play single note using existing playTones function
|
|
|
|
leadUpNoteIndex++;
|
|
|
|
if (leadUpNoteIndex >= leadUpNotesCount) {
|
|
return false; // this was the final note
|
|
}
|
|
return true; // Note was played (playTones handles buzzer availability internally)
|
|
}
|
|
|
|
void resetLeadUpSequence()
|
|
{
|
|
leadUpNoteIndex = 0;
|
|
}
|
|
|
|
void playComboTune()
|
|
{
|
|
// Quick high-pitched notes with trills
|
|
ToneDuration melody[] = {
|
|
{NOTE_G3, 80}, // Quick chirp
|
|
{NOTE_B3, 60}, // Higher chirp
|
|
{NOTE_CS4, 80}, // Even higher
|
|
{NOTE_G3, 60}, // Quick trill down
|
|
{NOTE_CS4, 60}, // Quick trill up
|
|
{NOTE_B3, 120} // Ending chirp
|
|
};
|
|
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
|
|
}
|