Events let the device react later while the prompt stays available. Frothy records a small handler, receives timer or hardware candidates, and runs the handler at a safe statement boundary.
Timers And A Button
Event registration belongs inside a word:
to start-ticks [
every 1000 [ print: "tick\n" ]
]
to stop-later [
after 10000 [ led.off: ]
]
to watch-button [
on $boot_button falling debounce 25 [
led.toggle:
]
]
start-ticks:
stop-later:
watch-button:
every repeats. after removes itself before its body runs. The GPIO handler
can use rising, falling, or changes; debounce is optional. The current
profile allows one event body per definition, so each source gets one small
registration word.
Event Forms
| Form | Identity | Behavior |
|---|---|---|
every ms [body] | kind plus millisecond value | Repeats until cancelled or cleared |
after ms [body] | kind plus millisecond value | Runs once, then disappears |
on pin edge [body] | GPIO pin | Runs on the selected edge |
on pin edge debounce ms [body] | GPIO pin | Drops candidates inside the debounce window |
on wifi.disconnected [body] | Wi-Fi state | Runs after a previously working connection drops |
on wifi.reconnected [body] | Wi-Fi state | Runs when that connection returns |
cancel ... | matching source identity | Removes one registration |
Cancel And Replace
Use the same identity used at registration:
cancel every 1000
cancel after 10000
cancel $boot_button
cancel wifi.disconnected
cancel wifi.reconnected
Timer identity includes both kind and period, so every 1000 and after 1000
are different registrations. GPIO identity is the pin alone: registering a new
edge handler for the same pin replaces the old one, and cancel pin removes it
regardless of edge or debounce. Each Wi-Fi lifecycle kind has one binding.
The current runtime holds 16 event bindings in total. Re-registering a matching
identity replaces it without consuming another slot. mem events shows used
and total capacity; events lists the active registrations.
Handler Scope
Event bodies do not capture the parameters or here locals of the word that
registered them. Use top-level names or call another top-level word:
presses is 0
to count-press [
set presses to presses + 1
]
to arm-button [
on $boot_button falling debounce 25 [ count-press: ]
]
This keeps a handler valid after the registration call has returned.
Dispatch And Output
Candidates arrive asynchronously, but handler code runs in the Frothy runtime at safe points: statement boundaries, loop back-edges, and word returns. A long single expression can delay delivery until the next such point. Handlers do not interrupt one another recursively.
Output produced outside the foreground reply is prefixed with ! on the wire:
! tick
If the platform queue overflows, Frothy reports ! events dropped: N. Keep
handlers short and move sustained work into ordinary foreground code when
possible.
Wi-Fi Lifecycle
Register Wi-Fi handlers before connecting:
to watch-wifi-down [
on wifi.disconnected [ print: "wifi down\n" ]
]
to watch-wifi-up [
on wifi.reconnected [ print: "wifi back\n" ]
]
watch-wifi-down:
watch-wifi-up:
wifi.connect:
The first successful connection is not a wifi.reconnected event. These forms
describe a drop and recovery after the device has already obtained an address.
See Wi-Fi, HTTP & TCP
for connection behavior.
RP2040 Support
The Nano RP2040 Connect and the XIAO RP2040 support timer and GPIO events. The Nano also supports Wi-Fi lifecycle events through its NINA radio. The XIAO RP2040 has no Wi-Fi radio.
On both RP2040 boards, save disables interrupts during each flash erase and
program step. A timer can run late during these steps. The device can miss GPIO
edges during a flash step. Do not run save while each GPIO edge is critical.
Persistence And Clearing
Event registrations are part of the project overlay. save persists them,
restore reinstalls them, and clear or a project wipe removes their live
platform registrations. Use events after restore to inspect what is active.
Timers and GPIO handlers are for human-scale asynchronous work. For captured or emitted edges with 100-nanosecond quantization, use Digital signals .