reorder menu and add sound settings
All checks were successful
ESP32 Build & Release / build (push) Successful in 1m18s

This commit is contained in:
2026-09-13 22:54:28 +02:00
parent 7afcc47152
commit 57cf8225bc
8 changed files with 496 additions and 67 deletions

View File

@@ -7,6 +7,8 @@
#include "esp_log.h"
#include "driver/ledc.h"
#include "hw_pins.h"
#include "nvs_flash.h"
#include "nvs.h"
#include "buzzer.h"
#include "freertos/queue.h"
@@ -19,6 +21,7 @@ static const char *TAG = "buzzer";
static QueueHandle_t s_sound_queue = NULL;
static volatile bool s_melody_playing = false;
static audio_profile_t s_profile = AUDIO_PROFILE_CHIPTUNE;
static const buzzer_note_t MELODY_VICTORY[] = {
{NOTE_C5, 90}, {NOTE_C5, 90}, {NOTE_C5, 90}, {NOTE_C5, 220},
@@ -79,6 +82,16 @@ static void buzzer_task(void *arg)
esp_err_t buzzer_init(void)
{
/* Load saved profile from NVS */
nvs_handle_t h;
if (nvs_open("mtg_cfg", NVS_READONLY, &h) == ESP_OK) {
uint8_t prof = 0;
if (nvs_get_u8(h, "audio_prof", &prof) == ESP_OK && prof <= AUDIO_PROFILE_SILENT) {
s_profile = (audio_profile_t)prof;
}
nvs_close(h);
}
ledc_timer_config_t timer_cfg = {
.speed_mode = BUZZER_SPEED_MODE,
.timer_num = BUZZER_TIMER_NUM,
@@ -109,12 +122,15 @@ esp_err_t buzzer_init(void)
xTaskCreate(buzzer_task, "buzzer_task", 2048, NULL, 3, NULL);
}
ESP_LOGI(TAG, "buzzer ready on GPIO %d (chiptune synth active)", HW_BUZZER_GPIO);
ESP_LOGI(TAG, "buzzer ready on GPIO %d (profile: %s)", HW_BUZZER_GPIO, buzzer_get_profile_name(s_profile));
return ESP_OK;
}
esp_err_t buzzer_start(uint32_t freq_hz, uint32_t duty_percent)
{
if (s_profile == AUDIO_PROFILE_SILENT) {
return ESP_OK;
}
if (freq_hz == 0) {
return buzzer_stop();
}
@@ -142,10 +158,17 @@ esp_err_t buzzer_stop(void)
esp_err_t buzzer_chirp(uint32_t freq_hz, uint32_t duration_ms)
{
if (s_profile == AUDIO_PROFILE_SILENT) {
return ESP_OK;
}
if (s_melody_playing) {
return ESP_OK; /* Don't disrupt ongoing background chiptune melody */
}
esp_err_t ret = buzzer_start(freq_hz, 30);
uint32_t duty = (s_profile == AUDIO_PROFILE_TACTILE) ? 10 : 30;
if (s_profile == AUDIO_PROFILE_TACTILE && duration_ms > 20) {
duration_ms = 20;
}
esp_err_t ret = buzzer_start(freq_hz, duty);
if (ret != ESP_OK) {
return ret;
}
@@ -155,8 +178,95 @@ esp_err_t buzzer_chirp(uint32_t freq_hz, uint32_t duration_ms)
esp_err_t buzzer_play_sound(buzzer_sound_t sound)
{
if (s_profile != AUDIO_PROFILE_CHIPTUNE) {
return ESP_OK;
}
if (s_sound_queue != NULL) {
xQueueSend(s_sound_queue, &sound, 0);
}
return ESP_OK;
}
void buzzer_set_profile(audio_profile_t profile)
{
s_profile = profile;
nvs_handle_t h;
if (nvs_open("mtg_cfg", NVS_READWRITE, &h) == ESP_OK) {
nvs_set_u8(h, "audio_prof", (uint8_t)profile);
nvs_commit(h);
nvs_close(h);
}
ESP_LOGI(TAG, "Audio profile set to: %s", buzzer_get_profile_name(profile));
}
audio_profile_t buzzer_get_profile(void)
{
return s_profile;
}
const char *buzzer_get_profile_name(audio_profile_t profile)
{
switch (profile) {
case AUDIO_PROFILE_CHIPTUNE: return "CHIPTUNE";
case AUDIO_PROFILE_TACTILE: return "TACTILE";
case AUDIO_PROFILE_SILENT: return "SILENT";
default: return "UNKNOWN";
}
}
void buzzer_sound_life_gain(void)
{
if (s_profile == AUDIO_PROFILE_SILENT) return;
if (s_profile == AUDIO_PROFILE_TACTILE) {
buzzer_chirp(NOTE_C6, 10);
return;
}
/* Chiptune: ascending two-tone */
buzzer_start(NOTE_G5, 25);
vTaskDelay(pdMS_TO_TICKS(22));
buzzer_start(NOTE_C6, 25);
vTaskDelay(pdMS_TO_TICKS(35));
buzzer_stop();
}
void buzzer_sound_life_loss(void)
{
if (s_profile == AUDIO_PROFILE_SILENT) return;
if (s_profile == AUDIO_PROFILE_TACTILE) {
buzzer_chirp(NOTE_C4, 12);
return;
}
/* Chiptune: descending two-tone */
buzzer_start(NOTE_E4, 25);
vTaskDelay(pdMS_TO_TICKS(25));
buzzer_start(NOTE_C4, 25);
vTaskDelay(pdMS_TO_TICKS(40));
buzzer_stop();
}
void buzzer_sound_rfid_tap(void)
{
if (s_profile == AUDIO_PROFILE_SILENT) return;
if (s_profile == AUDIO_PROFILE_TACTILE) {
buzzer_chirp(NOTE_A5, 20);
return;
}
/* Chiptune: bright recognition chime */
buzzer_start(NOTE_A5, 25);
vTaskDelay(pdMS_TO_TICKS(28));
buzzer_start(NOTE_E6, 25);
vTaskDelay(pdMS_TO_TICKS(45));
buzzer_stop();
}
void buzzer_sound_tick(void)
{
if (s_profile == AUDIO_PROFILE_SILENT) return;
if (s_profile == AUDIO_PROFILE_TACTILE) {
buzzer_start(NOTE_D6, 8);
vTaskDelay(pdMS_TO_TICKS(6));
buzzer_stop();
return;
}
buzzer_chirp(NOTE_C5, 12);
}