Skip to content

Latest commit

 

History

37 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CYD Physarum

A slime mold simulation for the ESP32 Cheap Yellow Display, in 2.4, 2.8 and 3.5 inch.

Physarum running on a 3.5 inch Cheap Yellow Display

Five hundred agents lay chemical trails and steer toward the strongest one they can sense. That single rule is enough to reproduce how Physarum polycephalum, a single cell with no brain, finds efficient routes between food.

Nothing on the panel is drawn. The branching networks are what the agents leave behind. The trail field decays, but the screen never clears, so what you see includes every route the colony has already abandoned.

Ported from Physarum Lab, which runs the same model in WebGL.

Flash it from your browser: cydphysarum.variable.gallery


Flash it

Plug the board into a computer with a data USB cable. Open cydphysarum.variable.gallery, pick your board, pick a seed, press install. Nothing to download, and no toolchain.

Web Serial is required. Recent Chrome, Edge, Opera and Firefox have it. Safari and mobile browsers do not, so the page also hands you the firmware, a seed file, and the one esptool command that writes both.

On Linux the browser needs permission for the serial device:

sudo usermod -aG dialout $USER

Then log out and log in again. A new terminal is not enough, because the browser must restart before it picks up the new group.

Supported boards

Env SKU Size Resolution Controller Backlight
cyd24 ESP32-2432S024R 2.4" resistive 320 × 240 ILI9341 / ST7789 GPIO 21
cyd24c ESP32-2432S024C 2.4" capacitive 320 × 240 ILI9341 / ST7789 GPIO 27
cyd28 ESP32-2432S028R 2.8" resistive 320 × 240 ILI9341 GPIO 21
cyd35 ESP32-3248S035R 3.5" resistive 480 × 320 ST7796 GPIO 27

The same board photographed from further back, on its packaging

Every one of these is a plain ESP32-WROOM-32: dual core, 240 MHz, 4 MB of flash, no PSRAM. They wire the display the same way, so one binary drives any of them. It picks the init sequence, the backlight GPIO and the simulation tuning from the board you name.

You do have to name it. Read Notes for CYD owners for why.

Seeds

The seed fixes the colour palette and the character of the colony. The same seed always grows the same organism, so a specimen you like is a number you can write down and flash again.

The installer page grows a colony in the background while you choose. The board and the page build their palettes from the same generator, so the seed you pick is the palette you get on the panel. The exact shape differs, because the panel grid is not the size of a browser window.

The seed is not compiled in. It lives in a 4 KB config partition that the installer writes, so a change never needs a rebuild. Three modes:

  • a seed you choose,
  • a random seed, picked once at install time,
  • a new random seed on every power-on.

Build from source

pio run -e cyd35  -t upload    # 3.5"  ESP32-3248S035R
pio run -e cyd28  -t upload    # 2.8"  ESP32-2432S028R
pio run -e cyd24  -t upload    # 2.4"  ESP32-2432S024R
pio run -e cyd24c -t upload    # 2.4"  ESP32-2432S024C
pio device monitor

Add --upload-port /dev/ttyUSB0 (or COMx) if the wrong port is picked. Hold BOOT during the upload if the board is not detected.

The env sets only the default board. A config sector written by the web installer overrides it, so a board flashed from the browser is right whichever env built the image.

pio run -t upload does not touch the config partition, so a seed set by the installer survives a reflash. To go back to a random seed:

esptool.py erase_region 0x300000 0x1000

How it works

Each agent holds a position and a heading. Every frame it does four things:

  1. Read the trail field at three points ahead: left, centre, right.
  2. Turn toward the strongest of the three.
  3. Move one step and deposit into the trail field.
  4. Eat any food under it.

The trail field then blurs by one cell and decays a few percent. That is the whole model. Networks appear because a deposit makes a route more attractive, and an attractive route collects more deposits.

