// Door buzzer detector: spectral-template matching on an I2S MEMS mic, ntfy push alerts. #include #include "driver/gpio.h" #include "esp_log.h" #include "esp_timer.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "audio_in.h" #include "board_config.h" #include "calibration.h" #include "config_store.h" #include "console.h" #include "led.h" #include "matcher.h" #include "notifier.h" #include "processing.h" static const char *TAG = "main"; // BOOT button (GPIO0, active low). A short press (30 ms .. 1 s) starts `learn`. static void button_task(void *arg) { gpio_config_t io = { .pin_bit_mask = 1ULL << BOOT_BTN_GPIO, .mode = GPIO_MODE_INPUT, .pull_up_en = GPIO_PULLUP_ENABLE, }; if (gpio_config(&io) != ESP_OK) { ESP_LOGE(TAG, "button gpio_config failed"); vTaskDelete(NULL); } int64_t down_at = 0; for (;;) { vTaskDelay(pdMS_TO_TICKS(20)); bool down = gpio_get_level(BOOT_BTN_GPIO) == 0; if (down && down_at == 0) { down_at = esp_timer_get_time(); } else if (!down && down_at != 0) { int64_t held_ms = (esp_timer_get_time() - down_at) / 1000; down_at = 0; if (held_ms >= 30 && held_ms <= 1000) { printf("\n[BOOT button] starting learn\n"); calibration_run_learn(false, 0.0f); // blocks this task only } } } } static void check(esp_err_t err, const char *what) { if (err != ESP_OK) { ESP_LOGE(TAG, "%s failed: %s", what, esp_err_to_name(err)); } } void app_main(void) { ESP_ERROR_CHECK(config_init()); // also initialises NVS check(led_init(), "led_init"); ESP_ERROR_CHECK(calibration_init()); ESP_ERROR_CHECK(matcher_init()); ESP_ERROR_CHECK(audio_in_init()); check(notifier_init(), "notifier_init"); ESP_ERROR_CHECK(processing_start()); ESP_ERROR_CHECK(audio_in_start()); if (xTaskCreate(button_task, "button", 4096, NULL, 3, NULL) != pdPASS) { ESP_LOGE(TAG, "button task not created"); } printf("\nDoor buzzer detector ready. Type `help`.\n"); if (!matcher_has_template()) { printf("NEEDS TEMPLATE. Either:\n" " 1) python tools/make_template.py --buzz your_recording.wav then rebuild/flash, or\n" " 2) type `learn` (or short-press BOOT) and press the buzzer during the 60 s session.\n"); } check(console_start(), "console_start"); }