Volt Docs

Language

Control flow

if and else, loops, match, and leaving a block early.

main.volt
hardware {
    pin led: Output = 2
}

enum Mode { idle, running, fault }

var mode: Mode = Mode.idle

setup {
    var n: int = 0
    while n < 3 { n += 1 }
    for i in 0..10 { log("loop", "i={i}") }
    for j in 0..100 step 10 { log("loop", "j={j}") }
    if n > 2 {
        led.on()
    } else if n == 2 {
        led.toggle()
    } else {
        led.off()
    }
    match(mode) {
        .idle -> led.off()
        .running -> led.on()
        _ -> led.toggle()
    }
}

if and else

Conditions don’t need brackets; the block does:

main.volt
hardware {
    pin fan: Output = 4
    pin probe: Analog = 34
}

every 1s {
    let raw: int = probe.read()
    if raw > 3000 {
        fan.on()
    } else if raw < 2500 {
        fan.off()
    }
}

Loops

for i in a..b counts from a up to, but not including, b. step sets how far each turn goes. while repeats while its condition holds, and break and continue work as you’d expect:

main.volt
setup {
    var total: int = 0
    for i in 0..10 {
        if i == 7 { break }
        if i % 2 == 0 { continue }
        total += i
    }
    log("sum", "odd numbers below 7 add up to {total}")
}

A loop that runs for a long time holds up everything else in its task. For something that should happen over time, use an every block instead of a loop with waits.

match

match picks one arm by value. An arm is an enum variant (.idle), a number, a range (0..10, which leaves out 10), or _ for anything else:

main.volt
hardware {
    pin knob: Analog = 34
}

every 500ms {
    let level: int = knob.read() / 1000
    match(level) {
        0 -> log("knob", "off")
        1..3 -> log("knob", "low")
        3 -> log("knob", "high")
        _ -> log("knob", "full")
    }
}

An arm can be one statement or a block in { }.