Category Archives: IOT / Domoticz

Fireworks LED addition and modifying Arcade buttons

I’ve given people on the street control over my Xmas/Fireworks lights last month. (This month it is going to be converted to an interactive game)

I saw some LED strip dividers on Aliexpress, next year it’s going to have a star on top.

Like this….

Another LED related project I started today is a Whack-A-Mole game with multiple levels.
For this I need to convert a simple arcade button to a programmable multicolor version.

From single white LED to multi color, programmable.

Giving people ability to control my Xmas lights

At the WHY2025 hackers event, we used bigred’s antenna pole to make a huge sign using leds.

It gave me the idea to make a pole which displays digital “fireworks” using leds.
Fireworks are becoming illegal the next year in the Netherlands, I think.

So why not going digital?
12 Meter pole, 300 Leds.

There is a QR code and a website link mentioned on a page at the gate.
10 presets to select via a website.

Notification on my TV

While waiting for the first visitor I made a magnetic game.
Using a bunch of magnets, and 3D printed hexagon rings.
Two players try to place magnets in a small area without moving the others. If magnets slam together, you have more pieces to place.
(Below, last player has to take those 6 pieces)

CODE for website index.html

<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>WLED Mast</title>

<style>
body {
    background: #111;
    color: #fff;
    font-family: Arial;
    margin: 0;
    padding: 20px;
    text-align: center;
}
.grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 18px;
}
button {
    padding: 25px;
    font-size: 22px;
    border-radius: 20px;
    border: none;
    background: #333;
    color: #fff;
    font-weight: bold;
}
button:active {
    background: #555;
}
</style>
</head>

<body>

<h1>WLED Mast</h1>

<div class="grid">
    <button onclick="run('b1')">off</button>
    <button onclick="run('b2')">fireworks</button>
    <button onclick="run('b3')">sound<BR>reactive</button>
    <button onclick="run('b4')">bounch-balls</button>
    <button onclick="run('b5')">fire</button>
    <button onclick="run('b6')">juggle</button>
    <button onclick="run('b7')">swing</button>
    <button onclick="run('b8')">sparkle</button>
    <button onclick="run('b9')">popcorn</button>
    <button onclick="run('b10')">comet</button>
</div>

<script>
const API_KEY = "misuse-prevent";

function run(action) {
    fetch(`/action.php?action=${action}&key=${API_KEY}`)
        .then(r => r.json())
        .then(j => console.log(j))
        .catch(err => alert("Error"));
}
</script>

</body>
</html>

CODE for Wled API

<?php

$public_api_key = "misuse-prevent";
if (!isset($_GET['key']) || $_GET['key'] !== $public_api_key) {
    http_response_code(401);
    die("Unauthorized");
}

$action = $_GET['action'] ?? null;

// Map 10 buttons → WLED preset numbers
$allowed_actions = [
    "b1"  => 19,
    "b2"  => 22,
    "b3"  => 23,
    "b4"  => 20,
    "b5"  => 21,
    "b6"  => 3,
    "b7"  => 8,
    "b8"  => 2,
    "b9"  => 4,
    "b10" => 14
];

if (!$action || !isset($allowed_actions[$action])) {
    http_response_code(400);
    die("Invalid action");
}

$preset = $allowed_actions[$action];

// ---- WLED IP address ----
$wled_ip = "http://WLEDDEVICEIP";   // <-- CHANGE THIS

// API endpoint
$url = $wled_ip . "/win&PL=" . $preset;

// Call WLED directly
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($ch, CURLOPT_TIMEOUT, 2);

$response = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);

header("Content-Type: application/json");

if ($error) {
    echo json_encode(["ok" => false, "error" => $error]);
} else {
    echo json_encode(["ok" => true, "preset" => $preset]);
}

Working on the garden lights POC

Working on my garden lights

Working 12V relay bottom left, and upper right the Raspberry $ compute module board with NodeRed.

I made a little board to program the ATTiny85.

