# Toggle

Process

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

IDAbbrevNameTypeDefaultDescription
inputTGToggleBOOLEANfalsePulse input signal. On each rising edge (false to true transition), the output will toggle its state.
onONOnBOOLEANfalseSwitches the output (O) on. Only reacts to a rising edge.
offOFFOffBOOLEANfalsePulse: Resets the output (O) to off. When held on: Block is locked and all other inputs are ignored. Dominant input.

# Outputs

IDAbbrevNameTypeDefaultDescription
outputOOutputBOOLEANfalseBi-stable output that toggles its state on each input pulse.
onONOnBOOLEANfalsePulse when output (O) is switched on. Fixed 100ms pulse width.
offOFFOffBOOLEANfalsePulse when output (O) is switched off. Fixed 100ms pulse width.

# State

IDNameTypeDefaultUnitDescription
last_input_stateLast input stateBOOLEANfalseStores the previous state of the toggle input to detect rising edges
last_on_stateLast on stateBOOLEANfalseStores the previous state of the on input to detect rising edges
last_off_stateLast off stateBOOLEANfalseStores 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)
}
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.