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]);
}

An idea I had to detect and count pages

One of my old ideas, never made or tested.
I saw a post on Reddit with this question, I decided to post a little drawing using my idea.

Center of below picture shows pages (the lines), with coppertape going front to back and connect to following page

Inductive copper tape

Taking resistors of the same value, you’ll get a logarithmic voltage divider.
If you want the values evenly spaced, to make sure you are not misreading the value you have to make the resistors more like:
10k,6k,3k3,2k5,2k,1k68,1k5

Strudel and Hydra

(Live real time using text (code) to make music and visuals)

Last week, I discovered Strudel.
I was playing around with it and thought: “This would be perfect for Tyrone”.
He is/was the main musical artist in our Group.

Strudel REPL is a web-based, live coding environment for creating music, based on the Tidal Cycles pattern language. It allows users to write and edit code in a browser to instantly hear the music it produces, with features like visual feedback and an interactive tutorial to help beginners and experts. The “REPL” stands for Read-Eval-Print Loop, a common term for interactive programming environments where you can type code, and the system immediately evaluates it and prints the result. 

Check it out on : https://strudel.cc/

Below a strudel example

I can make some simple patterns, but I discovered that it can be used multiuser with realtime synthesizer named Hydra.
I’m better doing visuals, than creating realtime digital music.
Check out https://www.henriaanstoot.nl/?s=shaders – for my previous shader programming posts.
(I love playing real instruments, let’s keep it that way.)

Hydra video synth is a free, open-source, live-coding environment for creating real-time visuals that runs in a web browser. It uses JavaScript and WebGL to allow users to “patch” together different visual sources and transformations, similar to an analog modular synthesizer, to generate effects like video feedback, generative patterns, and audio-reactive visuals. 

It is JavaScript being compiled to WebGL

So using https://flok.cc we can start a multiuser session with realtime live coding.

So the first test session, learning to use Hydra and Strudel together over the internet. Plan is to do a live session for others using a screen projector.

Left Tyrone (Strudel) right me with Hydra.

In the last few days, I made some examples using hydra.

These examples use Microphone for sound reactive, and Webcam for embedded effects.
NOTE: These are only in your browser session, nothing is being recorded/stored.

You can check some examples here :

https://media.henriaanstoot.nl/hydra/

UPDATE : Controlling Hydra input using my DIY Midi Controller (see other post) (Music is NOT related, no microphone input)

Strudel midi input with lpf volume and room controls.

let cc = await midin(1)
note("c a f e").lpf(cc(7).range(0, 1000)).room(cc(3).range(0, 10)).sound("sawtooth")

Avond van de Filmmuziek

4th time we’ve been

  • Also sprach Zarathustra, op. 30,(Richard Strauss cover)
  • Back to the Avond van de Filmmuziek,(intro film)
  • Back to the Future,(Alan Silvestri cover)
  • The Strength of the Righteous (main title),(Ennio Morricone cover) (from ‘The Untouchables’)
  • Downton Abbey: The Suite,(John Lunn cover)
  • Succession (Main Title Theme),(Nicholas Britell cover)
  • Renaissance (Main Title Theme),(Cristobal Tapia de Veer cover) (from ‘The White Lotus’)
  • This Is Berk,(John Powell cover) (with Anna Lapwood) (from ‘How to Train Your Dragon’)
  • Hymn to the Fallen,(John Williams cover) (from ‘Saving Private Ryan’)
  • La vita è bella,(Nicola Piovani cover)
  • I Could Use a Boost,(Kris Bowers cover) (from ‘The Wild Robot’)
  • Suite from ‘De Wilde Noordzee’,(Sven Figee cover) (with Sven Figee)
  • Mission: Impossible,(Lalo Schifrin cover)
  • Superdaan,(intro film)
  • Superman March,(John Williams cover)
  • Out of Africa,(John Barry cover)
  • 20th Century Fox Fanfare,(Alfred Newman cover)
  • American Beauty,(Thomas Newman cover) (with Sven Figee)
  • Mad World,(Tears for Fears cover) (with Gary Jules)
  • Of Separation,(Elliot Goldenthal cover) (from ‘Heat’)
  • Solomon,(Hans Zimmer cover) (from ’12 Years a Slave’)
  • Mommy’s Dollhouse,(Cristobal Tapia de Veer cover)
  • Chevaliers de Sangreal,(Hans Zimmer cover) (from ‘The Da Vinci Code’)
  • Suite from Interstellar,(Hans Zimmer cover) (with Anna Lapwood)
  • The Raiders March,(John Williams cover)
  • No One Mourns the Wicked,(Stephen Schwartz cover) (with Vajèn van den Bosch)
  • Defying Gravity,(Stephen Schwartz cover) (with Vajèn van den Bosch)

Other concerts we’ve been to, movie music related.

  • Hans Zimmer in Concert
  • Star Wars Suite
  • War of the worlds (Jeff Wayne)
  • ?? Forgot what it was called.

Working on a (C64) handheld probe oscilloscope

These will be available in my shop.

Probably a webpage with measured examples are usefull.

There is a cover for the pogo pin which holds the ground clamp

Handheld device to measure voltages and make screenshots using an application.

Control over serial

  • Select USB device to connect
  • Start a capture to screen
  • Clear (redraw probe screen)
  • Rotate screen for left/right-handed people and easy reading
  • Sample time speed in microseconds
  • 5V reading but 15 volt tolerant, due to the SID pins
  • ??? love to hear ideas

I’m currently working on streaming output.

Below, an example of screenshotting.

Below, measuring outputs from a NE555 (dutch comments)

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.

"If something is worth doing, it's worth overdoing."