Looking for a 16 step custom control for ARP and SEQ

Hi,

I’m looking for someone to help me out on making a custom control that can control sequencers or ARP’s with note lists (like Waldorf does).
The custom control should be 5-6 slots wide and 1 slot deep and contain the following:

  • 16 parameters in a row , grouped per 4 by a vertical line in between
  • all parameters share the same overlay list
  • only the bitmaps or the values are to be shown, no faders
  • the custom control name
  • the custom control encoder number, used for parameter selection
  • the custom control encoder number, used for parameter value setting

The idea is that the custom control is reusable so one screen can contain up to 6 such controls.
As each custom control only uses 2 encoders. So the Mk2’s 12 encoders can control all 6 custom controls at once, giving you access to up to 16*6 = 96 parameters within a single screen.
A custom control must also obey one common parameter that sets the max range between 0..16. Any parameter of the 16 above the range is to be hidden or darkened. That common parameter is shareable amongst multiple (but not all) custom controls. Not all, because else we would not be able to use the custom control for 32 or 64 step sequencers.

All 16 parameters are to be seen as virtual parameters in the parameter map. Setting them remotely will be done by sysex and midi CC callbacks.

Below is an example on how such custom control looks like on a Micro Q
image

Who can help? I see applications for Sequential, Waldorf and many more presets.

Hi,

Saw your thread and gave it a shot — draft here :
Electra One Widgets (look for 16-Step Note List under Design System)

Not sure I got everything right, easily possible this isn’t quite what you had in mind. The README walks through how I interpreted each line of your spec — if you’ve got 5
minutes of feedback I’d really appreciate it. MIT license, source open, fork or rewrite freely.

Source + uploadable preset JSON :

-– Romi

3 Likes

Hi Romi,
thanks for your work.
Visually it looks already promising!

But I’ll need some guidance from you though on how I can extract the widget or the example json and create a preset with me. Can you guide me?

Hi NewIgnis,
Sure! Easiest path:

  1. Grab the preset JSON directly: https://raw.githubusercontent.com/roomi-fields/electraone-widgets/main/widgets/note-list-16/demo.preset.json
  2. Open app.electra.one and create a new empty preset.
  3. Drag-drop the .json file into the editor canvas, or open the “Source / JSON view” tab and paste the contents — the editor will replace the empty preset with the widget.
  4. Click “Send to Electra” to push it to your controller.
    That gives you the 2 lines demo

To customise the step list:

  • Edit the lanes[ ].cells array in the Lua script (16 values per lane)
  • Or replace the overlay table to label each step with note names / chord degrees / drum sounds — see the README under “Overlays — defining your own step list”:

One firmware caveat from the README I should flag: custom tiles only receive events from 1 pot in firmware 4.1.4
So instead of “encoder #1 = step select, encoder #2 = value”, I use a single encoder + click-to-toggle-mode pattern (dbl-click to activate/deactivate)

I can’t believe my eyes… this looks like amazing work. But it’s rather irritating that this stuff is neither in the official preset library nor in the documentation. There’s so much stuff possible but almost no examples around. This is the biggest weakness of the Electra One right now. Almost everything is possible but one has to dive deeeeep to get started. Sorry for hijacking this thread :sweat_smile:

1 Like

Okay, I got started :slight_smile:

I’ll inform you in a c ouple of days of what I figured out to do .

Thanks for the works so far, it looks promising as a starting point

Dear Klaustorphil,

you are in a user community here, with stuff that is being thought of and/or developed by users themselves. So you can’t expect this to be in ‘official’ documentation, that would be contradictory to what a user community stands for.

Perhaps in time, when ideas start to standardise themselves, they can be picked up by the Electra One staff and added to their E1 standard.

But here the idea is 11 days old…

1 Like

Hi Roomi,

I’m first focusing on the User Interface itself. I can make things move by selecting via the touch screen, not via other means yet.

  • I have none of the twelve pots doing something. How do I set what pot impacts the first and what pot impacts the second line?
  • In the downloaded example, only steps 1..12 are active. How do I set the useable length between 1..16? Ideally there is a virtual parameter in the parameter map I should be able to use for this purpose.
  • How can I see /set the difference between steps being muted but stil passed through, and total step length shortened ?
  • Do I have it right that paramBase is the lowest virtual parameter of a row, assuming each step raises the parameternumber with 1?
  • Do I have it right that , in order to add lanes, I do this by enhancing the lanes array between rows 856-869 as well as the arrays found between 871 and 881? I tried but no new lane appeared.
  • What is the function of encEdit (line 861 and 867)?
  • How do I define the position of a lane (which of the 12 pages as well as which of the 6 rows)?
  • What does laneMode do (line 886)?
  • If possible, add a variable defining whether the value bar is to be shown horizontal or vertical?
  • When I change the parameter map via other faders, the values in the widget don’t change accordingly (the other way works !)

Hi NewIgnis,

Great set of questions.
I shipped rev 149 just now that fixes the four that actually needed code. Detail per question:

1. “How do I set what pot impacts the first and what pot impacts the second lane?”
Two things have to align before any pot fires on a tile:

(a) Pick the active control set. into the 3 horizontal sections (controlSetId 1 / 2 / 3). The 12 physical pots only address the currently-active set.

