
Flexcircuit
earlynerd/bl4818-servo-M23
This repository contains the electronics, embedded firmware, host software, and browser players for a network of brushless servo percussion actuators.

This repository contains the electronics, embedded firmware, host software, and browser players for a network of brushless servo percussion actuators.
Interface is an open-source printed circuit board by earlynerd, from the earlynerd/bl4818-servo-M23 repository on GitHub. It is a 4-layer board of 46.3 × 37.7 mm with 20 parts on 15 nets, routed with 83 tracks and 74 vias.
It is built around the MT6701CT-STD, SMAJ20CA and SMAJ6.0A. Its parts include 10 capacitors, 5 connectors, 3 diodes, 1 resistor and 1 IC. It belongs with the robots and motor control and interfaces and adapters boards of this library.
This repository contains the electronics, embedded firmware, host software, and browser players for a network of brushless servo percussion actuators. The actuators use modified BL4818 motor-controller hardware, a Nuvoton M2003 microcontroller, hall sensing, and an MT6701 absolute encoder to move a mallet with controlled timing and force.
The system is in active use: roughly 35 actuators have been built, and the firmware plus MIDI player/server are working well. The software is much closer to production-ready than the replication documentation, so this repository should currently be treated as a proven project under documentation rather than a turn-key kit.
check out video of these actuators playing various instruments on my Instagram!



Each self-contained actuator packages the modified BL4818 motor controller, absolute encoder, power/data interface, and mallet mechanism inside the printed shell. RX and TX connectors allow power and serial data to continue through the actuator chain, while the recessed SWD port provides programming access.
flowchart LR
MIDI["MIDI file or browser player"] --> HTTP["Python MIDI server"]
HTTP --> IFACE["USB serial / interface hardware"]
IFACE --> A0["Actuator 0"]
A0 --> A1["Actuator 1"]
A1 --> AN["More actuators"]
AN --> IFACEThe Python server owns the serial port and serves the browser UI. It enumerates the actuator ring, maps MIDI pitches to actuator addresses, schedules strikes, compensates for measured mechanical latency, and can build then deploy APROM updates through the permanent LDROM loaders without releasing the serial port. The updater and synchronized chord scheduler are hardware-validated on the 14-actuator handpan ring. Each actuator closes its own current, velocity, and position loops and runs the homing/strike state machine. The current protocol uses a four-bit address and supports up to 16 actuators per ring.
src/ and include/: M2003 bare-metal firmware.scripts/: ring-bus client, MIDI server, tuning, measurement, and demo tools.player/: browser-based MIDI player, looper, and tongue-drum player.pcb/: KiCad electronics plus current mechanical/fabrication exports.mechanical/: SolidWorks source CAD and STEP exports for the actuator shell,
mallet holder, and interface-board reference model.docs/: replication notes, hardware references, debug history, and design notes.protocol.md: byte-level Ring Bus Protocol v2 specification.midi_server_api.md: HTTP API for integrations and custom players.See Repository map for a guided tour.
The firmware builds on Windows and POSIX hosts, including Raspbian. Its Makefile
expects GNU Make and the Arm GNU toolchain in PATH. Initial SWD provisioning
still uses the PowerShell/J-Link scripts and is therefore Windows-oriented.
Install Python 3.10 or newer, then from the repository root run:
py -m venv .venv
.\.venv\Scripts\Activate.ps1
py -m pip install -r requirements.txtInstall arm-none-eabi-gcc and GNU Make, then run:
makeThe main output is build/m2003-motor.bin. Generate the complete J-Link
payload (application, commit manifest, permanent LDROM loader, and read-only
CONFIG capture) with:
powershell -File scripts/build-jlink.ps1Generation does not contact hardware or change CONFIG. The stable Gen1 ring updater, its recovery evidence, and its completed 14-actuator validation are documented in Ring firmware update. The LDROM loader is now maintenance-only; no further Gen1 loader features are planned.
Connect the programmer over SWD and run:
powershell -File scripts/flash-jlink.ps1For J-Link V9.58 or newer, use the faster native M2003FC1AE flash loader:
powershell -ExecutionPolicy Bypass -File scripts/flash-jlink.ps1 -NativeFlashAdd -SkipBuild to reuse the generated artifacts, or -GenerateOnly to build
them without contacting hardware. Native mode retains the CONFIG preservation,
commit-last manifest, and physical verification described below. Omitting
-NativeFlash retains the original per-word programming method.
This standard command first records CONFIG0..2, programs and byte-verifies APROM, its manifest, and LDROM, then preserves the existing configuration while selecting LDROM-first boot. It refuses automatic CONFIG changes on a locked or unexpected security configuration. Disconnect motor power while changing wiring or attaching the programmer; a servo actuator can move unexpectedly during bring-up.
Connect the interface serial port to a powered actuator ring and run:
py scripts/ring_midi_server.py -p COM7 --library-dir C:\path\to\midi-libraryOpen http://localhost:8765/. Enumerate the ring, home the actuators, and assign
a MIDI pitch to each slot before playing a file. Use the instrument selector
to save and switch named pitch maps and player settings. Profiles are stored locally in
instruments.json and are intentionally not committed. An existing
mapping.json is imported as the Default profile.
For multiple rings, use one USB adapter per ring (at most 16 actuators each):
py scripts/ring_midi_server.py --ring jameson=COM29,10 --ring retuned=COM48,10The player provides a saved-instrument selector for each ring and shared playback controls. See multiple-ring setup for profile persistence and slot routing. The Firmware panel lets you select rings to update and processes them one after another.
For a first hardware check without the browser:
py scripts/ring_tool.py -p COM7 enumerate
py scripts/ring_tool.py -p COM7 status 0Run py scripts/ring_tool.py --help for the complete command list.
The repository does not yet contain enough verified information for a new builder to safely reproduce the complete actuator without assistance. In particular, power-system limits, connector pinouts, a released BOM, mechanical assembly dimensions, and a photographed bring-up procedure still need to be documented. Those gaps are tracked explicitly in Replication status; unknown values are not guessed in the guides.
This project drives a fast moving mechanism at several amps. Use a current- limited supply during bring-up, keep hands and instruments clear of the mallet, provide a physical power disconnect, and test one actuator before assembling a ring.
No project-wide license has been selected yet. Until one is added, the source
is visible for evaluation but normal open-source reuse permissions have not
been granted. A license should be chosen before presenting the repository as a
fully replicable open-source project; third-party code under CMSIS/,
Library/, and RTT/ retains its own notices and terms.
| Qty | Value | Footprint | References |
|---|---|---|---|
| 6 | 22uF | Capacitor_SMD:C_0805_2012Metric | C3, C4, C5, C6, C7, C8 |
| 2 | 470uF | Capacitor_THT:C_Radial_D8.0mm_H7.0mm_P3.50mm | C1, C2 |
| 2 | Conn_01x05_Pin | Connector_JST:JST_PH_B5B-PH-K_1x05_P2.00mm_Vertical | J4, J5 |
| 2 | ~ | MSconnector:XT30(2+2)PB-M.G.B | J2, J3 |
| 1 | 0.1uF | Capacitor_SMD:C_0603_1608Metric | C9 |
| 1 | 100uF | Capacitor_SMD:C_1206_3216Metric | C11 |
| 1 | 1k | Resistor_SMD:R_0603_1608Metric | R3 |
| 1 | Conn_ARM_JTAG_SWD_10 | Connector_PinHeader_1.27mm:PinHeader_2x05_P1.27mm_Vertical_SMD | J1 |
| 1 | LED | LED_SMD:LED_0603_1608Metric | D2 |
| 1 | MT6701CT | Package_SO:SO-8_3.9x4.9mm_P1.27mm | U1 |
| 1 | SMAJ20CA | Diode_SMD:D_SMA | D1 |
| 1 | SMAJ6.0A | Diode_SMD:D_SMA | D3 |

