Last active
June 6, 2026 08:10
-
-
Save selvakn/66d22aae465e9525a84507266d93d6e2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| esphome: | |
| name: indriya-1 | |
| on_boot: | |
| - priority: 850 | |
| then: | |
| # Strip driver + RMT init; without a short delay first frames are sometimes dropped. | |
| - delay: 200ms | |
| - script.execute: cycle_status_led_pattern | |
| esp32: | |
| board: esp32dev | |
| framework: | |
| type: arduino | |
| logger: | |
| level: DEBUG | |
| wifi: | |
| ssid: iot-workshop | |
| password: !secret wifi_password | |
| mqtt: | |
| broker: 143.110.189.219 | |
| port: 5883 | |
| discovery: false | |
| ota: | |
| - platform: esphome | |
| password: !secret ota_password | |
| globals: | |
| - id: led_pattern_index | |
| type: int | |
| restore_value: no | |
| initial_value: "0" | |
| # ================================== | |
| # I2C Bus Configuration | |
| # ================================== | |
| i2c: | |
| sda: GPIO21 | |
| scl: GPIO22 | |
| scan: true | |
| # ESP32 default I2C timeout is 100us and often triggers "I2C hardware timeout" | |
| # with BME280 / shared bus; allow up to 13ms (ESP32 driver maximum). | |
| frequency: 50kHz | |
| timeout: 13ms | |
| # ================================== | |
| # I2C Sensors | |
| # ================================== | |
| sensor: | |
| - platform: bme280_i2c | |
| temperature: | |
| name: "BME280 Temperature" | |
| id: bme280_temperature | |
| pressure: | |
| name: "BME280 Pressure" | |
| id: bme280_pressure | |
| humidity: | |
| name: "BME280 Humidity" | |
| id: bme280_humidity | |
| address: 0x76 # Common addresses are 0x76 or 0x77. Change to 0x77 if it fails to initialize. | |
| update_interval: 60s | |
| - platform: vl53l0x | |
| id: lidar_distance | |
| name: "Lidar Distance" | |
| address: 0x29 | |
| update_interval: 1s | |
| on_value: | |
| then: | |
| - if: | |
| condition: | |
| lambda: |- | |
| return std::isfinite(x) && x < 0.1f; | |
| then: | |
| # Note: trailing digit after a letter is octave (4–7), not duration. Use 8c for an eighth note. | |
| - rtttl.play: "close:d=4,o=6,b=200:8c,8e,8g,8e,8c" | |
| # ================================== | |
| # Analog Sensors (ADC) | |
| # ================================== | |
| - platform: adc | |
| pin: GPIO25 | |
| id: ldr_voltage | |
| name: "LDR Light Level" | |
| update_interval: 10s | |
| attenuation: 12db # Required for reading up to ~3.3V (11db deprecated) | |
| # ================================== | |
| # Digital Inputs (Binary Sensors) | |
| # ================================== | |
| binary_sensor: | |
| - platform: gpio | |
| pin: GPIO27 | |
| name: "PIR Motion Sensor" | |
| device_class: motion | |
| # Sound module digital output (DO) — threshold is set on the module potentiometer. | |
| - platform: gpio | |
| pin: GPIO5 | |
| id: microphone_digital | |
| name: "Microphone (digital)" | |
| device_class: sound | |
| filters: | |
| - delayed_on: 40ms | |
| - delayed_off: 120ms | |
| # ================================== | |
| # Display (Assumed SSD1306) | |
| # ================================== | |
| font: | |
| - file: "gfonts://Roboto" | |
| id: roboto | |
| size: 14 | |
| - file: "gfonts://Roboto" | |
| id: roboto_sm | |
| size: 10 | |
| display: | |
| - platform: ssd1306_i2c | |
| model: "SSD1306 128x64" # Adjust model if your screen is different | |
| address: 0x3C | |
| update_interval: 500ms | |
| lambda: |- | |
| const int lh = 13; | |
| int y = 0; | |
| it.print(0, y, id(roboto), "indriya-1"); | |
| y = 16; | |
| if (id(bme280_temperature).has_state() && id(bme280_humidity).has_state()) { | |
| it.printf(0, y, id(roboto_sm), "T:%.1fC RH:%.0f%%", | |
| id(bme280_temperature).state, id(bme280_humidity).state); | |
| } else { | |
| it.print(0, y, id(roboto_sm), "T:-- RH:--"); | |
| } | |
| y += lh; | |
| if (id(bme280_pressure).has_state()) { | |
| if (id(lidar_distance).has_state()) { | |
| float d = id(lidar_distance).state; | |
| if (std::isfinite(d)) { | |
| it.printf(0, y, id(roboto_sm), "P:%.0f D:%.2fm", | |
| id(bme280_pressure).state, d); | |
| } else { | |
| it.printf(0, y, id(roboto_sm), "P:%.0f D:----", | |
| id(bme280_pressure).state); | |
| } | |
| } else { | |
| it.printf(0, y, id(roboto_sm), "P:%.0f D:--", id(bme280_pressure).state); | |
| } | |
| } else { | |
| it.print(0, y, id(roboto_sm), "P:-- D:--"); | |
| } | |
| y += lh; | |
| if (id(ldr_voltage).has_state()) { | |
| const char *mic = id(microphone_digital).state ? "ON" : "off"; | |
| it.printf(0, y, id(roboto_sm), "LDR:%.2fV Mic:%s", id(ldr_voltage).state, mic); | |
| } else { | |
| const char *mic = id(microphone_digital).state ? "ON" : "off"; | |
| it.printf(0, y, id(roboto_sm), "LDR:-- Mic:%s", mic); | |
| } | |
| # ================================== | |
| # Outputs & Lighting | |
| # ================================== | |
| light: | |
| - platform: esp32_rmt_led_strip | |
| pin: GPIO32 | |
| num_leds: 3 | |
| # WS2812 and WS2812B timing: ESPHome only lists WS2812 (not WS2812B). | |
| chipset: WS2812 | |
| rgb_order: GRB | |
| # Boards without PSRAM: default use_psram can prevent the strip from working. | |
| use_psram: false | |
| default_transition_length: 0s | |
| name: "Status LEDs" | |
| id: status_leds | |
| effects: | |
| - addressable_rainbow: | |
| name: Rainbow | |
| speed: 12 | |
| width: 3 | |
| - addressable_scan: | |
| name: Scan | |
| move_interval: 150ms | |
| scan_width: 1 | |
| - addressable_twinkle: | |
| name: Twinkle | |
| twinkle_probability: 18% | |
| progress_interval: 6ms | |
| - addressable_color_wipe: | |
| name: Color Wipe | |
| colors: | |
| - red: 100% | |
| green: 0% | |
| blue: 0% | |
| num_leds: 1 | |
| - red: 0% | |
| green: 100% | |
| blue: 0% | |
| num_leds: 1 | |
| - red: 0% | |
| green: 0% | |
| blue: 100% | |
| num_leds: 1 | |
| add_led_interval: 120ms | |
| - addressable_fireworks: | |
| name: Fireworks | |
| update_interval: 40ms | |
| spark_probability: 20% | |
| use_random_color: true | |
| script: | |
| - id: cycle_status_led_pattern | |
| mode: restart | |
| then: | |
| - lambda: |- | |
| static const int k_n = 5; | |
| static const char *const k_patterns[k_n] = { | |
| "Rainbow", "Scan", "Twinkle", "Color Wipe", "Fireworks", | |
| }; | |
| int i = id(led_pattern_index); | |
| auto call = id(status_leds).turn_on(); | |
| call.set_effect(k_patterns[i]); | |
| call.perform(); | |
| id(led_pattern_index) = (i + 1) % k_n; | |
| interval: | |
| - interval: 8s | |
| then: | |
| - script.execute: cycle_status_led_pattern | |
| # ================================== | |
| # Buzzer (Using LEDC for PWM Tones) | |
| # ================================== | |
| output: | |
| - platform: ledc | |
| pin: GPIO18 | |
| id: buzzer_pwm | |
| # Optional: Add RTTTL platform to play ringtones via the buzzer | |
| rtttl: | |
| output: buzzer_pwm | |
| # ================================== | |
| # Infrared (IR) Components | |
| # ================================== | |
| remote_receiver: | |
| pin: | |
| number: GPIO15 | |
| inverted: true # Standard for IR receivers | |
| remote_transmitter: | |
| pin: GPIO23 | |
| carrier_duty_percent: 50% |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment