Tick + ATOM Matrix
A 5×5 LED grid the size of a quarter. Grab the firmware from GitHub, flash it, configure from the setup page, and drop it in the swamp.
ATOM Matrix — 24 × 24mm. 25 RGB LEDs. Accelerometer. Wi-Fi. USB-C. ~$15.
The ATOM Matrix has everything built in. No shields, no wiring, no breadboard.
| LEDs | 5×5 WS2812C RGB matrix — 25 LEDs, any color |
| Chip | ESP32-PICO-D4, dual-core 240 MHz, 4MB flash |
| Motion | MPU6886 accelerometer + gyroscope |
| Wireless | Wi-Fi (built in) |
| Power | USB-C, 5V |
| Firmware | CircuitPython + Tick — get from GitHub |
| Button | 1 button hidden under the LED grid |
Download the firmware zip and extract it on your computer.
Connect the ATOM Matrix via USB-C. It shows up as a drive called CIRCUITPY. Copy the swamp-glow folder contents onto the drive. The device reboots automatically and starts running. It boots in about 2 seconds.
What happens on boot:
ATOM Matrix inside the waterproof housing. LED grid facing out. Swamp green.
The device becomes its own Wi-Fi hotspot. You connect to it and configure from a web page.
Hold the button for 3 seconds. The LED grid turns yellow — the ATOM Matrix is now running as a Wi-Fi access point.
Wi-Fi name: Tick Password: 11111111
Go to http://192.168.4.1 in your phone’s browser. A setup page loads — it’s stored on the device itself, not the internet.
Set color, brightness, pattern, and timing from a web form. Easy to fine-tune exact values.
The setup page is embedded in the firmware — a single HTML file served from the device. No internet needed. Dark background, green accents, swamp glow theme. It looks like it belongs to the book.
The AP page also lets you enter Wi-Fi credentials for Step 3 — but that’s optional. You can use the device with just the AP page forever.
Optional. Connect to your home network for remote control.
On the AP setup page, there’s a section for Wi-Fi credentials. Enter your network name and password. Hit save. The device reboots, connects to your Wi-Fi, and now you can reach it from any device on the same network.
With Wi-Fi, you can control pucks from inside the house. No need to walk out. Change a color, adjust a pattern, turn one off — all from your browser.
If you have multiple pucks on the same network, each one has its own IP. Bookmark them. Control any puck from any browser on your network.
What’s running on the device. CircuitPython.
The ATOM Matrix runs CircuitPython with the Tick library. All the code lives on the CIRCUITPY drive. Here’s what it does:
The 25 WS2812C LEDs are on GPIO 27. The NeoPixel driver handles them:
import board
import neopixel
import math, time
NUM_LEDS = 25
np = neopixel.NeoPixel(board.G27, NUM_LEDS, auto_write=False)
# Set all 25 LEDs to swamp green
def set_color(r, g, b):
np.fill((r, g, b))
np.show()
# Breathe — fade brightness up and down
def breathe(r, g, b, max_bright=20):
t = time.monotonic()
val = (math.sin(t * 0.5) + 1) / 2 # 0.0 to 1.0
scale = 2 + int(val * max_bright)
np.fill((r * scale // 255, g * scale // 255, b * scale // 255))
np.show()
Two hours on, ten minutes dark — just a timer:
on_duration = 2 * 60 * 60 # 2 hours in seconds
off_duration = 10 * 60 # 10 minutes in seconds
cycle_start = time.monotonic()
glowing = True
while True:
elapsed = time.monotonic() - cycle_start
if glowing and elapsed >= on_duration:
set_color(0, 0, 0) # LEDs off
glowing = False
cycle_start = time.monotonic()
elif not glowing and elapsed >= off_duration:
glowing = True
cycle_start = time.monotonic()
if glowing:
breathe(5, 40, 3) # swamp green pulse
time.sleep(0.02)
The MPU6886 accelerometer detects if someone picks up the puck:
import busio
import adafruit_mpu6886
i2c = busio.I2C(board.G21, board.G25)
imu = adafruit_mpu6886.MPU6886(i2c)
def check_motion():
ax, ay, az = imu.acceleration
accel = math.sqrt(ax*ax + ay*ay + az*az)
# Sitting still = ~9.8 m/s². Picked up = spike above 15
if accel > 15:
set_color(40, 0, 0) # flash red
time.sleep(0.5)
set_color(5, 40, 3) # back to green
When you hold the button, the device starts a web server:
import wifi
import socketpool
from adafruit_httpserver import Server, Request, Response
# Start AP mode
wifi.radio.start_ap(ssid="Tick", password="11111111")
pool = socketpool.SocketPool(wifi.radio)
server = Server(pool, "/static")
@server.route("/")
def index(request: Request):
return Response(request, body=SETUP_HTML,
content_type="text/html")
@server.route("/save", methods=["POST"])
def save(request: Request):
save_settings(request.form_data)
return Response(request, body="Saved. Rebooting...")
server.serve_forever(str(wifi.radio.ipv4_address_ap))
Same housing as the simple Swamp Glow versions:
No soldering. No wiring. The ATOM Matrix is the whole circuit.
Plug in USB. Drag and drop. Done.
The device runs CircuitPython. When you plug it into a computer, it shows up as a USB drive called CIRCUITPY. The Tick code is a set of .py files on that drive. To update:
Download the latest files from the i4Seer GitHub repo:
github.com/i4seer/tick-swamp-glow
Click the green Code button, then Download ZIP. Or use git clone if you know git.
Connect via USB-C. A drive called CIRCUITPY appears on your computer — just like a thumb drive.
Drag the updated .py files from the download onto the CIRCUITPY drive. Replace the old files.
CIRCUITPY/
code.py ← main program
tick_led.py ← LED patterns
tick_web.py ← AP setup page
settings.toml ← saved settings
The device reboots automatically when you save files. Your settings (color, brightness, timing) are preserved. Unplug USB and it runs on its own.
Updates are optional. The device works out of the box. But if i4Seer releases new patterns, bug fixes, or features — this is how you get them. No special tools. Just copy files.