Skip to the content
2 layers163.8 × 52.4 mmSolenoid driver v2, the printed circuit board in 3D

Solenoid driver v2

jboymel/piano-robot

Modular solenoid-based robotic piano actuator system — Northwestern SURG 2026

Size
163.8 × 52.4 mm
Copper layers
2
Thickness
1.6 mm
Parts
75
Nets
48
Pads
192
Tracks, vias
512, 42
Pours
2
Routed
Yes
KiCad
KiCad 10.0 (file 20260206)
Created
17 Jun 2026
Updated
27 Sep 2026

Overview

Solenoid driver v2 is an open-source printed circuit board by jboymel, from the jboymel/piano-robot repository on GitHub. It is a 2-layer board of 163.8 × 52.4 mm with 75 parts on 48 nets, routed with 512 tracks and 42 vias.

It is built around the 74HC595, FR307 and IRLZ44N, with the SMBJ28A among its other parts. Its parts include 24 resistors, 16 connectors, 13 diodes, 12 transistors and 4 capacitors. It belongs with the robots and motor control boards of this library.

Main components

4

README

README.md

Modular Robotic Actuation System for Piano Key Control

A modular, clamp-on solenoid system that plays an acoustic piano from a MIDI score. Scaled from a one-octave prototype to a 7-octave (84-key) array of daisy-chained driver boards.

Northwestern University · Summer Undergraduate Research Grant (SURG) 2026 Jordan Boymel · Advisor: Dr. Brenna Argall, Assistive & Rehabilitation Robotics Lab, Shirley Ryan AbilityLab

Robot mounted on the piano

Status (Sept 2026): hardware, firmware, and host software complete; full-scale tuning paused. The whole pipeline, from MIDI to solenoids, runs. The final demo used a lower-rated 24 V supply because the main supply couldn't be wired properly, and several actuators strike inconsistently. See Current status and known issues.


Why

Self-playing pianos are purpose-built, expensive instruments. This project asks whether a modular attachment can turn an ordinary piano into a music-making machine instead. It is motivated by making piano playing accessible to people with motor disabilities, and by the number of acoustic pianos that sit unused.

What I built

AreaWhat it is
Driver electronicsCustom 2-layer KiCad PCB, one per octave: 12 low-side MOSFET channels, flyback protection, and a shift-register serial interface. Boards daisy-chain for power and signal.
Actuation24 V push-pull solenoids (one per key) with a threaded felt-tipped striker
MechanicalParametric Onshape bracket that straddles 80/20 T-slot extrusion over the keybed. Key pitch was measured on a real piano.
FirmwareArduino Mega sketch that receives full keyboard state over USB serial and clocks it to the shift-register chain, with safety interlocks
Host softwarePython player that reads a MuseScore MIDI export, compensates for actuator latency, and streams frames to the Arduino

System architecture

The Arduino connects to the whole 84-key array through five wires: 5 V, GND, DATA (pin 51), CLOCK (pin 52), and LATCH (pin 8).

Hardware

Octave driver board

Octave driver board
  • 163.8 × 52.4 mm, 2-layer. Four M3 mounting holes on a 155.8 × 44.4 mm pattern.
  • Two 74HC595 shift registers per board, in DIP sockets and cascaded (U1 QH′ → U2 SER). 12 of 16 outputs are used. SRCLR is tied high and OE is tied low.
  • 12 × IRLZ44N logic-level MOSFETs (55 V VDS), low-side switching, TO-220 mounted vertically to save board depth.
  • FR307 flyback diode across each solenoid, and an SMBJ28A TVS diode for transient protection.
  • Each MOSFET gate has a 220 Ω and a 10 kΩ resistor.
  • GND pour on B.Cu and +24 V on F.Cu. Trace widths sized to IPC-2152 for solenoid current.
  • Power in/out: screw terminals J15 → J16 pass the 24 V bus board-to-board on heavy wire. Logic signals chain separately on a 5-conductor ribbon.
  • First spin fabricated by JLCPCB. Seven boards assembled.

Actuators and strikers

  • JF-1039B push-pull solenoid: 25 N, 10 mm stroke, about 400 mA at 24 V.
  • Striker: an M4 × 0.7 coupling nut threads onto the plunger, with a 3/8″ felt pad on the contact face to protect the keys and soften the attack.

Mounting bracket

