Creative Hardware

Falling Sand in CircuitPython, Because Python Got Fast Enough

Adafruit's new PixelDust guide runs a particle simulation that used to need compiled C — on a Metro RP2350, in Python, thanks to Turbo modules and Picogame.

Falling-sand simulations are one of the great microcontroller demos: tilt the board, the pixels pour, and the illusion of physical material in a grid of LEDs is immediate and oddly satisfying. Adafruit’s PixelDust library has been behind a lot of them.

It has also, until now, always meant Arduino, or something Linux-class. Sand requires updating thousands of particles per frame with gravity and collision, and that is the kind of tight inner loop where interpreted Python historically falls over.

A new Adafruit learn guide does it in CircuitPython.

Adafruit’s demonstration of the CircuitPython version running on hardware.

What changed

Two things, per Adafruit’s own framing:

Turbo modules, compiled with Viper. CircuitPython is “shifting gears into Turbo,” and Turbo modules compiled with Viper can “crunch numbers super fast. Numbers like the ones used to simulate gravity and collisions for a lot of particles.”

Picogame for rendering. Picogame “is more efficient at rendering canvas-style graphics of this sort than displayio, which keeps the demo rendering smoothly on the Metro RP2350 + TFT Shield.”

The guide covers two builds: the Metro RP2350 with a TFT shield, and the Matrix Portal for an LED matrix version.

What Viper actually is, and why it matters more than it sounds

Viper is a code emitter, not a library. MicroPython — which CircuitPython derives from — supports decorators that change how a function is compiled:

  • @micropython.native compiles to machine code instead of bytecode, while keeping full Python object semantics
  • @micropython.viper goes further: it uses native machine types (int, ptr32, ptr8) rather than Python objects, and skips the boxing, reference counting and dynamic dispatch that make Python slow

A Viper function is Python-shaped source that compiles to something much closer to C. You lose most of Python’s dynamism inside that function — no arbitrary objects, restricted types, careful manual indexing — and in exchange you get an order-of-magnitude-class speedup on numeric loops.

That trade is exactly right for a particle simulation, because the structure of the problem is a small, hot, numeric kernel inside a large, comfortable, dynamic program. The sand physics is maybe fifty lines that run thousands of times a frame. Everything else — setup, display config, reading the accelerometer, the user’s own modifications — has no performance requirement at all.

The real significance: where the language boundary sits

For most of microcontroller history the choice was binary and up-front: either your project is C/C++ and you accept a compile-flash-test cycle and manual memory management, or your project is Python and you accept that anything computationally serious is off the table.

That boundary is what has actually shaped what people build on these boards. Plenty of creative-hardware projects got written in C not because the author wanted to, but because one loop somewhere needed to be fast.

Viper-compiled kernels move the boundary inside a single file. You write the project in CircuitPython, and the three functions that need to be fast get a decorator. No toolchain, no build step, still editable by dragging a file onto a USB drive — which remains CircuitPython’s genuine superpower and the reason it is the right first environment for artists and beginners.

Picogame is the same argument applied to graphics. displayio is CircuitPython’s general-purpose display stack: retained-mode, object-based, it manages a scene graph of sprites and groups and works out what changed. That is exactly what you want for a UI and exactly what you don’t want for a full-canvas simulation where every pixel changes every frame. Picogame’s canvas-style immediate-mode approach skips the bookkeeping.

What to build with it

The sand demo is the hook; the capability is the point. Things that were previously “write it in C or don’t bother” and are now plausibly CircuitPython:

  • Cellular automata of all kinds — Game of Life, reaction-diffusion, Wolfram rules on a strip
  • Flocking and boids on a small display
  • Audio-reactive particle systems, which need both FFT and per-particle updates
  • Real-time image effects — dithering, palette cycling, feedback buffers
  • Generative visuals on battery, where the RP2350 plus a display is a complete, tiny, self-contained piece

And the accelerometer-plus-sand combination remains one of the best demonstrations of physical computing there is, because the input is your hand and the output is immediately, wordlessly legible. It is a very good first project for someone who has never written a loop.