Introduction

LumenScript is a plain‑English scripting language for LEDs. It’s fast to learn, friendly to read, and runs efficiently on tiny microcontrollers. It’s the best way to go from idea to glowing lights without needing to be a programmer.

Tip: You can use the LumenStudio web IDE at ls.hnl.cc to write and visually test your scripts in your browser. The in‑app Docs also include “Load in Editor” buttons for these examples.

Quick Start

Make everything fade in, hold, then fade out.

set $color = cyan
set $fade = 800ms

set all color black brightness 0
fade all color $color brightness 200 over $fade
delay $fade
fade all brightness 0 over $fade

Common Recipes

Short, practical patterns with plain‑English descriptions. In the Web IDE, use the “Load in Editor” buttons to try these instantly.

Breathe — a gentle brightness pulse on all LEDs

set $c = blue
set all color $c brightness 0
loop {
  repeat 3 times {
    fade all brightness 200 over 1.2s
    delay 1.2s
    fade all brightness 20 over 1.2s
    delay 1.2s
  }
}

Scanner — move a single bright LED from 1→8

set $on_c = cyan
set $off_b = 5

func off_all() {
  set all color black brightness $off_b
}

loop {
  repeat 3 times {
    set led[1] color $on_c brightness 200
    delay 120ms
    call off_all()
    set led[2] color $on_c brightness 200
    delay 120ms
    call off_all()
    set led[3] color $on_c brightness 200
    delay 120ms
    call off_all()
    set led[4] color $on_c brightness 200
    delay 120ms
    call off_all()
    set led[5] color $on_c brightness 200
    delay 120ms
    call off_all()
    set led[6] color $on_c brightness 200
    delay 120ms
    call off_all()
    set led[7] color $on_c brightness 200
    delay 120ms
    call off_all()
    set led[8] color $on_c brightness 200
    delay 120ms
    call off_all()
  }
}

Rainbow Cycle — step through named colors smoothly

set $t = 600ms
loop {
  fade all color red brightness 180 over $t
  delay $t
  fade all color orange brightness 180 over $t
  delay $t
  fade all color yellow brightness 180 over $t
  delay $t
  fade all color green brightness 180 over $t
  delay $t
  fade all color blue brightness 180 over $t
  delay $t
  fade all color purple brightness 180 over $t
  delay $t
  fade all color magenta brightness 180 over $t
  delay $t
  fade all brightness 0 over 800ms
  delay 800ms
}

Theater Chase — alternate odd/even groups

define %odd = (led[1], led[3], led[5], led[7])
define %even = (led[2], led[4], led[6], led[8])
set $c = orange
set all color black brightness 0
loop {
  repeat 6 times {
    set %odd color $c brightness 200
    set %even brightness 0
    delay 200ms
    set %even color $c brightness 200
    set %odd brightness 0
    delay 200ms
  }
  fade all brightness 0 over 600ms
  delay 600ms
}

White Flash — quick attention‑grabbing flash via func

func flash_white() {
  set all color white brightness 255
  delay 60ms
  set all brightness 0
  delay 60ms
}

loop {
  call flash_white()
  delay 500ms
  call flash_white()
  delay 800ms
}

Flicker Alert — temporary alert effect, then gently dim

define %back = leds(5..8)
loop {
  set %back color red brightness 255
  flicker %back
  delay 2s
  stop_effect %back
  fade %back brightness 50 over 500ms
  delay 500ms
}

General Syntax

  • Commands are one per line: COMMAND [arguments...].
  • Comments start with #. Note: hex colors like #FFA500 or #FA0 are parsed as colors, not comments.
  • Targets: all, led[N] (1-based), leds[N..M], %group_name.
  • Colors: named (red, green, blue, white, black/off, yellow, cyan, magenta/purple, orange), rgb(R,G,B), hex #RRGGBB or #RGB, or $variable.
  • Brightness: 0-255 integer, keyword brightness.
  • Durations: Number + unit (ms, s), e.g., 500ms, 1.5s, $variable (fractional seconds allowed).
  • Numbers: Integers. Decimals are accepted but truncated to integers (except durations with s, which support fractional seconds).
  • Blocks: Always enclosed in { ... }. Required for loop, repeat, if/else if/else.
  • Variables: Global scope, defined with set $name = value, referenced with $name. Basic arithmetic (+, -, *, /) supported for numeric and duration variables. Variables can also hold colors and targets.

Reserved Keywords and Operators

  • Commands: set, delay, fade, flicker, stop_effect, define, loop, repeat, if, else if, else, break, continue, func, call (Web IDE only)
  • Targets: all, led[N], leds[A..B], %group
  • Operators (conditions): ==, !=, >, <, >=, <=, modulo via %, %%, or mod (use as $x % m == r)
  • Arithmetic (variables): +, -, *, / (numeric/duration types)
  • Units: ms, s

Commands


set

Instantly sets properties or variables.

Syntax:

  • set [target] color [color_value]
  • set [target] brightness [0-255]
  • set [target] color [color_value] brightness [0-255] (Order fixed)
  • set $var = [value]
  • set $var = $var [op] [numeric_value_or_var] (Arithmetic)

Parameters:

  • target: all, led[N], leds[N..M], %group.
  • color_value: Name, rgb(), #, or $variable.
  • 0-255: Brightness value (literal or $variable).
  • value: Number, color, duration, or target for variable assignment.
  • op: +, -, *, / (Requires numeric operands).

Examples:

