From 0ca50be26555d25e3adc97dc011b6b07e6a9d279 Mon Sep 17 00:00:00 2001 From: Blackwhitebear8 Date: Fri, 10 Oct 2025 14:46:06 +0200 Subject: [PATCH] Add components/sound_sensor/sound_sensor.h --- components/sound_sensor/sound_sensor.h | 115 +++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 components/sound_sensor/sound_sensor.h diff --git a/components/sound_sensor/sound_sensor.h b/components/sound_sensor/sound_sensor.h new file mode 100644 index 0000000..44dce7e --- /dev/null +++ b/components/sound_sensor/sound_sensor.h @@ -0,0 +1,115 @@ +#include "esphome.h" + +// ===== CONFIGURATIE (deze kun je hier nog steeds aanpassen) ===== +const int ADC_PIN = 36; +const int SAMPLE_WINDOW_MS = 250; +const float SENSITIVITY = 45.0; +const int NOISE_FLOOR = 25; +// ================================================================ + +// Dit is de hoofdklasse die de metingen doet. +// Deze is grotendeels ongewijzigd gebleven. +class SoundSensor : public PollingComponent { + public: + SoundSensor() : PollingComponent(1000) {} // Update-interval van 1 seconde + + // Setters om de sensor-objecten vanuit de YAML te koppelen + void set_db_sensor(sensor::Sensor *s) { this->db_sensor_ = s; } + void set_volume_sensor(sensor::Sensor *s) { this->volume_sensor_ = s; } + void set_raw_sensor(sensor::Sensor *s) { this->raw_sensor_ = s; } + + void setup() override { + pinMode(ADC_PIN, INPUT); + } + + void update() override { + unsigned long startMillis = millis(); + unsigned int sample; + long sum_of_squares = 0; + int sample_count = 0; + + while (millis() - startMillis < SAMPLE_WINDOW_MS) { + sample = analogRead(ADC_PIN); + long signal = sample - 2048; + sum_of_squares += signal * signal; + sample_count++; + delay(0); + } + + if (sample_count == 0) return; + + double rms = sqrt(sum_of_squares / (double)sample_count); + + if (this->raw_sensor_ != nullptr) this->raw_sensor_->publish_state(rms); + + if (rms < NOISE_FLOOR) { + if (this->db_sensor_ != nullptr) this->db_sensor_->publish_state(0); + if (this->volume_sensor_ != nullptr) this->volume_sensor_->publish_state(0); + } else { + float db_value = SENSITIVITY * log10(rms); + if (this->db_sensor_ != nullptr) this->db_sensor_->publish_state(db_value); + + float volume_percent = map(db_value, 0, 90, 0, 100); + volume_percent = constrain(volume_percent, 0, 100); + if (this->volume_sensor_ != nullptr) this->volume_sensor_->publish_state(volume_percent); + } + } + + protected: + sensor::Sensor *db_sensor_{nullptr}; + sensor::Sensor *volume_sensor_{nullptr}; + sensor::Sensor *raw_sensor_{nullptr}; + + float map(float x, float in_min, float in_max, float out_min, float out_max) { + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; + } +}; + + +// =========== NIEUWE CODE VOOR INTEGRATIE MET ESPHOME =========== +// Dit deel is de "lijm" tussen je YAML en de C++ klasse. + +#include "esphome/core/component.h" +#include "esphome/components/sensor/sensor.h" + +// Definieer de configuratie-sleutels die we in YAML gebruiken +static const char* const CONF_DB_SENSOR = "db_sensor"; +static const char* const CONF_VOLUME_SENSOR = "volume_sensor"; +static const char* const CONF_RAW_SENSOR = "raw_sensor"; + +// Definieer het "schema" voor ons component, zodat ESPHome weet welke opties geldig zijn. +// Dit moet overeenkomen met de structuur in je YAML. +#define SOUND_SENSOR_SCHEMA(name) \ + cv::Schema{ \ + cv::Required(name): sensor::sensor_schema(), \ + } + +// Dit is de "fabriek" die ons component bouwt op basis van de YAML configuratie +esp_err_t sound_sensor_to_code(esphome::config_parser::ASTNode* config) { + auto* ss = new SoundSensor(); + App.register_component(ss); + + // Koppel de 'db_sensor' configuratie uit YAML aan ons C++ object + if (config->has_key(CONF_DB_SENSOR)) { + auto conf = config->get_node(CONF_DB_SENSOR); + sensor::Sensor* s = cg::new_Pvariable(conf->get_id()); + sensor::setup_sensor(s, conf); + cg::add(ss->set_db_sensor(s)); + } + // Koppel de 'volume_sensor' configuratie + if (config->has_key(CONF_VOLUME_SENSOR)) { + auto conf = config->get_node(CONF_VOLUME_SENSOR); + sensor::Sensor* s = cg::new_Pvariable(conf->get_id()); + sensor::setup_sensor(s, conf); + cg::add(ss->set_volume_sensor(s)); + } + // Koppel de 'raw_sensor' configuratie + if (config->has_key(CONF_RAW_SENSOR)) { + auto conf = config->get_node(CONF_RAW_SENSOR); + sensor::Sensor* s = cg::new_Pvariable(conf->get_id()); + sensor::setup_sensor(s, conf); + cg::add(ss->set_raw_sensor(s)); + } + + return esp_err_t::ESP_OK; +} \ No newline at end of file