experimental.knobs

class experimental.knobs.BufferedKnob(knob)

A wrapper for a Knob instance whose value remains fixed until .update(…) is called

This allows multiple uses of .percent(), .choice(…), etc… without forcing a re-read of the ADC value

choice(values, samples=None, deadzone=None)

Return a value from a list chosen by the current voltage value.

percent(samples=None, deadzone=None)

Return the knob’s position as relative percentage.

range(steps=100, samples=None, deadzone=None)

Return a value (upper bound excluded) chosen by the current voltage value.

read_position(steps=100, samples=None, deadzone=None)

Returns the position as a value between zero and provided integer.

set_deadzone(deadzone)

Override the default deadzone with the given value.

set_samples(samples)

Override the default number of sample reads with the given value.

update(samples=None)

Re-read the ADC and update the buffered value

@param samples Specifies the number of samples to average to de-noise the ADC reading

See europi.AnalogueReader for details on ADC sampling

class experimental.knobs.DisabledKnob(knob: Knob)

A LockableKnob that cannot be unlocked and whose value is unimportant. Useful when building multifunction knobs.

Parameters

knob – The knob to wrap.

choice(values, samples=None, deadzone=None)

Return a value from a list chosen by the current voltage value.

lock(samples=None)

Locks this knob at its current state. Makes a call to the underlying knob’s _sample_adc() method with the given number of samples.

percent(samples=None, deadzone=None)

Return the knob’s position as relative percentage.

range(steps=100, samples=None, deadzone=None)

Return a value (upper bound excluded) chosen by the current voltage value.

read_position(steps=100, samples=None, deadzone=None)

Returns the position as a value between zero and provided integer.

request_unlock()

LockedKnob can never be unlocked

set_deadzone(deadzone)

Override the default deadzone with the given value.

set_samples(samples)

Override the default number of sample reads with the given value.

class experimental.knobs.KnobBank(physical_knob: Knob, virtual_knobs, initial_selection)

A KnobBank is a group of named ‘virtual’ :class”LockableKnobs that share the same physical knob. Only one of these knobs is active (unlocked) at a time. This allows for a single knob to be used to control many parameters.

It is recommended that KnobBanks be created using the :class:Builder, as in:

k1_bank = (
    KnobBank.builder(k1)
    .with_disabled_knob()
    .with_unlocked_knob("x", threshold=0.02)
    .with_locked_knob("y", initial_percentage_value=1)
    .build()
)

Knobs can be referenced using their names:

k1_bank.x.percent()
k1_bank.y.read_position()

Note

KnobBank is not thread safe. It is possible to end up with two unlocked knobs if you call next() and take readings from a knob in two different threads. This can easily happen if your script calls next() in a button handler, while constantly reading the knob state in a main loop. The workaround is to set a flag in the button handler and call next() in the main loop.

For example:

class KnobBankExample(EuroPiScript):
    def __init__(self):
        super().__init__()
        self.next_k1 = False

        self.kb1 = (
            KnobBank.builder(k1)
            .with_locked_knob("p1", initial_percentage_value=1, threshold_percentage=0.02)
            .with_locked_knob("p2", initial_percentage_value=1)
            .with_locked_knob("p3", initial_percentage_value=1)
            .build()
        )

        @b1.handler
        def next_knob1():
            self.next_k1 = True

    def main(self):

        while True:
            if self.next_k1:
                self.kb1.next()
                self.next_k1 = False

            # main loop body
class Builder(knob: Knob)

A convenient interface for creating a KnobBank with consistent initial state.

build() KnobBank

Create the KnobBank with the specified knobs.

with_disabled_knob() Builder

Add a DisabledKnob to the bank. This disables the knob so that no parameters can be changed.

with_locked_knob(name: str, initial_percentage_value=None, initial_uint16_value=None, threshold_percentage=None, threshold_from_choice_count=None) Builder

Add a LockableKnob to the bank whose initial state is locked.

threshold_from_choice_count is a convenience parameter to be used in the case where this knob will be used to select from a relatively few number of choices, via the choice() method. Pass the number of choices to this parameter and an appropriate threshold value will be calculated.