The RS485 chip I wanted to use (SN65HVD3082) came as SMD, luckily I have some SMD to THT/DIL boards. (breakoff)

Above on the breadboard : The SN65HVD3082EP on a little pcb, the ATTiny85 .
4×4 WS2812 led matrix will be my dimmable RGB garden light.

New MMWave boards.

Several years ago, I used some radar boards to detect movement.

After that I used a MMWave board

These are amazing, I’m using this in my Lab to switch on my big LED panel. You don’t need to move, it will detect human presence.
Another one I’m using in my living room.
It can power off all media at night (like TV, amplifier and lights)
It’s part of my home alarm system when we are away.

Now I got a new MMWave sensor (hlk-ld2450) , it can detect up to 3 persons and their location.


Screenshot from a Bluetooth phone app reading the sensor.

New afvalwijzer using Home Assistant

New version of :

New schematic using ESPHOME and has reset button (pressing the lid).
(Resets the LED when you’ve put the trash at the street curb.)

Above, a simplified version. I’m using 4 ws2812 leds now.

ESPHOME code:

esphome:
  name: afvalwemos
  friendly_name: AfvalWemos
  on_boot:
    priority: 800
    then:
    - delay: 1s
    - light.turn_off: main_leds

esp8266:
  board: d1_mini

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "bT76oR8vOxxxxxxxxxxxxxxxxxxxxxxxxQbyjY6M="

ota:
  - platform: esphome
    password: "c1dbxxxxxxxxxxxxxxxxxxxxxxxxxx36e75"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Afvalwemos Fallback Hotspot"
    password: "vVxxxxxxxxxxxxxxaw"

captive_portal:

# LED strip definition
light:
  - platform: neopixelbus
    type: RGB
    variant: WS2812
    pin: D5
    num_leds: 4
    name: "All LEDs"
    id: main_leds
    restore_mode: ALWAYS_OFF   # ensures all LEDs start off


  # Individual LED partitions
  - platform: partition
    name: "LED 1"
    segments:
      - id: main_leds
        from: 0
        to: 0

  - platform: partition
    name: "LED 2"
    segments:
      - id: main_leds
        from: 1
        to: 1

  - platform: partition
    name: "LED 3"
    segments:
      - id: main_leds
        from: 2
        to: 2

  - platform: partition
    name: "LED 4"
    segments:
      - id: main_leds
        from: 3
        to: 3


# Physical button on D6 to turn off all LEDs
binary_sensor:
  - platform: gpio
    pin:
      number: D6
      mode: INPUT_PULLUP
      inverted: True
    name: "All Off Button"
    on_press:
      - logger.log: "Button pressed — turning all LEDs OFF"
      - light.turn_off: main_leds

Home Assistant automation:

alias: Afvalwijzer Plastic
description: Afvalwijzer leds
triggers:
  - at: "18:00:00"
    trigger: time
conditions:
  - condition: template
    value_template: >
      {% set raw = states('sensor.gad_pmd') %} {% if raw not in ['unknown',
      'unavailable', 'none', ''] %}
        {% set clean = raw.replace('Tomorrow, ', '').replace('Today, ', '').strip() %}
        {% set parts = clean.split(', ') %}
        {% set date_part = parts[-1] if parts|length > 1 else clean %}
        {% set pmd_date = strptime(date_part, '%d-%m-%Y').date() %}
        {% set tomorrow = (now().date() + timedelta(days=1)) %}
        {{ pmd_date == tomorrow }}
      {% else %}
        false
      {% endif %}
actions:
  - action: light.turn_on
    target:
      entity_id: light.afvalwemos_led_3
    data:
      rgb_color:
        - 236
        - 199
        - 14
mode: single

Easy cheap touch light

Remember those expensive touch lights you can buy?

This is a less than 5 euro version.

Warning : Some tricks I used

  • Using D5 as GND (I didn’t want to splice GND Wire.)
  • Using PWM for dimming
  • Using 5V led, use resistor if using a generic LED (220ohm)

TTP223 sensors are only a few cents!
And react even without touching (< 5mm)
So, you can build this in a case or behind fabric!

