nimphea/hid/ctrl

Search:
Group by:
Source   Edit  

Controls and sensors support for libDaisy Nim wrapper

This module provides support for encoders, switches, analog controls, and ADC.

Example - Simple button:

import nimphea, hid/ctrl

var daisy = initDaisy()
var button = initSwitch(D2())

while true:
  button.update()
  if button.pressed:
    daisy.setLed(true)
  elif button.released:
    daisy.setLed(false)
  daisy.delay(1)

Example - Rotary encoder:

var encoder = initEncoder(D0(), D1(), D2())
var value = 0

while true:
  encoder.update()
  value += encoder.increment
  daisy.delay(1)

Example - Analog input (ADC):

var adc = initAdc(daisy, [A0(), A1()])
adc.start()

while true:
  let knob1 = adc.value(0)  # 0.0 to 1.0
  let knob2 = adc.value(1)
  daisy.delay(10)

Types

AdcChannelConfig {.importcpp: "daisy::AdcChannelConfig".} = object
Source   Edit  
AdcHandle {.importcpp: "daisy::AdcHandle".} = object
Source   Edit  
AdcReader = object
Source   Edit  
AnalogControl {.importcpp: "daisy::AnalogControl".} = object
Source   Edit  
ConversionSpeed {.importcpp: "daisy::AdcChannelConfig::ConversionSpeed", size: 4.} = enum
  SPEED_1CYCLES_5 = 0, SPEED_2CYCLES_5, SPEED_8CYCLES_5, SPEED_16CYCLES_5,
  SPEED_32CYCLES_5, SPEED_64CYCLES_5, SPEED_387CYCLES_5, SPEED_810CYCLES_5
Source   Edit  
Encoder {.importcpp: "daisy::Encoder".} = object
Source   Edit  
MuxPin {.importcpp: "daisy::AdcChannelConfig::MuxPin", size: 4.} = enum
  MUX_SEL_0 = 0, MUX_SEL_1, MUX_SEL_2, MUX_SEL_LAST
Source   Edit  
OverSampling {.importcpp: "daisy::AdcHandle::OverSampling", size: 4.} = enum
  OVS_NONE = 0, OVS_4, OVS_8, OVS_16, OVS_32, OVS_64, OVS_128, OVS_256, OVS_512,
  OVS_1024, OVS_LAST
Source   Edit  
Switch {.importcpp: "daisy::Switch".} = object
Source   Edit  
SwitchPolarity {.importcpp: "daisy::Switch::Polarity", size: 4.} = enum
  POLARITY_NORMAL = 0, POLARITY_INVERTED
Source   Edit  
SwitchPull {.importcpp: "daisy::Switch::Pull", size: 4.} = enum
  PULL_UP = 0, PULL_DOWN, PULL_NONE
Source   Edit  
SwitchType {.importcpp: "daisy::Switch::Type", size: 4.} = enum
  TYPE_MOMENTARY = 0, TYPE_LATCHING, TYPE_TOGGLE
Source   Edit  

Procs

proc fallingEdge(encoder: var Encoder): bool {....raises: [], tags: [], forbids: [].}
Check if encoder button was just released Source   Edit  
proc fallingEdge(switch: var Switch): bool {....raises: [], tags: [], forbids: [].}
Check if switch just transitioned to released (trigger once) Source   Edit  
proc getRawFloat(control: var AnalogControl): float {....raises: [], tags: [],
    forbids: [].}
Source   Edit  
proc getRawValue(control: var AnalogControl): uint16 {....raises: [], tags: [],
    forbids: [].}

Get the raw unsigned 16-bit ADC value.

Returns: Raw ADC value (0 to 65535)

Source   Edit  
proc increment(encoder: var Encoder): int {....raises: [], tags: [], forbids: [].}
Get encoder position change since last call (-N to +N) Source   Edit  
proc initAdc(daisy: var DaisySeed; pins: openArray[Pin]; oversampling: int = 4): AdcReader {.
    ...raises: [], tags: [], forbids: [].}

Initialize ADC for reading analog inputs

Parameters: daisy: The DaisySeed instance pins: Array of analog pins to read (e.g., A0(), A1(), A2()) oversampling: Oversampling rate (0=NONE, 1=4x, 2=8x, 3=16x, 4=32x (default), 5=64x, etc.)

Example:

var adc = initAdc(daisy, [A0(), A1(), A6()])
adc.start()
let knob1Value = adc.value(0)  # Read first channel

Source   Edit  
proc initAnalogControl(adcPtr: ptr uint16; sampleRate: float;
                       flip: bool = false; invert: bool = false;
                       slewSeconds: float = 0.002): AnalogControl {....raises: [],
    tags: [], forbids: [].}

Initialize an AnalogControl for a potentiometer or CV input.

This provides filtered, smoothed analog input with slew limiting.

Parameters: adcPtr: Pointer to raw ADC value (from AdcHandle.getPtr()) sampleRate: Rate at which process() will be called (Hz) flip: If true, flip the input (1.0 - input) invert: If true, invert the input (-1.0 * input) slewSeconds: Slew time in seconds for value changes (smoothing)

Example:

# Setup ADC for analog input
var adc = initAdc(daisy, [A0()])
adc.start()

# Create AnalogControl connected to ADC channel 0
var knob = initAnalogControl(daisy.adc.getPtr(0), 1000.0)

