Hawthorn
Your name in SPONSORS.md, and her grudging respect.
A gesture wand with a platinum attitude.
Draw a spell in the air. She tracks the tip 208 times a second, names the shape on the wand itself in about a millisecond, and has your home obey: lights, music, scenes. A haptic flourish and a glowing tip are included. Elegant, cunning, and only slightly dramatic.
I Meet Malfoid
She reads your wrist like a ledger, and judges it accordingly.
Malfoid is a complete, open hardware project: firmware, circuit design, a 3D-printable body and this site. Underneath the attitude it's an embedded systems project done properly, with interrupt-driven sensing, sensor fusion, an on-device recognizer tested against thousands of simulated casts, and a power design that sleeps on microamps.
Madgwick sensor fusion at 208 Hz, with the accelerometer ignored mid-flick and gyro drift relearned whenever she rests.
Dynamic time warping against spell templates on the ESP32-S3 itself. No cloud and no training set.
MQTT with Home Assistant discovery: every spell arrives as a device trigger, ready for automations.
An LRA haptic signature per spell, a light-piped tip, and deep sleep until an IMU interrupt notices you've picked her up.
II The spellbook
Draw a spell with your mouse or finger. This is the same recognizer that runs on the wand, ported line for line to JavaScript and checked against the firmware's unit tests.
Cast something worthy of her attention.
Go on, then. Impress me.Malfoid
The mark on the meter is her acceptance threshold. She also refuses when the runner-up is within 5%, because ambiguity is beneath her.
III Anatomy
About 360 mm of wand. The electronics live in the handle, a 3 mm optical fibre carries the light to the tip, and the motion sensor sits close to your wrist, where flicks distort it least.
IV Under the hood
Sensing runs in its own FreeRTOS task, woken by the IMU's data-ready interrupt. Everything else, from recognition to Wi-Fi and haptics, waits its turn.
Gyro and accelerometer are read over I²C on every data-ready pulse.
208 Hz · ±2000 dps · ±8 gMadgwick AHRS. Gyro bias is relearned at rest; the accelerometer is ignored mid-flick.
β 0.08 · 0.85–1.15 g gateTip direction becomes azimuth and elevation relative to where the cast began. Wrist roll cancels out.
104 points / s32 equidistant points. Lines keep their aspect ratio; shapes are squared up by principal axes.
32 × (x, y)Dynamic time warping in a Sakoe–Chiba band against every template. The winner must beat the runner-up.
≈1 ms on the ESP32-S3Tip light, a haptic signature, and an MQTT message that Home Assistant can turn into anything.
MQTT · device triggers# every cast, as your broker sees it $ mosquitto_sub -t 'malfoid/#' -v malfoid/a1b2c3/status online malfoid/a1b2c3/spell lumen malfoid/a1b2c3/state {"battery":76, "voltage":3.93, "charging":false, "last_spell":"lumen", "rssi":-58} malfoid/a1b2c3/spell malfoid # her signature, obviously
# automations.yaml - or build it in the UI: Device → Malfoid - alias: "Lumen turns the lights on" triggers: - trigger: mqtt topic: "malfoid/+/spell" payload: "lumen" actions: - action: light.turn_on target: entity_id: light.living_room
// newline-delimited JSON over USB serial → {"cmd":"hello"} ← {"evt":"hello","fw":"0.1.0","board":"xiao-s3","spells":[…]} → {"cmd":"record","name":"Accio"} ← {"evt":"armed","id":"accio"} ← {"evt":"cast","ok":true,"id":"malfoid", "score":0.91,"ms":840,"pts":[[-0.5,-0.5],…]}
Every spell is also announced to Home Assistant as a device trigger, so no YAML is needed.
V Build her
Start with breakout boards on a free afternoon, or go all the way with the Malfoid Core, an 18 × 92 mm four-layer board designed to live inside the handle.
| Specification | Path ABreakout buildStart here | Path BMalfoid Core rev A |
|---|---|---|
| Brain | Seeed Studio XIAO ESP32S3 | ESP32-S3-MINI-1-N8 on the Core board |
| Sensors & output | LSM6DSOX, DRV2605L + LRA and MAX17048 on STEMMA QT breakouts, one SK6812 | The same parts placed for a wand: IMU at the wrist pivot, power-gated LED behind a level shifter |
| Power | XIAO's onboard charger, 1S LiPo 400–500 mAh | USB-C, MCP73831 with load sharing, TPS63802 buck-boost, 14500 Li-ion 800 mAh |
| Asleep | ~1–3 mA (about 0.3 mA with breakout LEDs cut) | ~40–60 µA estimated, about 9 weeks of typical use |
| Soldering | A few wires; everything else plugs in | Fine-pitch SMD, or a PCB assembly service |
| Firmware | pio run -e xiao | pio run -e core |
VI Wand console
Plug in the wand and connect from this page. You can watch the tip move live, inspect every cast, set up Wi-Fi and MQTT, and teach her new spells. Everything travels over the cable; nothing leaves your browser.
Name it, press record, then cast once. Recording under an existing name, like lumen, adds your handwriting as an extra template.
Play any spell's light and haptics on the wand, or send her to sleep.
VII Flash from the browser
Every push to main is built by GitHub Actions and published right here, ready to install.
Checking for published firmware…
VIII Patronage
Malfoid is free and open: firmware, hardware and this site. Sponsorship pays for PCB revisions, actuator samples and the measurement gear that turns estimates into real numbers. She has expensive taste, and so does good hardware.
Your name in SPONSORS.md, and her grudging respect.
Vote on the next spell and get early firmware builds.
Your initials on the next PCB revision's silkscreen.
Your logo on this page and a say in the hardware roadmap.
IX Credits
Original artwork. The Malfoid cameo, the wand illustrations, the crest and the icons were drawn for this project. No film imagery or fan art is used.
Free to reuse with credit under CC BY 4.0. PNG and SVG files are in docs/assets.