Parametric bracket
  • An asymmetric inverted-U saddle that straddles 80/20 T-slot extrusion. It is fully parametric in Onshape.
  • Key pitch was measured on a real piano and adjusted from 23.4 mm to about 23.5 mm. The standoff inset is a parameter, so the bracket stays compatible with the PCB hole pattern.

Power

  • 24 V solenoid bus: a single 1500 W (62.5 A) switching supply, chained board-to-board.
  • 5 V logic: supplied from the laptop over the Arduino's USB connection and carried to every board on the signal ribbon.
  • All grounds are common.

Firmware and control

Serial protocol (host → Arduino)

FieldBytesValue
Sync20xAA 0x55
Key state1184 bits, one per key (1 = energized)
Checksum1XOR

Sent at 250000 baud. Every frame carries the full keyboard state. The Arduino never has to reconstruct note-on/note-off history, so a dropped frame is simply replaced by the next one.

Safety limits (firmware)

LimitValuePurpose
MAX_SIMULTANEOUS20 keysCaps solenoid current at about 8 A
MAX_ON_MS5000 msReleases any key held too long, which protects the coils from overheating
LINK_TIMEOUT_MS500 msReleases all keys if the host stops sending valid frames

Latency compensation (host)

Measured strike latency is about 50 ms from energize to key contact. musescore_player.py schedules every note ATTACK_LATENCY_MS (≈50 ms) early so strikes land on the beat. It also enforces MINIMUM_STRIKE_HOLD_MS (≈10 ms) so very short notes still fully depress the key.

The latency also sets a mechanical limit: repeated notes on the same key top out around sixteenth notes at 95–100 BPM.

Design evolution

The project started as a one-octave bench prototype focused on characterizing a single key. The table lists the major changes on the way to 84 keys.

ChangeWhy
One Arduino pin per key → 74HC595 shift-register chain84 keys can't each get a pin. Three signal lines now drive any number of boards.
IRLB8721 (30 V) → IRLZ44N (55 V)More drain-voltage margin against inductive switching transients on a 24 V rail
3-tier PCB stack → 2 tiersThe FSR circuit was confirmed as instrumentation only, not part of the production drive path
One large board → one PCB per octave, daisy-chainedIdentical boards are cheaper to fabricate, easier to debug, and scale to any number of octaves
Key pitch 23.4 mm → ≈23.5 mmMeasured on a real piano. The error accumulates across an octave.

Peer review of the schematics caught wiring errors before fabrication, including flyback diode polarity and MOSFET pinout.

Current status and known issues

Works

  • Seven octave boards assembled and running on one chain.
  • Firmware, serial protocol, and safety limits are working.
  • The Python player drives the array from MuseScore MIDI.
  • The shift-register chain was validated with indicator LEDs before solenoids were connected.

Resolved

  • Chain failure when scaling from 3 to 7 boards. The symptoms looked like a power-budget problem, but the cause was one shift register seated backwards in its socket. Write-up: docs/power-debugging.md.

Known issues

  1. Demo run on an underpowered 24 V supply. The main 1500 W supply couldn't be wired in time for the final demo because the right-gauge wire was missing, so a lower-rated supply stood in.
  2. Inconsistent strikes on some actuators. Not yet diagnosed. An under-supplied 24 V rail (issue 1) is the first suspect. Solenoid, striker, or mounting variation still has to be ruled out once the main supply is connected.

Next steps

  • Wire in the main 24 V supply and re-test all 84 channels.
  • Diagnose the inconsistent actuators channel by channel (current draw, stroke, striker seating).
  • Quantify timing and force consistency. The original proposal set targets (mean onset error under 10 ms, standard deviation under 5 ms, force coefficient of variation under 15%) and planned an FSR 402 and TCST2103 photointerrupter rig to measure them. That rig was prototyped on the bench but not used in the final build, and no characterization data has been collected yet.
  • Record a clean full-keyboard demo.

Lessons learned

  • Check the assembly before redesigning the system. The failure at 7 boards looked like a supply problem, and I had started planning a separate 5 V supply. The actual cause was one reversed IC.
  • Scale in steps and test at each one. Adding boards incrementally narrowed the fault to the new part of the chain.
  • Design reviews pay for themselves. Wiring errors were caught on paper instead of on a powered board.

Repository layout

text
firmware/
  piano_driver/        piano_driver.ino: Arduino Mega sketch (serial → shift-register chain)
  bench_test/          serial_logger.py: logger from the single-key bench prototype
