# Toggle
Converts a monostable pulse input into a bi-stable toggle output. Each rising edge on the input toggles the output state. Supports explicit on/off inputs and emits pulse outputs on state transitions.
Toggle
TG
ON
OFF
O
ON
OFF
# Inputs
| ID | Abbrev | Name | Type | Default | Description |
|---|---|---|---|---|---|
input | TG | Toggle | BOOLEAN | false | Pulse input signal. On each rising edge (false to true transition), the output will toggle its state. |
on | ON | On | BOOLEAN | false | Switches the output (O) on. Only reacts to a rising edge. |
off | OFF | Off | BOOLEAN | false | Pulse: Resets the output (O) to off. When held on: Block is locked and all other inputs are ignored. Dominant input. |
# Outputs
| ID | Abbrev | Name | Type | Default | Description |
|---|---|---|---|---|---|
output | O | Output | BOOLEAN | false | Bi-stable output that toggles its state on each input pulse. |
on | ON | On | BOOLEAN | false | Pulse when output (O) is switched on. Fixed 100ms pulse width. |
off | OFF | Off | BOOLEAN | false | Pulse when output (O) is switched off. Fixed 100ms pulse width. |
# State
| ID | Name | Type | Default | Unit | Description |
|---|---|---|---|---|---|
last_input_state | Last input state | BOOLEAN | false | Stores the previous state of the toggle input to detect rising edges | |
last_on_state | Last on state | BOOLEAN | false | Stores the previous state of the on input to detect rising edges | |
last_off_state | Last off state | BOOLEAN | false | Stores the previous state of the off input to detect rising edges and lock state |
# Source Code
View Volang source
pulse_ms = 100
channel = input::channel()
value = input::value()
// Single callback handler - resets both pulse outputs
// Only one callback can be active at a time per block
extern fn onCallback(unused) {
output::set("on", false)
output::set("off", false)
}
// Handle "off" input first (dominant input)
if (channel == "off") {
last_off_state = state::get("last_off_state")
if (value and !last_off_state) {
// Rising edge on off input - turn off output
prev = output::get("output")
if (prev) {
output::set("output", false)
callback::clear()
output::set("on", false)
output::set("off", true)
callback::set(pulse_ms, "onCallback", 0)
}
}
state::set("last_off_state", value)
return
}
// If off input is held high, block is locked - ignore other inputs
// Still track input states to avoid false edges after unlock
if (state::get("last_off_state")) {
if (channel == "input") {
state::set("last_input_state", value)
} else if (channel == "on") {
state::set("last_on_state", value)
}
return
}
// Handle "on" input
if (channel == "on") {
last_on_state = state::get("last_on_state")
if (value and !last_on_state) {
// Rising edge on "on" input - turn on output
prev = output::get("output")
if (!prev) {
output::set("output", true)
callback::clear()
output::set("off", false)
output::set("on", true)
callback::set(pulse_ms, "onCallback", 0)
}
}
state::set("last_on_state", value)
return
}
// Handle toggle input
if (channel == "input") {
last_input_state = state::get("last_input_state")
// Only react to rising edge (false -> true)
if (value and !last_input_state) {
prev = output::get("output")
output::toggle("output")
callback::clear()
output::set("on", false)
output::set("off", false)
if (prev) {
// Was on, now off - emit off pulse
output::set("off", true)
} else {
// Was off, now on - emit on pulse
output::set("on", true)
}
callback::set(pulse_ms, "onCallback", 0)
}
state::set("last_input_state", value)
}