while true:
  let value = knob.process()  # Returns 0.0 to 1.0
  daisy.delay(1)

Source   Edit  
proc initBipolarCv(adcPtr: ptr uint16; sampleRate: float): AnalogControl {.
    ...raises: [], tags: [], forbids: [].}

Initialize an AnalogControl for bipolar CV input (-5V to +5V).

This is a specialized initialization for CV inputs that range from -5V to +5V. The output will be in the range -1.0 to +1.0.

Parameters: adcPtr: Pointer to raw ADC value (from AdcHandle.getPtr()) sampleRate: Rate at which process() will be called (Hz)

Example:

var adc = initAdc(daisy, [A0()])
adc.start()

var cvInput = initBipolarCv(daisy.adc.getPtr(0), 1000.0)

while true:
  let cv = cvInput.process()  # Returns -1.0 to +1.0
  daisy.delay(1)

Source   Edit  
proc initEncoder(pinA, pinB: Pin; clickPin: Pin = Pin();
                 updateRate: float = 1000.0): Encoder {....raises: [], tags: [],
    forbids: [].}

Initialize a rotary encoder

Parameters: pinA, pinB: Encoder signal pins clickPin: Optional click button pin (use Pin() to skip) updateRate: How often to check the encoder (Hz)

Example:

var encoder = initEncoder(D0(), D1(), D2())  # With click
var encoderNoClick = initEncoder(D3(), D4())  # Without click

Source   Edit  
proc initSwitch(pin: Pin; updateRate: float = 1000.0;
                switchType: SwitchType = TYPE_MOMENTARY;
                polarity: SwitchPolarity = POLARITY_NORMAL;
                pull: SwitchPull = PULL_UP): Switch {....raises: [], tags: [],
    forbids: [].}

Initialize a switch/button

Parameters: pin: The GPIO pin the switch is connected to updateRate: How often to check the switch (Hz) switchType: TYPE_MOMENTARY, TYPE_LATCHING, or TYPE_TOGGLE polarity: POLARITY_NORMAL or POLARITY_INVERTED pull: PULL_UP, PULL_DOWN, or PULL_NONE

Example:

var button = initSwitch(D2())  # Simple momentary button

Source   Edit  
proc pressed(encoder: var Encoder): bool {....raises: [], tags: [], forbids: [].}
Check if encoder button is pressed Source   Edit  
proc pressed(switch: var Switch): bool {....raises: [], tags: [], forbids: [].}
Check if switch is currently pressed Source   Edit  
proc process(control: var AnalogControl): float {....raises: [], tags: [],
    forbids: [].}
Source   Edit  
proc rawValue(adc: var AdcReader; channel: int): uint16 {....raises: [], tags: [],
    forbids: [].}
Get raw ADC value (0-65535) for a channel Source   Edit  
proc released(switch: var Switch): bool {....raises: [], tags: [], forbids: [].}
Check if switch is currently released Source   Edit  
proc risingEdge(encoder: var Encoder): bool {....raises: [], tags: [], forbids: [].}
Check if encoder button was just pressed Source   Edit  
proc risingEdge(switch: var Switch): bool {....raises: [], tags: [], forbids: [].}
Check if switch just transitioned to pressed (trigger once) Source   Edit  
proc setCoeff(control: var AnalogControl; coefficient: float) {....raises: [],
    tags: [], forbids: [].}

Set the coefficient of the one-pole smoothing filter.

Parameters: coefficient: Filter coefficient (0.0 to 1.0) Higher values = less smoothing (faster response) Lower values = more smoothing (slower response)

Source   Edit  
proc setOffset(control: var AnalogControl; offset: float) {....raises: [],
    tags: [], forbids: [].}

Set the offset used by the process function.

Normally set during initialization, but can be adjusted for calibration.

Parameters: offset: Offset to add to the processed value

Source   Edit  
proc setSampleRate(control: var AnalogControl; sampleRate: float) {....raises: [],
    tags: [], forbids: [].}

Set a new sample rate after initialization.

Parameters: sampleRate: New update rate in Hz

Source   Edit  
proc setScale(control: var AnalogControl; scale: float) {....raises: [], tags: [],
    forbids: [].}

Set the scaling factor used by the process function.

Normally set during initialization, but can be adjusted for calibration.

Parameters: scale: Scaling factor to apply to the processed value

Source   Edit  
proc start(adc: var AdcReader) {....raises: [], tags: [], forbids: [].}
Start ADC conversions Source   Edit  
proc stop(adc: var AdcReader) {....raises: [], tags: [], forbids: [].}
Stop ADC conversions Source   Edit  
proc timeHeld(encoder: var Encoder): float {....raises: [], tags: [], forbids: [].}
Source   Edit  
proc timeHeld(switch: var Switch): float {....raises: [], tags: [], forbids: [].}
Source   Edit  
proc update(encoder: var Encoder) {....raises: [], tags: [], forbids: [].}
Update encoder state (call this regularly) Source   Edit  
proc update(switch: var Switch) {....raises: [], tags: [], forbids: [].}
Update switch state (call this regularly, typically in main loop) Source   Edit  
proc value(adc: var AdcReader; channel: int): float {....raises: [], tags: [],
    forbids: [].}
Source   Edit  
proc value(control: AnalogControl): float {....raises: [], tags: [], forbids: [].}
Source   Edit