host/                  midi_player.py: MIDI file → serial key-state frames
hardware/
  pcb/                 KiCad project (solenoid-driver-v2) and fabrication Gerbers (.zip)
cad/
  stl/                 bracket.stl
matlab/analysis/       analyze_trials.m: trial statistics (onset time, force)
docs/                  BOM, wiring, schematic PDF, chain-failure write-up
media/                 Photos, KiCad render, test videos

matlab/analysis/analyze_trials.m generates placeholder data if no real trial CSV is present. Any plots it produces without real data are not results.

Bill of materials and wiring

Parts

75
QtyValueFootprintReferences
1210kΩResistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_HorizontalR1, R3, R5, R7, R9, R11, R13, R15, R17, R19, R21, R23
12220ΩResistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_HorizontalR2, R4, R6, R8, R10, R12, R14, R16, R18, R20, R22, R24
12FR307Diode_THT:D_DO-201AD_P15.24mm_HorizontalD2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13
12IRLZ44NPackage_TO_SOT_THT:TO-220-3_VerticalQ1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12
12Screw_Terminal_01x02TerminalBlock_Phoenix:TerminalBlock_Phoenix_MKDS-1,5-2-5.08_1x02_P5.08mm_HorizontalJ1, J2, J3, J4, J5, J6, J7, J8, J9, J10, J11, J12
4MountingHoleMountingHole:MountingHole_3.2mm_M3H1, H2, H3, H4
20.1µFCapacitor_THT:C_Disc_D5.0mm_W2.5mm_P2.50mmC3, C4
274HC595Package_DIP:DIP-16_W7.62mm_SocketU1, U2
2Conn_01x05_PinConnector_PinHeader_2.54mm:PinHeader_1x05_P2.54mm_VerticalJ13, J14
2Screw_Terminal_01x02TerminalBlock_Phoenix:TerminalBlock_Phoenix_MKDS-3-2-5.08_1x02_P5.08mm_HorizontalJ15, J16
11000µFCapacitor_THT:CP_Radial_D10.0mm_P5.00mmC2
110µFCapacitor_THT:CP_Radial_D5.0mm_P2.00mmC1
1SMBJ28ADiode_SMD:D_SMBD1

Similar boards

  • 2 layers105 × 50 mmMagneto chico, the printed circuit board in 3D

    Magneto chico

    MarianoDel/kicad_magneto_chico

    Placa para el magneto chico

    53 parts
  • 2 layersTIP122Board, the printed circuit board in 3D

    TIP122Board

    jibonaronno/documentsA

    It is required to change settings using SCLManager.exe when required for new setup.

    82 parts4
  • 2 layers99.1 × 99.1 mmFlipDotDriver, the printed circuit board in 3D

    FlipDotDriver

    bitluni/FlippyFlip

    49 parts14
  • 4 layers71.3 × 95.9 mmChessBotController, the printed circuit board in 3D

    ChessBotController

    cryptoAlgorithm/chess-printer

    A chess bot, but on steroids. Custom 3D printer control board with a few oddly specific features.

    55 parts3
  • 2 layersOrgan Serial to Parallel, the printed circuit board in 3D

    Organ Serial to Parallel

    locokepler/Pipe_Organ

    The repository of the pipe organ, over the different iterations of mechanical, electrical, and code design

    105 parts2
  • 2 layers163.5 × 55 mmIROC U Charging NMOS, the printed circuit board in 3D

    IROC U Charging NMOS

    24bec124-sketch/IROC-U-Charging-NMOS

    Developed for Team Arrow as part of IRoC-U (ISRO Robotics Challenge - URSC), a national student competition hosted by the Indian Space Research Organization (ISRO).

    41 parts1MIT

Questions

How big is the Solenoid driver v2 PCB?

It measures 163.8 × 52.4 mm and has 2 copper layers, 1.6 mm thick.

What parts does the Solenoid driver v2 use?

75 parts, built around the 74HC595, FR307, IRLZ44N and SMBJ28A. 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.

Where can I download the Solenoid driver v2 KiCad files?

From the jboymel/piano-robot repository on GitHub, at the commit this page was made from: the board is hardware/pcb/solenoid-driver-v2.kicad_pcb and its schematic hardware/pcb/solenoid-driver-v2.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the Solenoid driver v2 design in my own project?

Its repository states no licence, so its author keeps all rights: ask jboymel before reusing the design.