set led[1] color red
set led[1] brightness 255
set leds[5..8] color blue brightness 128
set $max_b = 200
set $delay = 500ms
set $counter = 0
set $counter = $counter + 1

delay

Pauses execution.

Syntax: delay [duration] Example: delay 1s, delay $my_pause Note: 0ms (or non-positive) results in no pause.


fade

Smoothly transitions properties over time.

Syntax: fade [target] (color [color_value])? (brightness [0-255])? over [duration] (Requires at least one of color or brightness. Order flexible; either can appear before over)

Parameters:

  • target: The LED(s) to affect.
  • color_value: (Optional) Target color.
  • 0-255: (Optional) Target brightness (literal or $variable).
  • duration: Transition time (e.g., 500ms, $fade_time).

Examples:

fade all color green brightness 255 over 2s
fade led[3] brightness 50 over 500ms
fade %mygroup color white over 1s

flicker

Activates a predefined flicker effect using the LED’s current color and brightness as the peak. Parameters are now fixed by the implementation for simplicity. Use stop_effect to cancel.

Syntax: flicker [target]

Parameters:

  • target: The LED(s) to affect. (Implementation defines frequency/duty cycle, e.g., 2Hz/50%)

Example: flicker all flicker %mygroup


stop_effect

Cancels active effects (flicker) on target LEDs.

Syntax: stop_effect [target] Example: stop_effect all


define

Defines a named group of LEDs.

Syntax: define %group_name = [target_definition] Parameters:

  • %group_name: Name (e.g., %front).
  • target_definition: led(N), leds(N..M), (target1, target2, ...) (combinations allowed).

Example:

define %front = leds[1..4]
define %odd = (led[1], led[3], led[5])

loop

Repeats a block indefinitely. Use break to exit.

Syntax:

loop {
    # commands...
    # use 'break' to exit
    # use 'continue' to skip to next iteration
}

Example:

set $counter = 0
loop {
    # ... do cycle ...
    set $counter = $counter + 1
    if $counter > 10 {
        break # Exit loop after 10 cycles
    }
    delay 100ms
}

repeat

Repeats a block a specific number of times.

Syntax:

repeat [N_or_$var] times {
    # commands...
    # use 'break' to exit early
    # use 'continue' to skip to next iteration
}

Parameters:

  • N_or_$var: Number of repetitions (integer or $variable).

Example:

repeat 5 times {
    set led[2] color blue
    delay 100ms
    set led(2) color black
    delay 100ms
}

if / else if / else

Conditionally executes blocks. {...} are mandatory.

Syntax:

if $[variable] [op] [value_or_$var] {
    # commands if true...
} else if $[variable] [op] [value_or_$var] {
    # commands if first is false and this is true...
} else {
    # commands if all preceding conditions are false...
}

(else if and else are optional)

Parameters:

  • variable: Variable name (numeric or duration value).
  • op: ==, !=, >, <, >=, <=.
  • value_or_$var: Numeric/duration literal or variable to compare against.

Modulo form: Use $var % M == R to test remainders. %, %%, or mod are accepted for modulo. Shorthand: if $var % M { ... } is true when the remainder is non-zero.

Example:

set $level = 150
if $level > 200 {
    set all color red
} else if $level > 100 {
    set all color yellow
} else {
    set all color green
}

func / call (no params)

Defines simple, reusable command sequences without parameters.

Support note: The LumenStudio Web IDE preprocesses and inlines func/call. The current firmware parser ignores call lines (no function registry). If you deploy to device firmware, inline function bodies manually or avoid func/call.

Syntax:

# Definition
func function_name() {
    # commands...
}

# Execution
call function_name()

Example:

func flash_white() {
    set all color white brightness 255
    delay 50ms
    set all brightness 0
    delay 50ms
}

# Use it
call flash_white()
delay 500ms
call flash_white()

break

Immediately exits the current loop or repeat block.

Syntax: break


continue

Skips the rest of the current iteration of a loop or repeat block and proceeds to the next iteration (or condition check).

Syntax: continue


Example Script

# Define groups
define %front = leds(1..4)
define %back = leds(5..8)

# Define vars
set $main_color = rgb(0, 80, 200)
set $accent_color = #FFA500
set $fade_time = 1s
set $max_loops = 5
set $loop_count = 0

# Define simple functions
func initial_setup() {
    set all color black brightness 0
    delay 500ms
    fade all color $main_color brightness 200 over $fade_time
    delay $fade_time
}

func fade_out() {
    fade all brightness 0 over 2s
    delay 2s
}

# --- Main Script ---
call initial_setup()

repeat $max_loops times {
    set $loop_count = $loop_count + 1

    # Alternate effect based on loop counter
    if $loop_count == $max_loops {
        # Special last loop action
        fade %front color white over 1s
        fade %back color $accent_color over 1s
        delay 1s
    } else if $loop_count % 2 == 0 { # Even loops
        # Pulse front
        fade %front color $accent_color over 500ms
        delay 500ms
        fade %front color $main_color over 500ms
        delay 500ms
    } else { # Odd loops
        # Flicker back (using simplified command)
        flicker %back
        delay 2s
        stop_effect %back
    }

    # Example using continue (e.g., skip delay on first loop)
    if $loop_count == 1 {
        continue # Skip the final delay
    }

    delay 250ms # Short delay between loops unless skipped
}

# Example using break (though not necessary here as repeat finishes)
# loop {
#   if some_condition { break }
# }

call fade_out()
# --- End Script ---