NOTE: If you are using an ESP32 you can configure a pin as touch!!!
So no TTP223 needed.
But ESP32 are more expensive as Wemos mini.

Code:

#define TOUCH_PIN D2 // My video has D7
#define LED_PIN   D6
#define FAKE_GND D5

// Brightness steps (0 = off, 255 = full bright)
int brightnessLevels[] = {0, 25, 125, 255};
int currentLevel = 0;
bool lastTouchState = LOW;

void setup() {
  
  pinMode(TOUCH_PIN, INPUT);
  pinMode(LED_PIN, OUTPUT);
  pinMode(FAKE_GND, OUTPUT);

  digitalWrite(FAKE_GND, LOW);  
  analogWrite(LED_PIN, brightnessLevels[currentLevel]);  // start OFF
}

void loop() {
  bool touchState = digitalRead(TOUCH_PIN);

    if (touchState == HIGH && lastTouchState == LOW) {
      // Advance brightness step
      currentLevel = (currentLevel + 1) % 4;  // 0-3 steps
      int pwmValue = brightnessLevels[currentLevel];
      analogWrite(LED_PIN, pwmValue);
    }

  lastTouchState = touchState;
}

Dim levels less obvious on recording, but you can change the levels in the code!

DIY Garden Lights.

We are planning to redo our garden. And I am making a water and light plan for it.

I thought I could do it myself using 12V and RS485/Modbus.

So these are my plans. (NOTE, this is a work in progress)

I’m going to put 4-wire ground cable in our garden, and a RS485/Modbus master controller in my shed.
4 Wires will have 12V low voltage, ground and RS485 A/B wires.
This way I can control till 64 devices on a single cable.

Below, a USB stick to connect the RS485 cables to a Raspberry Pi?
Software is probably going to be a NodeRed instance connected to Home Assistant.

On/Off lights using a RS485 board and relay. These can be bought on a single PCB and can control 220V. I am probably going to use generic outside lamps and refit them for 12V led or 220v, with those RS485 controllers.

The above left part will be encased in resin or alike.
Right PCB is for testing only.

For dimming RGB lights, I made the below design.

NOTE: This needs 120ohm end resistor and capacitors over the 7805.

12V to 5V using a 7805, RS485 8pin DIL/DIP and a ATTiny85 8pin DIL/DIP. Plus a 4×4 RGB Matrix.
These also encased in resin.

More information on the ATTiny85 and programmer can be found here:

Modbus using NodeRed (I’ve used this to control my RD6006 Lab Power Supply)

Bare minimal to control the relay.

HA control via MQTT

5 sensor Flame detector

December is coming, time for candles.

The plan is to make a flame sensor, with in combination with my presence sensor will alert me when we leave the room and candles are on, give us a notification.

Above is the schematic. A Wemos mini (left over from another project), an analog multiplexer and a cheap 5 times flame detector.
There is a potentiometer on this board to change the sensitivity.

Search “Infrared Ir Flame Sensor Detector Fire Detection Module 5 Channel” on Aliexpress. These are 1 euro.

Presence sensor:

Here is some Arduino code.

#define MUX_A D5
#define MUX_B D6
#define MUX_C D7
#define ENABLE D1

#define ANALOG_INPUT A0


void setup() {
    Serial.begin(9600);

  //Define output pins for Mux
  pinMode(MUX_A, OUTPUT);
  pinMode(MUX_B, OUTPUT);     
  pinMode(MUX_C, OUTPUT);     
  pinMode(ENABLE, OUTPUT);     
  digitalWrite(ENABLE, LOW); // No need to switch, can be permanenty low
  
}

void changeMux(int c, int b, int a) {
  digitalWrite(MUX_A, a);
  digitalWrite(MUX_B, b);
  digitalWrite(MUX_C, c);
}

void loop() {
  float value;
  
  
  changeMux(LOW, LOW, HIGH);
  value = analogRead(ANALOG_INPUT); //Value of the sensor connected Option 1 pin of Mux
  Serial.print("Variable_1:");
  Serial.print(value);
  Serial.print(",");

  changeMux(LOW, HIGH, LOW);
  value = analogRead(ANALOG_INPUT); //Value of the sensor connected Option 2 pin of Mux
  Serial.print("Variable_2:");
  Serial.print(value);
  Serial.print(",");

  changeMux(LOW, HIGH, HIGH);
  value = analogRead(ANALOG_INPUT); //Value of the sensor connected Option 3 pin of Mux
  Serial.print("Variable_3:");
  Serial.print(value);
  Serial.print(",");

  changeMux(HIGH, LOW, LOW);
  value = analogRead(ANALOG_INPUT); //Value of the sensor connected Option 4 pin of Mux
  Serial.print("Variable_4:");
  Serial.print(value);
  Serial.print(",");

  changeMux(HIGH, LOW, HIGH);
  value = analogRead(ANALOG_INPUT); //Value of the sensor connected Option 5 pin of Mux
  Serial.print("Variable_5:");
  Serial.println(value);
}

ESPHOME Code

esphome:
  name: flamedetector
  friendly_name: FlameDetector
  on_boot:
    priority: 600
    then:
      - switch.turn_off: enable 

esp8266:
  board: d1_mini

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "BMHbLdN6Rxxxxxxxxxxxxxxxxxxxxv0LE="

ota:
  - platform: esphome
    password: "780fe0xxxxxxxxxxxxxxxxxxxxx7859"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Flamedetector Fallback Hotspot"
    password: "cm1xxxxxxxxxxxxNX"

captive_portal:

switch:
  - platform: gpio
    id: enable
    pin:
      number: D1

cd74hc4067:
  - id: cd74hc4067_1
    pin_s0: D5
    pin_s1: D6
    pin_s2: D7
    pin_s3: D2

globals:
  - id: last_flame_state
    type: bool
    restore_value: no
    initial_value: 'false'
  - id: trigger_on
    type: bool
    restore_value: no
    initial_value: 'false'

sensor:
  - platform: adc
    id: adc_sensor
    pin: A0
    name: flameanalog
    update_interval: 10s
  - platform: cd74hc4067
    id: flame_1_1
    name: flame_1_1
    number: 1
    sensor: adc_sensor
    update_interval: 10s
  - platform: cd74hc4067
    id: flame_1_2
    name: flame_1_2
    number: 2
    sensor: adc_sensor
    update_interval: 10s
  - platform: cd74hc4067
    id: flame_1_3
    name: flame_1_3
    number: 3
    sensor: adc_sensor
    update_interval: 10s
  - platform: cd74hc4067
    id: flame_1_4
    name: flame_1_4
    number: 4
    sensor: adc_sensor
    update_interval: 10s
  - platform: cd74hc4067
    id: flame_1_5
    name: flame_1_5
    number: 5
    sensor: adc_sensor
    update_interval: 10s


interval:
  - interval: 10s
    then:
      - lambda: |-
          const float threshold = 0.01;
          bool any_above =
            id(flame_1_1).state > threshold ||
            id(flame_1_2).state > threshold ||
            id(flame_1_3).state > threshold ||
            id(flame_1_4).state > threshold ||
            id(flame_1_5).state > threshold;

          // Store the result
          if (any_above != id(last_flame_state)) {
            id(last_flame_state) = any_above;
            if (any_above) {
              ESP_LOGI("flame_check", "Flame detected (turning ON)");
              id(trigger_on) = true;
            } else {
              ESP_LOGI("flame_check", "No flame detected (turning OFF)");
              id(trigger_on) = false;
            }
          }

  - interval: 1s
    then:
      - if:
          condition:
            lambda: 'return id(trigger_on);'
          then:
            - homeassistant.service:
                service: homeassistant.turn_on
                data:
                  entity_id: input_boolean.testtoggle
          else:
            - homeassistant.service:
                service: homeassistant.turn_off
                data:
                  entity_id: input_boolean.testtoggle