A ferrofluid electromagnetic display driven by a 4×4 coil array, with a physics simulation suite and a reservoir computing research harness. The simulation and firmware are complete — the physical hardware build is in progress.
FerroBot has two goals:
1. Display platform — A 4×4 grid of electromagnets shapes ferrofluid into dynamic formations in real time. An Arduino + PCA9685 PWM driver controls the array, with a Python control stack and an LLM agent for natural-language pattern commands.
2. Physical reservoir computer — The central research question: can a ferrofluid surface controlled by electromagnets function as a physical reservoir computer, with peak computational capacity occurring near the Rosensweig instability threshold (edge of chaos)?
The hypothesis is that near the critical field Hc — where surface tension and magnetic pressure balance and spikes first emerge — the fluid dynamics are rich enough to perform nonlinear computation (benchmarked on NARMA-10) without any trained parameters. The edge-of-chaos connection is the core claim.
A paper writeup is in progress (paper.tex).
Three simulation iterations, each building on the last.
- 16×16 coil array (configurable)
- 8 artistic wave patterns (traveling sine, circular ripples, interference, spiral, standing wave, etc.)
- Verlet integration with magnetic, gravity, viscous damping, and surface tension forces
- Nonlinear Langevin saturation curve (tanh approximation)
- Real-time 3D matplotlib visualization
- Adds spike formation physics: Rosensweig instability above critical field threshold
- Hexagonal packing preference (energetically favored spike arrangement)
- Magnetic hysteresis — spikes persist when field drops slightly below Hc
- Labyrinth mode via reaction-diffusion (Turing mechanism)
- 4 modes: smooth waves, discrete spikes, hybrid, labyrinth
- Tuned for 4×4 build: 16 coils, 40mm spacing, 100ml ferrofluid
- Full thermal model — per-coil temperature tracking, duty cycle limiting, burnout prevention
- 8 patterns specifically designed for the 4×4 geometry
- Arduino serial hooks (
send_to_arduino()) wired but pending hardware validation
python simulation.py # baseline waves
python simulation2.py # Rosensweig instabilities
python simulation3.py # hardware-targeted with thermal limitsrc_harness.py benchmarks the ferrofluid as a reservoir computer on the NARMA-10 task (10th-order nonlinear autoregressive moving average — a standard dynamical systems benchmark).
Two physics modes:
- IIR spike mode — exponential smoothing, collapses to rank-1
- Wave mode — 2D damped wave equation with capillary and gravity terms, maintains higher effective rank
Sweep experiments:
- Bias sweep — varies DC operating point from 0 to 4×Hc, looks for NRMSE minimum near threshold
- Amplitude sweep — varies input signal gain
- Rank analysis — effective rank via singular value entropy (Roy & Vetterli 2007), plotted against bias
The hypothesis is supported if NRMSE is minimized in [0.7 Hc, 1.5 Hc].
python rc_harness.py --mode bias # sweep DC operating point
python rc_harness.py --mode amplitude # sweep input gain
python rc_harness.py --mode rank # effective rank vs biasMagnetic field — Superposition of inverse power-law fields from all coils:
H(r) = Σ intensity[i] / (ε + |r - r_i|^α)
where α = FIELD_DECAY ≈ 1.8, ε prevents singularity.
Ferrofluid response — Nonlinear Langevin saturation:
M_eff = M_sat × tanh(H / M_sat)
Rosensweig instability — Spikes form when magnetic pressure exceeds surface tension:
Critical wavelength: λ_c ≈ 2π √(σ / ρgH_c) ≈ 8–12mm for EMG-series fluids
Above Hc, local field maxima nucleate spikes with Gaussian spatial profiles and hexagonal packing preference. Hysteresis window prevents rapid oscillation at threshold.
Build status: in progress. Firmware is complete and ready. Physical assembly underway.
| Component | Spec | Qty | Est. Cost |
|---|---|---|---|
| Electromagnets | 12V, ~1A, 30mm dia | 16 | $56 |
| PCA9685 PWM driver | 16-channel, I2C | 1 | $8 |
| Arduino Mega/UNO | Any with I2C + UART | 1 | $15 |
| TIP120 Darlington transistors | + 1kΩ base resistor each | 16 | $8 |
| 1N4004 flyback diodes | Inductive kick protection | 16 | $3 |
| 12V 20A power supply | 240W, headroom for full array | 1 | $25 |
| DS18B20 temperature sensors | OneWire, per-coil monitoring | 4+ | $12 |
| Ferrofluid | EMG-627 or similar, 100ml | 1 | $40 |
| Acrylic container | 160×160mm, 30mm deep | 1 | $50+ |
| Frame / coil mount | 3D printed or wood | 1 | $15 |
Array geometry: 4×4 coils, 40mm spacing → 160×160mm active area. Coils mounted 25mm above fluid surface for optimal field coupling.
Power budget: 8.4W per coil at 70% duty cycle → 134W sustained. PWM hard-capped at 70% in firmware and simulation.
See wiring_diagram.png or regenerate with:
python wiring_diagram.pyArduino UNO → PCA9685 (I2C, 400 kHz) → TIP120 per coil → 12V electromagnet. DS18B20 on pin 2 (OneWire).
firmware/ferrobot/ferrobot.ino — Arduino firmware, no external libraries.
- PCA9685 driven over bare I2C (no Adafruit library dependency)
- DS18B20 temperature readout via bit-bang OneWire on pin 2
- Serial protocol:
- Control packet:
[0xFF, pwm0…pwm15, 0xFE](18 bytes, 20 Hz) - Temperature request:
0xFD→ responds with int16 in tenths of °C
- Control packet:
- Safety: 5-second watchdog ramps all coils to zero if host goes silent
- Gradual ramp-down (5 PWM units / 50ms) prevents thermal shock
Flash with Arduino IDE or arduino-cli.
python -m ferrobot # interactive CLI with LLM agent
python -m ferrobot --sim # simulation mode (no serial required)
python -m ferrobot --no-agent # cycle patterns without LLM
python test_coil.py # single-coil hardware test
CLI commands:
/patterns list available patterns
/set <name> switch to named pattern
/status coil temperatures + current pattern
/stop zero all coils
/sim toggle simulation mode
/quit exit
Natural language commands go to the LLM agent (OpenAI-compatible endpoint, configurable in ferrobot/config.py). The agent controls patterns, individual coils, and intensity in response to free-form instructions.
simulation.py Baseline physics + waves
simulation2.py Rosensweig instability + labyrinth modes
simulation3.py Hardware-targeted, thermal limits, Arduino hooks
rc_harness.py Reservoir computing benchmark (NARMA-10)
test_coil.py Single-coil serial test harness
wiring_diagram.py Generates wiring_diagram.png
paper.tex / .pdf Research paper (in progress)
ferrobot/
├── config.py Hardware defaults + serial config
├── controller.py Serial bridge to Arduino/PCA9685
├── patterns.py Pattern registry + thermal model
├── agent.py LLM-driven command interface
├── llm_client.py HTTP client for OpenAI-compatible LLM
└── cli.py Terminal REPL
firmware/
└── ferrobot/
└── ferrobot.ino Arduino firmware
pip install numpy scipy matplotlib scikit-learn pyserialVisualization requires matplotlib with a GUI backend (TkAgg or Qt5Agg). Serial communication requires pyserial and an Arduino running the firmware. Simulation mode works without hardware.
| Component | State |
|---|---|
| Simulation (all 3 iterations) | ✅ Complete |
| Rosensweig physics model | ✅ Complete |
| Reservoir computing harness | ✅ Complete |
| Arduino firmware | ✅ Complete |
| Python control stack + CLI | ✅ Complete |
| LLM agent integration | ✅ Complete |
| Physical hardware build | 🔧 In progress |
| RC validation on real hardware | ⏳ Pending build |
| Paper | ✍️ In progress |