Left alone, the colony settles into stripes. Two mechanisms stop it. Food clusters respawn into empty areas, which drags the colony across the panel. A hash of the trail field is sampled every few seconds, and when it stops changing, the agents scatter and fresh food scatters with them.

The model is in src/SlimeMold.cpp. The installer page runs the same model in JavaScript, in web/src/lib/physarum.ts.

Layout

include/Panel.h        multi-board driver and the board profile table
src/Panel.cpp
include/Palette.h      seeded palette, shared with the installer page
src/Palette.cpp
include/DeviceConfig.h seed and board record in the config partition
src/DeviceConfig.cpp
include/Tuning.h       simulation tuning, chosen at runtime from panel size
include/SlimeMold.h    simulation
src/SlimeMold.cpp      the agent model
src/main.cpp           bring-up and the serial boot report
partitions.csv         factory app plus a 4 KB config partition at 0x300000
platformio.ini         one env per board
scripts/build-firmware.sh  builds and packages the web-flashable image
web/                   SvelteKit installer, cydphysarum.variable.gallery

Two ports that must agree

Two pairs of files implement the same function twice, once in C++ and once in TypeScript. Change one and you must change the other.

C++ TypeScript Why
src/Palette.cpp web/src/lib/palette.ts The page previews the palette the board will use
src/DeviceConfig.cpp web/src/lib/installer.ts The page writes the config record the board reads

Both are verified rather than assumed. The palette generator produces identical RGB on an ESP32 and in Node across eight seeds, including 0 and values above 2³¹. The config record is checked byte for byte, 504859530100020040e2010001000000e8069f4d on both sides.

The CRC in the config record is a plain CRC-32, written out longhand on both sides instead of calling the ESP ROM crc32_le, so the two are provably the same function. They meet only on real hardware, where a mismatch would be silent.

SeededRandom in the C++ port reproduces JavaScript number semantics on purpose. Every intermediate is kept in the width JS would use, int32 for the state and uint32 for the result, with the products computed in int64 before truncation. Do not simplify those casts.

Boot report

src/main.cpp prints a stable key=value block that the installer parses:

physarum:begin
panel=CYD 3.5"
sku=ESP32-3248S035R
panel_source=config
panel_id=0x7FDF00
resolution=480x320
seed=123456
seed_source=configured
physarum:end

panel_source is config when the installer wrote it, or build-default when the env did. seed_source is configured or random. panel_id is diagnostic only, and on these boards it is expected to be meaningless.

Config partition

One packed little-endian record, at 0x300000:

Offset Size Field
0 4 magic 0x53594850 (PHYS)
4 2 version (1)
6 2 board: 0 build default, 1 CYD 2.8", 2 CYD 3.5", 3 CYD 2.4"R, 4 CYD 2.4"C
8 4 seed
12 4 flags, bit 0 = reseed on every boot
16 4 CRC-32 of the first 16 bytes

Board values are append-only, so a sector written by an older installer keeps its meaning. A bad magic, version or CRC counts as blank, which means a random seed and the board compiled into the build.

The web installer

cd web
npm install
npm run dev            # http://localhost:3000
npm run build          # static site in web/build

To rebuild the image the site serves:

./scripts/build-firmware.sh

This merges bootloader, partition table and application into one image at offset 0x0 with esptool merge_bin, and writes it into web/static/firmware/ next to firmware.json. That file carries the config partition offset, so the offset is defined in one place. The artefacts are committed, so any static host can serve the site without a C toolchain.

The merged image uses DIO flash mode, inherited from the framework bootloader through --flash_mode keep. Every CYD flash chip accepts it. Local pio run builds still use QIO.

Credits

Built by Shahab Nedaei for variable.gallery.

Sibling of Physarum Lab, which runs the same organism in WebGL across Euclidean, hyperbolic and Nil geometries.

License

MIT. See LICENSE.

About

Slime Mould (Physarum) for any CYD

Topics

Resources

Stars

6 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages