u/chatelp

Image 1 — Silicon Bubbles — an iMessage client for the Cardputer ADV (needs a BlueBubbles server on a Mac)
Image 2 — Silicon Bubbles — an iMessage client for the Cardputer ADV (needs a BlueBubbles server on a Mac)

Silicon Bubbles — an iMessage client for the Cardputer ADV (needs a BlueBubbles server on a Mac)

My daily driver phone is an iPhone and my pocket toy is a Cardputer ADV, so the conclusion was inevitable: the 56-key keyboard now sends iMessages. Real bubbles, pixel-art emoji, tapbacks shown as little pills on the bubble corner, marimba-ish synthesized sounds instead of beeps, EN/FR interface.

Hard requirement up front: this is a client for BlueBubbles, the open-source iMessage bridge. You need their server running on a Mac (or Hackintosh/macOS VM) signed into iMessage. No Mac, no messages — there is no way around Apple on this one. Setup is ~10 minutes and their docs are good.

What the device does once it's talking to your server:

  • conversation list that merges duplicate threads per person, with a calibration pass that figures out who you actually talk to
  • bubble-by-bubble scrolling, group sender labels, unsend/edit handling
  • 42 hand-drawn 12×12 emoji glyphs (68 codepoints), unknown ones get a clean placeholder instead of tofu
  • name any conversation locally (BlueBubbles doesn't expose Mac contacts), WiFi scan + QR-based setup from a phone, settings backup to microSD
  • a web portal for config, and stable error codes (E11…E50) documented in the README so "response cut short" never reads as raw JSON vomit

The part I'm proudest of is invisible: the ESP32-S3FN8 has no PSRAM, and the real budget is the ~31 KB contiguous heap block left at runtime. Responses are parsed as a stream straight off the TLS socket — no body is ever buffered. Along the way I hit a nasty core bug: NetworkClient::readBytes treats a momentarily empty TLS socket as a fatal error, silently truncating anything bigger than the decrypted buffer. If your ESP32 HTTPS code "randomly" fails on large responses, that may be your answer.

Honest status: work in progress. It runs daily against exactly one setup — ADV, BlueBubbles v1.9.9 behind Cloudflare, French numbers. That's one data point. If you flash it against a different setup (other country codes, big group chats, self-signed TLS, ngrok, the original Cardputer), please open an issue and tell me what broke or didn't. At this stage your setup report is worth more than any feature request — though those are welcome too.

Installing: it's on M5Burner under CARDPUTER (search Silicon Bubbles) if you'd rather not touch a toolchain, or grab the factory .bin from the GitHub releases. Either erases existing device settings, so back yours up first if you have some.

Everything on GitHub (MIT), including a desktop SDL simulator that renders the exact same UI code — every screenshot and the GIF above come from it, none of this is a mockup. Built with Claude Code driving the implementation; the decision journal in the repo keeps the whole dialogue, wrong turns included, and the device says so itself in its About screen.

https://github.com/chatelp/silicon-bubbles-cardputeradv

u/chatelp — 4 days ago

Silicon Casino — five casino games for the Cardputer ADV. Fake chips, real odds.

The Cardputer ADV keyboard has a number row nobody uses in a game, an IMU nobody shakes, and a 1W speaker with opinions. So I made it a casino: 3-reel slots, a 5×3 video slot, blackjack, Jacks-or-Better video poker, European roulette. Virtual chips only — the house refills you when you hit zero, and the number row prints money (1 = +10 chips, 0 = +100) under a rain of golden pixels. This is a toy about animation, not a gambling product.

The identity gimmick: everything is electronics. The slot cabinet is a PCB with mounting holes and vias. The blackjack felt is routed like a board, silkscreen and all. The roulette wheel sits on a rotary encoder labeled RE1 — 37 detents, one per pocket. Good luck sourcing that part. While the reels spin, the bottom of the screen is an oscilloscope trace that loses sync and tears whenever a reel locks. Reel symbols are floppy, CRT, chip, invader — with a GLYPHS setting that swaps back to cherries and bells if the geek skin isn't your thing. Same paytable either way.

Under the pixel art, the odds are the honest part:

  • video poker rank frequencies are verified against all 2,598,960 possible five-card hands in a native test — if the 9/6 table drifts, the build fails
  • all ten roulette bets settle at exactly 972,973 ppm across the 37 pockets, enumerated
  • slots RTP is 95.24%, derived analytically from the strip counts, not simulated
  • the RNG is injected (hardware TRNG on device, xorshift in tests), drawn by rejection — no modulo bias

Cardputer-specific scars, for whoever comes after me:

  • getBuffer() hands you RGB565 with the bytes swapped. My first greyscale pass produced a uniformly magenta screen. bswap16 in, fixed.
  • lgfx color overloads dispatch on type: 0x18E3 as a bare literal is RGB888. Every color in this codebase is a named constexpr uint16_t.
  • &M5Cardputer.Display captured in a global constructor is garbage — Display is a member reference, M5 isn't initialized yet, and the crash waits for your first pushSprite.
  • the speaker rolls off under ~400 Hz. All cues live in 800–2600 Hz and a unit test rejects anything below the band.

Everything renders through lgfx::, so the exact same drawing code runs in a desktop SDL simulator. All motion — reel easing, the ball's bounce, the coin rain — is pure functions of a time parameter, which means the animations have unit tests and every screenshot here is reproducible from a fixed seed.

The whole thing is built as a casino, not a slot machine: common game interface, shared balance, per-game bets — adding a sixth game is a module, not a rewrite. So, honest question for the thread: what belongs in here next? Craps is the obvious IMU candidate (shake to throw is sitting right there), keno fits a 56-key keyboard suspiciously well, and Game & Watch-style horse racing keeps tempting me. Or tell me what the current games get wrong — odds you'd want displayed, a demo mode tweak, glyphs that don't read. I'd rather grow this thing along what people actually want to hold.

On M5Burner under CARDPUTER, as "Silicon Casino". Or build from source — MIT including the pixel art: github.com/chatelp/geek-casino-cardputeradv

About how it was made: Claude Code wrote the C++; I set the scope and the rules, judged every screen on the actual device, and sent plenty back ("the equalizer has no punch, change registers" is in the decision journal, right next to the AI's failed first attempt). Press a in the lobby and the device tells you the same thing. The odds aren't a matter of trust either way — the enumeration tests are in the repo.

u/chatelp — 7 days ago

A Yi Jing casting device for the Cardputer ADV — the Wi-Fi in the room nudges the draw

Every firmware in the M5Burner Cardputer list is a tool: Wi-Fi attacks, radios, remotes, emulators. I wanted the opposite — something you hold still for thirty seconds.

Daoa Mini casts the Yi Jing line by line, the traditional three-coin way. Six lines bottom to top, then the figure, the figure it is tending toward, and the text: portrait, Judgment, Image, the meaning of each of the six lines. English and French. Nothing leaves the device — no account, no cloud, no AI at runtime. The randomness is the ESP32's hardware TRNG.

The part I actually built it for: before each casting, it listens to the room. A passive Wi-Fi scan — never connects, radio off the moment it ends, no SSID or BSSID kept, nothing stored or transmitted — becomes a particle field on screen, one dot per network, and it weights the draw. Density leans yin or yang by 5% at most; agitation makes changing lines up to 4% more likely. Bounded, documented, on by default, switchable off.

Press w and it shows you everything: networks, channels, dBm, density, agitation, the two weights, and the resulting probabilities of 6/7/8/9. If a thing like this influences a draw, you should be able to audit exactly how much.

Three things I learned the hard way, in case they save someone time:

Biasing the coins does nothing. A line is yang when the number of heads is odd, and binomial parity is insensitive to bias down to third order — a 5% coin bias moves the yin/yang balance by 0.05%. The weighting had to move to the line level instead.

The 1 W speaker is deaf below ~400 Hz. I wrote the interface tones as a pentatonic in A3–A4 and the casting was silent while the high ticks rang fine. Transposed two octaves up, same intervals, problem gone.

M5GFX's DejaVu fonts are ASCII only — no accents at all. efontJA covers accented Latin; efontCN has the hexagram glyphs except 遯, 夬 and 姤.

Source is MIT, with the full method and a desktop SDL simulator that runs the exact same rendering code: https://github.com/chatelp/daoa-mini-cardputeradv

On M5Burner under CARDPUTER, as "Daoa Mini". Built and tested on the ADV.

Two disclosures, because I would rather say them than have them found. First, this is a companion object for Daoa, my Yi Jing app — the last screen is a QR code to it. Second, the commit log makes it plain anyway: I designed and directed this, and Claude Code wrote most of the implementation. The scope, the product rules, the three-coin decision, the visual direction and all the on-device validation are mine; the typing largely is not. The maths is covered by tests you can run yourself — if something is wrong, tell me and I will fix it.

(I got into the Yi Jing as a teenager reading The Man in the High Castle, which is probably the most predictable possible origin story for this.)

u/chatelp — 11 days ago