#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; }