Reference
Errors and warnings
What each of Volt's checks means, an example that triggers it, and how to fix it.
Volt checks a program in milliseconds, as you type in Volt IDE and the playground, or with volt check. Errors stop a build: the program would not work, or would damage the board’s boot. Warnings don’t: the program builds, but probably doesn’t do what you meant.
Many of these come with a fix. In Volt IDE and the playground, it’s a button under the problem; click it and the code is changed for you. Every example below opens in the playground, where you can see the message and try the fix.
Pins
pin-blocked
The GPIO is wired to the board’s flash memory. On an ESP32 that’s GPIO 6 to 11, and driving one crashes the chip.
hardware {
pin led: Output = 6
}
every 1s { led.toggle() }Fix: use another pin. The error lists the free ones and offers to move it.
pin-input-only
The GPIO can only read. On an ESP32, GPIO 34 to 39 have no output driver, so they can’t be an Output, PWM or Servo.
hardware {
pin relay: Output = 34
}
every 1s { relay.toggle() }Fix: move the output to a pin that can drive, and keep 34 to 39 for buttons and analog inputs.
pin-strapping
The GPIO decides how the chip boots: GPIO 0, 2, 5, 12 and 15 on an ESP32. It works, but whatever’s wired to it must not pull it the wrong way while the board starts, or the board won’t boot or flash. This is a warning.
hardware {
pin relay: Output = 12
}
every 1s { relay.toggle() }Fix: use another pin if one is free; otherwise make sure the circuit leaves the pin at its default level at power-up.
pin-uart0
GPIO 1 and 3 are the USB serial port. Using them stops the serial monitor and firmware flashing from working.
hardware {
pin led: Output = 1
}
every 1s { led.toggle() }pin-adc2-wifi
The analog pin is on ADC2, which the ESP32’s Wi-Fi takes over. While Wi-Fi is on, reads fail or return nonsense.
hardware {
pin soil: Analog = 25
}
every 5s {
let v: int = soil.read()
log("soil", "{v}")
}
setup {
wifi.connect("home", "secret") or retry(5)
}Fix: use an ADC1 pin, GPIO 32 to 39.
pin-conflict
Two declarations use the same GPIO.
hardware {
pin led: Output = 4
pin fan: Output = 4
}
every 1s {
led.toggle()
fan.toggle()
}pin-no-adc, pin-no-pwm, pin-no-dac, pin-no-touch
The pin can’t do what its mode asks: it has no analog input, no PWM, no DAC, or no touch sensing. Pin modes says which pins can.
hardware {
pin out: DAC = 4
}
every 1s { out.write(128) }Devices and buses
unknown-device
There’s no driver by that name on this computer. It may be misspelled, in which case the message suggests the closest name, or it may be a library from the Volt Grid you haven’t installed yet.
hardware {
device env: BME208
}
every 1s {
log("env", "hello")
}device-missing-pin
The device is wired to GPIOs and one of its pins wasn’t given. Each device’s page lists its pins.
hardware {
device sonar: HCSR04(trig: 26)
}
every 1s {
let cm: float = sonar.distance_cm()
log("sonar", "{cm}")
}i2c-address-clash
Two devices on one I²C bus have the same address, so neither would answer reliably.
hardware {
device a: BME280 on i2c0 at 0x76
device b: BMP180 on i2c0 at 0x76
i2c i2c0(sda: 21, scl: 22)
}
every 1s {
log("env", "{a.temperature()}")
}Fix: most parts have a second address, set by a pin on the board; use it, or put the second part on another bus.
i2c-address-unsupported
The part can’t be set to that address. The message lists the ones it supports.
hardware {
device env: BME280 on i2c0 at 0x40
i2c i2c0(sda: 21, scl: 22)
}
every 1s {
log("env", "{env.temperature()}")
}Types and values
TYPE MISMATCH
A value is the wrong type for where it’s used. The most common one is a duration written without its unit:
hardware {
pin led: Output = 2
}
every 500 {
led.toggle()
}Fix: 500ms or 500s. The fix button offers both. Between int and float, convert with float(n) or int(x).
NAME ERROR
A name isn’t declared, or is misspelled. The message suggests the closest name it knows.
hardware {
pin led: Output = 2
}
every 1s {
lde.toggle()
}MUTABILITY ERROR
The code changes a value declared with let. Declare it with var if it’s meant to change.
let limit: int = 10
setup {
limit = 20
}Behaviour
These are warnings: the program builds, but probably doesn’t do what you meant.
UNHANDLED FAILURE
wifi.connect or mqtt.connect has no fallback, so if it fails the program carries on offline as if nothing happened.
setup {
wifi.connect("home", "secret")
}Fix: add or retry(5), or skip or or restart; the fix button adds one. See Handling failure.
UNSAVED STORAGE
A storage variable is never saved, so it goes back to its starting value on every boot.
storage boots: int = 0
setup {
boots += 1
}Fix: call storage.save("boots", boots) after changing it. See Storage.
DEAD POLICY
A try block holds no calls at all, so nothing in it can fail and its or policy can never apply.
var count: int = 0
every 1s {
try {
count += 1
} or skip
}Syntax
SYNTAX ERROR
The code can’t be read. The message points at the spot and, for the usual slips, says what to do, with a fix button:
| You wrote | Fix |
|---|---|
every 500 ms | 500ms: the unit goes straight after the number. |
led.toggle(); | Remove the semicolon; a new line ends a statement. |
every 500ms with no { | Add the {, and the } after the block if it’s missing. |
hardware {
pin led: Output = 2
}
every 500 ms {
led.toggle()
}