Slot ranges per set:

  • Set 1: slotId 0 .. 23 — active when the top-left button is pressed (default at boot)
  • Set 2: slotId 24 .. 47 — active when the middle-left button is pressed
  • Set 3: slotId 48 .. 71 — active when the bottom-left button is pressed

Verified mapping for set 1 on firmware 4.1.4:

  • slotId = 1, top row full-width → bottom-left pot, ev.id = 6
  • slotId = 7, bottom row full-width → top-left pot, ev.id = 0

That field is the only place that controls pot ↔ lane binding:

lanes = {
[1] = { name = "NOTES", ..., potEvId = 6, ... }, -- tile at slotId 1, set 1
[2] = { name = "VELOCITY", ..., potEvId = 0, ... }, -- tile at slotId 7, set 1
}

Rev 149 renames the old encEdit field to potEvId (clearer name) but keeps the old name as a backward-compat alias. The lane also has an optional targetLane field if you want a different cross-dispatch (e.g., top-pot drives top-lane rather than its column-opposite).

2. “Steps 1..12 active, want full 1..16 with virtual param for the length”

Three things make this work, all in lane config:

  • lane.cells = { v1, v2, ..., v16 } — the initial value table, 16 entries (0..127). Edit this to ship a default pattern.
  • lane.initialMuted = { [3] = true, [7] = true, ... } (new in rev 149) — the initial mute table, listing which step indices start muted on preset load. Useful for shipping a default rhythmic pattern.
  • Double-click the pot at runtime to activate/deactivate the currently selected step. The underlying value is preserved (muted = emit 0, stored value kept; unmute restores).

For the active step count itself (your “1..16”), the widget exposes the virtual parameter PARAM_COMMON_RANGE (= 33) — rev 149 listens to it via parameterMap.onChange, so drop a fader on another page mapped to virtual:33 on device 1 and the live step count moves with it. Default is now 16 (all active).

3. Mute pass-through vs total step length — confirming what you want

Just to be sure I’m building the right thing — two distinct concepts exist in the widget, and they map to two of your questions:

  • Mute (per-step) — Q2 territory. Step N stays in range visually (shown as !), keeps its stored value, emits 0 over MIDI. Toggled with double-click on the pot or pre-set via initialMuted. Useful for skipping a step inside the pattern without losing it.
  • Length (commonRange) — this question. Steps beyond commonRange render with a CANVAS background and a dim dot, are NOT part of the sequence anymore, and shouldn’t be played. Driven by virtual param 33.

Are these two concepts you want both, or is what you actually need just one of them (a single “number of active steps” knob, no per-step mute)? The current widget does both because the spec was ambiguous; if you only need the length, I can simplify the UX (drop the double-click mute entirely).

4. “paramBase is the lowest virtual param of a row, +1 per step”
Exactly. Lane 1 (paramBase=0) → virtual params 1..16. Lane 2 (paramBase=16) → 17..32. Step N of lane L writes to virtual param lane.paramBase + N on device 1.

5. “Tried to add lanes — no new lane appeared”
Pre-rev-148 the state tables (selectedStep, dragging, muted, laneMode, potState) and preset.onLoad were hardcoded for indices 1 and 2 only, and the cross-dispatch forced (sourceId == 1) ? 2 : 1. Rev 149 iterates over #lanes everywhere and adds a per-lane targetLane field (default = self), so adding lane 3+ now needs only:

  1. A 3rd custom tile in the JSON. Pick a slotId from the ranges in Q1 — and remember it determines which control set the tile lives in.
  2. A new entry in the lanes table with the matching potEvId.
  3. (optional) Set targetLane if you want it to drive a different lane.

6. “What does encEdit do (renamed potEvId in rev 149)”
It’s the ev.id the firmware dispatches to this tile’s pot. Used as a filter in potLane: events with a different ev.id are ignored. The name was misleading — potEvId is what it actually means.

7. “How to define the position of a lane (page, row)”
Two places:

  • JSON tiles[].slotId (0..71 per page on MK2) — sets which slot on the page the tile occupies. Slot range determines which control set the tile lives in (see Q1). Pages are separate JSON pages[] entries.
  • Lua c:setBounds({x, y, w, h}) in preset.onLoad — the actual painted area in pixels. The widget defaults to {0, (i-1)*100, 1016, 100} for full-width lanes stacked vertically.

8. “What does laneMode do?”
Per-lane state machine, two states: "navigate" (pot turns step the selection 1..16) and "edit" (pot turns change the selected step’s value). A pot click toggles between the two; a double-click toggles the selected step’s mute state. The current state is shown as a “NAV” / “EDIT” pill in the lane header.

9. “Horizontal vs vertical value bar option”
Added in rev 148. Set lane.gaugeOrientation = "v" for a thin vertical bar on the right edge of each cell; default "h" keeps the original horizontal bar at the bottom.

10. “External fader changes don’t update the widget”
Fixed in rev 148. The widget now implements function parameterMap.onChange(valueObjects, origin, midiValue) which catches external changes to PARAM_COMMON_RANGE and to the per-step virtual params and repaints. The handler filters origin == LUA so it doesn’t loop on the widget’s own parameterMap.set writes.


Grab the updated preset: electraone-widgets/widgets/note-list-16/demo.preset.json at main · roomi-fields/electraone-widgets · GitHub

The lane configuration fields are now documented in the widget’s README. Holler if rev 149 doesn’t address your case exactly — happy to iterate.

Romi