NeoTrellis 4x4 RGB Button Pad Module
Nim wrapper for the Adafruit NeoTrellis 4x4 RGB keypad.
The NeoTrellis is a 4x4 grid of elastomer buttons with individually addressable RGB NeoPixel LEDs underneath. It combines capacitive touch sensing with vibrant RGB lighting, perfect for creating custom controllers and MIDI interfaces.
Features:
- 16 elastomer buttons (4x4 grid) with capacitive touch sensing
- 16 individually addressable RGB NeoPixels
- Key event detection (press/release with rising/falling edge)
- Callback support for key events
- I2C interface only
- Based on Seesaw firmware
Example:
import nimphea import nimphea/dev/neotrellis var trellis: NeoTrellisI2C var config: NeoTrellisConfig # Configure I2C transport config.transport_config.address = NEO_TRELLIS_ADDR config.transport_config.periph = I2C_PERIPH_1 config.transport_config.speed = I2C_400KHZ config.transport_config.scl = seed.GetPin(11) # PB8 config.transport_config.sda = seed.GetPin(12) # PB9 if trellis.init(config) == NEOTRELLIS_OK: # Activate all keys to detect rising and falling edges for x in 0..3: for y in 0..3: trellis.activateKey(x, y, RISING, true) trellis.activateKey(x, y, FALLING, true) while true: trellis.process() # Read events and update state for i in 0..15: if trellis.getRising(i): # Button i was just pressed trellis.pixels.setPixelColor(i, 255, 0, 0) # Red if trellis.getFalling(i): # Button i was just released trellis.pixels.setPixelColor(i, 0, 0, 0) # Off trellis.pixels.show()
Types
KeyEvent {.importcpp: "daisy::NeoTrellis<daisy::NeoTrellisI2CTransport>::keyEvent", bycopy.} = object reg* {.importcpp: "reg".}: uint16
- Key event structure Source Edit
NeoPixelI2C {.importcpp: "daisy::NeoPixelI2C", bycopy.} = object
- NeoPixel I2C controller (from dev/neopixel.h) Source Edit
NeoPixelI2CConfig {.importcpp: "daisy::NeoPixelI2C::Config", bycopy.} = object
- NeoPixel I2C configuration (from dev/neopixel.h) Source Edit
NeoTrellisConfig {.importcpp: "daisy::NeoTrellisI2C::Config", bycopy.} = object transport_config* {.importcpp: "transport_config".}: NeoTrellisI2CTransportConfig pixels_conf* {.importcpp: "pixels_conf".}: NeoPixelI2CConfig
- NeoTrellis device configuration Source Edit
NeoTrellisI2C {.importcpp: "daisy::NeoTrellisI2C", bycopy.} = object pixels* {.importcpp: "pixels".}: NeoPixelI2C
- NeoTrellis device with I2C transport Source Edit
NeoTrellisI2CTransport {.importcpp: "daisy::NeoTrellisI2CTransport", bycopy.} = object
- I2C transport for NeoTrellis Source Edit
NeoTrellisI2CTransportConfig {.importcpp: "daisy::NeoTrellisI2CTransport::Config", bycopy.} = object periph* {.importcpp: "periph".}: I2CPeripheral speed* {.importcpp: "speed".}: I2CSpeed scl* {.importcpp: "scl".}: Pin sda* {.importcpp: "sda".}: Pin address* {.importcpp: "address".}: uint8
- I2C transport configuration Source Edit
NeoTrellisKeypadEdge {.importcpp: "daisy::NeoTrellis<daisy::NeoTrellisI2CTransport>::KeypadEdge", size: 4.} = enum NEO_TRELLIS_HIGH = 0, ## Key is currently high NEO_TRELLIS_LOW = 1, ## Key is currently low NEO_TRELLIS_FALLING = 2, ## Falling edge (key released) NEO_TRELLIS_RISING = 3 ## Rising edge (key pressed)
- Key event edge types Source Edit
NeoTrellisResult {.importcpp: "daisy::NeoTrellis<daisy::NeoTrellisI2CTransport>::Result", size: 4.} = enum NEOTRELLIS_OK = 0, ## Success NEOTRELLIS_ERR = 1 ## Error
- Operation result Source Edit
TrellisCallback = proc (evt: KeyEvent) {.cdecl.}
- Callback function type for key events Source Edit
Consts
NEO_TRELLIS_ADDR = 0x2E'u8
- Default I2C address Source Edit
NEO_TRELLIS_NUM_COLS = 4'i32
- Number of columns Source Edit
NEO_TRELLIS_NUM_KEYS = 16'i32
- Total number of keys (4x4) Source Edit
NEO_TRELLIS_NUM_ROWS = 4'i32
- Number of rows Source Edit
Procs
proc activateKey(this: var NeoTrellisI2C; x: uint8; y: uint8; edge: uint8; enable: bool) {.importcpp: "#.ActivateKey(#, #, #, #)", header: "dev/neotrellis.h", ...raises: [], tags: [], forbids: [].}
-
Activate or deactivate a key event
Parameters:
- x - Column index (0-3, 0 is leftmost)
- y - Row index (0-3, 0 is topmost)
- edge - Edge sensitivity (NEO_TRELLIS_RISING, NEO_TRELLIS_FALLING, etc.)
- enable - true to enable event, false to disable
proc clear(this: var NeoPixelI2C) {.importcpp: "#.Clear()", header: "dev/neopixel.h", ...raises: [], tags: [], forbids: [].}
- Clear all pixels (set to off/black) Source Edit
proc enableKeypadInterrupt(this: var NeoTrellisI2C) {. importcpp: "#.EnableKeypadInterrupt()", header: "dev/neotrellis.h", ...raises: [], tags: [], forbids: [].}
-
Enable keypad interrupt
Enables the interrupt that fires when events are in the FIFO.
Source Edit proc getFalling(this: var NeoTrellisI2C; idx: uint8): bool {. importcpp: "#.GetFalling(#)", header: "dev/neotrellis.h", ...raises: [], tags: [], forbids: [].}
-
Check if a key was just released (falling edge)
Clears the falling flag after reading. Updated by process() function.
Parameters:
- idx - Key index (0-15)
Returns: true if just released
Source Edit proc getKeypadCount(this: var NeoTrellisI2C): uint8 {. importcpp: "#.GetKeypadCount()", header: "dev/neotrellis.h", ...raises: [], tags: [], forbids: [].}
-
Get the number of events in the FIFO
Returns: Number of events waiting to be read
Source Edit proc getRising(this: var NeoTrellisI2C; idx: uint8): bool {. importcpp: "#.GetRising(#)", header: "dev/neotrellis.h", ...raises: [], tags: [], forbids: [].}
-
Check if a key was just pressed (rising edge)
Clears the rising flag after reading. Updated by process() function.
Parameters:
- idx - Key index (0-15)
Returns: true if just pressed
Source Edit proc getState(this: var NeoTrellisI2C; idx: uint8): bool {. importcpp: "#.GetState(#)", header: "dev/neotrellis.h", ...raises: [], tags: [], forbids: [].}
-
Check if a key is currently pressed
Updated by process() function.
Parameters:
- idx - Key index (0-15)
Returns: true if pressed, false if released
Source Edit proc getTransportError(this: var NeoTrellisI2C): NeoTrellisResult {. importcpp: "#.GetTransportError()", header: "dev/neotrellis.h", ...raises: [], tags: [], forbids: [].}
-
Get and reset the transport error flag
Returns: NEOTRELLIS_ERR if error occurred, NEOTRELLIS_OK otherwise
Source Edit proc init(this: var NeoTrellisI2C; config: NeoTrellisConfig): NeoTrellisResult {. importcpp: "#.Init(#)", header: "dev/neotrellis.h", ...raises: [], tags: [], forbids: [].}
-
Initialize the NeoTrellis device
Parameters:
- config - Configuration struct with transport settings
Returns: NEOTRELLIS_OK on success, NEOTRELLIS_ERR on failure
Source Edit proc initNeoTrellisConfig(): NeoTrellisConfig {.constructor, importcpp: "daisy::NeoTrellisI2C::Config(@)", header: "dev/neotrellis.h".}
- Initialize device config with defaults Source Edit
proc initNeoTrellisI2CTransportConfig(): NeoTrellisI2CTransportConfig {. constructor, importcpp: "daisy::NeoTrellisI2CTransport::Config(@)", header: "dev/neotrellis.h".}
- Initialize I2C transport config with defaults Source Edit
proc process(this: var NeoTrellisI2C; polling: bool = true) {. importcpp: "#.Process(#)", header: "dev/neotrellis.h", ...raises: [], tags: [], forbids: [].}
-
Read all events from the FIFO and update state
Call this regularly to process key events and update rising/falling states.
Parameters:
- polling - true if not using interrupt pin, false if using interrupt (default: true)
proc read8(this: var NeoTrellisI2C; reg_high: uint8; reg_low: uint8; delay: cint): uint8 {. importcpp: "#.Read8(#, #, #)", header: "dev/neotrellis.h", ...raises: [], tags: [], forbids: [].}
-
Read an 8-bit value from a register
Parameters:
- reg_high - High byte of register address
- reg_low - Low byte of register address
- delay - Delay in microseconds before reading
Returns: 8-bit register value
Source Edit proc registerCallback(this: var NeoTrellisI2C; x: uint8; y: uint8; cb: TrellisCallback) {. importcpp: "#.RegisterCallback(#, #, #)", header: "dev/neotrellis.h", ...raises: [], tags: [], forbids: [].}
-
Register a callback for a key
Parameters:
- x - Column index (0-3)
- y - Row index (0-3)
- cb - Callback function to call when event detected
proc setKeypadEvent(this: var NeoTrellisI2C; key: uint8; edge: uint8; enable: bool) {.importcpp: "#.SetKeypadEvent(#, #, #)", header: "dev/neotrellis.h", ...raises: [], tags: [], forbids: [].}
-
Activate or deactivate a key event by key number
Parameters:
- key - Key number (0-15)
- edge - Edge sensitivity
- enable - true to enable, false to disable
proc setPixelColor(this: var NeoPixelI2C; pixel: uint16; r: uint8; g: uint8; b: uint8) {.importcpp: "#.SetPixelColor(#, #, #, #)", header: "dev/neopixel.h", ...raises: [], tags: [], forbids: [].}
-
Set a pixel's RGB color
Parameters:
- pixel - Pixel index (0-15 for NeoTrellis)
- r - Red value (0-255)
- g - Green value (0-255)
- b - Blue value (0-255)
proc show(this: var NeoPixelI2C) {.importcpp: "#.Show()", header: "dev/neopixel.h", ...raises: [], tags: [], forbids: [].}
-
Update all pixels with buffered color values
Must be called after setPixelColor() to actually display the colors.
Source Edit proc swReset(this: var NeoTrellisI2C) {.importcpp: "#.SWReset()", header: "dev/neotrellis.h", ...raises: [], tags: [], forbids: [].}
-
Perform a software reset
Resets all Seesaw registers to default values.
Source Edit proc unregisterCallback(this: var NeoTrellisI2C; x: uint8; y: uint8) {. importcpp: "#.UnregisterCallback(#, #)", header: "dev/neotrellis.h", ...raises: [], tags: [], forbids: [].}
-
Unregister a callback for a key
Parameters:
- x - Column index (0-3)
- y - Row index (0-3)
proc write8(this: var NeoTrellisI2C; reg_high: uint8; reg_low: uint8; value: uint8) {.importcpp: "#.Write8(#, #, #)", header: "dev/neotrellis.h", ...raises: [], tags: [], forbids: [].}
-
Write an 8-bit value to a register
Parameters:
- reg_high - High byte of register address
- reg_low - Low byte of register address
- value - Value to write