Tutorial 2: Your first config

You’ve cloned the repo and seen the bundled preview in your browser. Now you’ll
write your own config/config.toml from scratch. By the end of this chapter
you’ll have a working one-section config and understand the structure every
led-ticker config follows.
~10 min · no hardware needed
Picks up from Chapter 1 — you’ll need the repo cloned and
make try running (or ready to run). No new prerequisites.
Starting point
Section titled “Starting point”Delete any existing config/config.toml and start fresh:
rm -f config/config.tomlReset block — start of Chapter 2
If you ever want to reset to exactly the starting point for this chapter, create
config/config.toml with just the [display] and [web] blocks and no widgets yet:
[display]rows = 64cols = 256chain_length = 1default_scale = 4brightness = 60
[web]# lets make try show your sign live in the browser; harmless on the Pi deployThe [display] block
Section titled “The [display] block”Open a new config/config.toml in your editor. Add the display block first,
then a [web] block on the line below it:
[display]rows = 64cols = 256chain_length = 1default_scale = 4brightness = 60
[web]# lets make try show your sign live in the browser; harmless on the Pi deployWhat each field does:
rows = 64andcols = 256— the physical dimensions of the panel array in pixels. The bigsign is eight 32×64 panels arranged in a 2×4 serpentine grid, giving a 256×64 physical canvas.chain_length = 1— number of chains. The bigsign uses a single chain of eight panels.default_scale = 4— the logical-to-physical ratio. All drawing happens on a logical canvas ofcols / scale × rows / scale= 64×16 pixels. Every logical pixel expands to a 4×4 block on the real panel. This keeps font sizes and layout coordinates manageable, and is why the BDF pixel font looks crisp at display size.brightness = 60— panel brightness, 0–100. 60 is a comfortable starting point.[web]— publishes the display engine’s state so the browser preview can show your sign live. An empty block is enough; the defaults are fine for laptop use. The same block enables the web dashboard on a real Pi deploy — it’s harmless to leave it in your production config.
There are several Pi-specific hardware knobs you’ll see in the example configs —
pixel_mapper_config, gpio_slowdown, hardware_mapping, pwm_bits, rp1_pio. These
control low-level GPIO timing and panel chaining. They have no effect on the
laptop preview and are safe to omit until you’re deploying to real hardware.
See Hardware → Bigsign for details on those.
Add the first widget
Section titled “Add the first widget”Below the [web] block, add a section with one message widget:
[[playlist.section]]mode = "ticker"loop_count = 1
[[playlist.section.widget]]type = "message"text = "Welcome to Firebird Yoga"font_color = [225, 48, 108]A few things to notice:
The double brackets [[...]] — [[playlist.section]] and
[[playlist.section.widget]] use TOML’s array-of-tables syntax. Each
[[playlist.section]] header appends a new section to the playlist array; each
[[playlist.section.widget]] header appends a new widget to the most recently
opened section. This is a common gotcha for TOML newcomers: single brackets
[...] define a single table, double brackets [[...]] append to an array.
mode = "ticker" — the section joins all its widgets into one continuous
scrolling stream. The text enters from the right, scrolls left, and the loop
repeats. Other modes (slideshow, one_at_a_time) are covered in Chapter 3.
loop_count = 1 — how many times to run the section before the playlist
advances. For a multi-section config, 1 means each section plays once per
playlist cycle.
font_color = [225, 48, 108] — an RGB triple. led-ticker accepts colors as
[r, g, b] lists anywhere a color is expected. This particular value is the
Instagram magenta ([225, 48, 108]) the social handle uses.
Validate
Section titled “Validate”Before previewing, run the config validator. With make try running, use the
try container itself (a second terminal — no Python install needed):
docker exec led-ticker-try-engine led-ticker validate /code/config/config.tomlOn a machine with the dev toolchain (make dev once), the direct form works
too: uv run led-ticker validate config/config.toml.
If everything is correct you’ll see:
Validating config/config.toml...
No issues found.Try introducing a deliberate error — change font_color = [225, 48, 108] to
font_color = "pink" and run validate again:
Validating config/config.toml...
✗ ERROR section[0].widget[0]: unknown font_color style 'pink'; available: ['color_cycle', 'gradient', 'rainbow', 'random'] Fix: See error message for details.
1 issue(s): 1 error(s), 0 warning(s)The validator catches type errors, unknown fields, and missing required values before you ever preview. Get in the habit of running it after every edit. Revert the typo before continuing.
Preview
Section titled “Preview”With your config saved and the validator passing, run make try:
make tryOpen http://localhost:8080 and click the live preview tab. You should see “Welcome to Firebird Yoga” scrolling in pink across a black background — identical to the demo at the top of this page:

If make try is still running from Chapter 1, stop it first (Ctrl-C) and
run make try again — the Chapter 1 session started on the bundled example
before your config/config.toml existed, and the config choice happens at
startup. From now on you won’t need to restart: saved edits to your config
hot-reload into the preview within one playlist cycle. (The exception is
[display]-level fields, which always need a Ctrl-C + make try.)
The edit-validate-preview loop
Section titled “The edit-validate-preview loop”Most led-ticker development follows a tight loop: edit the TOML, validate, save, and check the browser preview. Try a few concrete changes to get comfortable with it:
Change the text. Edit text = "Welcome to Firebird Yoga" to something
longer, then save. The browser preview updates within one playlist cycle. If
you want to capture the result as a GIF with a longer duration, call the
renderer directly (needs make dev once — see the aside above):
uv run python tools/render_demo/render.py config/config.toml -o preview.gif --duration 20Change the color. Try a different [r, g, b] triple — for example
[124, 173, 232] (sky blue) or [255, 92, 38] (flame orange). Validate and
save after each change, then check the preview.
Add a second widget. Append another [[playlist.section.widget]] block
immediately after the first (still under the same [[playlist.section]]):
[[playlist.section.widget]]type = "message"text = "Open Tuesday – Sunday * 10am – 8pm"font_color = [255, 240, 200]Save. In ticker mode both messages appear back-to-back in a single continuous
stream, separated by a small gap. The * character renders as a mid-dot
separator — a common convention in ticker text.
Each edit-validate-preview cycle takes under ten seconds on a laptop. Keep the loop tight and build confidence before moving on to the more complex sections in Chapter 3.
What’s next
Section titled “What’s next”Chapter 3 introduces multiple sections, the slideshow and one_at_a_time modes, the
two_row widget for two-line layouts, and hi-res emoji. You’ll go from a single
message to a sign that rotates through distinct content cards.