scale.fr
to scale with percent, max [
here bounded is clamp: percent, 0, 100;
bounded * max / 100
]
scale: 80, 255
to blink with pin, count, wait [
repeat count [
gpio.high: pin; ms: wait;
gpio.low: pin; ms: wait
]
]
blink: $led_builtin, 5, 200
to watch.light [
here level is adc.read: $a0;
if level > 2000 [
led.on:
] else [
led.off:
]
]
watch.light:
to signal [ led.blink: 2, 120 ]
to warn [ signal: ]
to signal [ led.blink: 8, 40 ]
warn:
boot is fn [
on $boot_button falling debounce 30 [
led.toggle:
]
]
save
to doze [
sleep.wake-on-gpio: $boot_button, 0;
sleep.deep: 30000
]
doze:
blink.rate is 200
to pulse [ led.blink: 3, blink.rate ]
save -- snapshot the overlay to flash
blink.rate is 40 -- try a faster rate, live...
restore -- ...snap back to the saved 200
notes
A word is a name with code behind it — write it with to, run it with a trailing colon. with names its arguments.
here binds a value that's local to the block, so bounded exists only inside scale. A block hands back its last line — here, the scaled number.
The hello-world of hardware — and it already ships in the base image. repeat runs the block a fixed number of times, ms: waits, $led_builtin is the onboard LED.
Arguments follow the colon, comma-separated: a pin, a count, a delay.
Read an analog pin with adc.read:, keep the reading in a local, and branch on it. if … else takes the first block when the test is true.
Sense, decide, act — the whole loop of physical computing, in seven lines.
warn calls signal by name. Redefine signal and every caller picks up the new version on the next call.
No recompile, no re-flash, nothing to restart. This is the thing Frothy is really for: changing a running device one word at a time.
on $boot_button falling debounce 30 [ … ] toggles the LED on a falling edge — a button press — with 30 ms of debounce, so one push registers once. every <ms> [ … ] does the same on a timer.
Handlers fire cooperatively, at safe points between steps — never mid-write. Register them in boot, save, and the device reacts on its own from power-on.
Arm a wake source, then power the core down. sleep.wake-on-gpio: says "come back when this pin goes low"; sleep.deep: sleeps up to that many milliseconds.
The thing a battery project lives or dies on — one line each.
Your top-level names — blink.rate and pulse here — sit in an overlay on top of the base image the board shipped with. save writes that overlay to flash, so it survives a power cycle.
restore snaps the live overlay back to the last save — a cheap undo for a session that wandered. dangerous.wipe erases the saved overlay entirely, back to the bare base. Save a state worth keeping; restore to recover; wipe to start clean.