earlynerd/bl4818-servo-M23
This repository contains the electronics, embedded firmware, host software, and browser players for a network of brushless servo percussion actuators.

victorstoica114/UWB_Module_ESP_IDF
ESP-IDF 6.0.2 firmware for the custom UWB Module V1.0 Rev.B, based on an ESP32-S3-WROOM-1-N16R8. The same application image runs on every module; persistent identity and runtime configuration select the role and active…

alexWandugu/4in1-ESC-STM32F407-DRV8323
Open-source 4-in-1 Electronic Speed Controller (ESC) for quadcopter BLDC motors. Features STM32F407VET6, DRV8323RS gate driver, and MCG4D8N04YHE3-TP MOSFETs. Designed for 4S LiPo (up to ~7A continuous per motor).

cs-pub-ro/smart-solar-irradiance-sensor
Open-source hardware & software for a smart wireless sensor that measures solar irradiance.

DesignStraub/ringwheel-hybrid-drone
A 5-inch FPV drone whose prop ducts fold down and become wheels. Design study in Fusion 360 and KiCad, CC BY-NC-SA 4.0.




avenhaus/SO-ARM100-Encoders
It explores to use much cheaper magnetic encoders for the Leader Arm instead of the regular servos. These dummy servos are also much easier to move manually, as there is no gear train that needs to back drive the servo…
It measures 46.3 × 37.7 mm and has 4 copper layers, 1.6 mm thick.
20 parts, built around the MT6701CT-STD, SMAJ20CA and SMAJ6.0A. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.
From the earlynerd/bl4818-servo-M23 repository on GitHub, at the commit this page was made from: the board is pcb/interface/interface.kicad_pcb and its schematic pcb/interface/interface.kicad_sch. PCBKit opens the board in the browser, with nothing to install.
Its repository states no licence, so its author keeps all rights: ask earlynerd before reusing the design.