Parameters
  • name – the name of this virtual knob

  • threshold_percentage – the threshold percentage for this knob as described by LockableKnob

  • threshold_from_choice_count – Provides the number of choices this knob will be used with in order to generate an appropriate threshold.

with_unlocked_knob(name: str, threshold_percentage=None, threshold_from_choice_count=None) Builder

Add a LockableKnob to the bank whose initial state is unlocked. This knob will be active. Only one unlocked knob may be added to the bank.

threshold_from_choice_count is a convenience parameter to be used in the case where this knob will be used to select from a relatively few number of choices, via the choice() method. Pass the number of choices to this parameter and an appropriate threshold value will be calculated.

Parameters
  • name – the name of this virtual knob

  • threshold_percentage – the threshold percentage for this knob as described by LockableKnob

  • threshold_from_choice_count – Provides the number of choices this knob will be used with in order to generate an appropriate threshold.

property current: LockableKnob

The currently active knob.

next()

Select the next knob by locking the current knob, and requesting an unlock on the next in the bank.

set_current(name)

Set the currently-unlocked knob to the one whose name matches the argument

@param name The name of the knob to set as the current one

class experimental.knobs.LockableKnob(knob: Knob, initial_percentage_value=None, initial_uint16_value=None, threshold_percentage=0.05)

A Knob whose state can be locked on the current value. Once locked, reading the knob’s position will always return the locked value. When unlocking the knob, the value still doesn’t change until the position of the knob moves to within threshold percent of the value. This prevents large jumps in a stetting when the knob is unlocked.

This class is useful for cases where you want to have a single physical knob control several parameters (see also the KnobBank class). Or where the value of a parameter needs to be disassociated from the position of the knob, as in after loading saved state.

This class accepts two different parameters to specify it’s initial value, initial_uint16_value and initial_percentage_value. Only one initial value may be specified. If both are specified, initial_percentage_value is ignored. The percentage value is more useful if you would like to hardcode a starting value for a knob in the code in a readable way. The uint16 value uses the knob’s internal representation and is more appropriate for use when loading a saved knob position. If your script would like to read the internal representation of current position of a LockableKnob, first lock the knob, then read it’s value.:

lockable_knob.lock()
internal_rep = lockable_knob.value
Parameters
  • knob – The knob to wrap.

  • initial_uint16_value – The UINT16 (0-europi.MAXINT16) value to lock the knob at. If a value is provided the new knob is locked, otherwise it is unlocked.

  • initial_percentage_value – The percentage (as a decimal 0-1) value to lock the knob at. If a value is provided the new knob is locked, otherwise it is unlocked.

  • threshold – a decimal between 0 and 1 representing how close the knob must be to the locked value in order to unlock. The percentage is in terms of the knobs full range. Defaults to 5% (0.05)

choice(values, samples=None, deadzone=None)

Return a value from a list chosen by the current voltage value.

lock(samples=None)

Locks this knob at its current state. Makes a call to the underlying knob’s _sample_adc() method with the given number of samples.

percent(samples=None, deadzone=None)

Return the knob’s position as relative percentage.

range(steps=100, samples=None, deadzone=None)

Return a value (upper bound excluded) chosen by the current voltage value.

read_position(steps=100, samples=None, deadzone=None)

Returns the position as a value between zero and provided integer.

request_unlock()

Requests that the knob be unlocked. The knob will unlock the next time a reading of it’s position is taken that is withing the threshold percentage of the locked value. That is, when the knob is moved close to the locked value. If lock() is called before the knob unlocks, the unlock is aborted.

set_deadzone(deadzone)

Override the default deadzone with the given value.

set_samples(samples)

Override the default number of sample reads with the given value.

class experimental.knobs.MedianAnalogInput(analog_in, samples=100, window_size=5)

A wrapper for an analogue input (e.g. knob, ain) that provides additional smoothing & debouncing

This class uses a window of the n latest samples from the underlying input and uses the median of those samples. Larger window sizes will produce a more stable output, but at the cost of slowing down reaction time to changes.

percent()

Read the hardware percentage and apply our additional smoothing

Smoothing is done using a simple 5-window median filter