If anyone’s looking for a good lightweight MIDI controller that’s an upgrade from a Korg nanoKontrol2 or a Behringer X-Touch Mini, I’d like to recommend the Presonus Atom SQ. Its greatest features are undocumented by Presonus(!), so I document them here for the community (see below). With Cantabile bindings and filters, the SQ becomes amazing.
Review:
Why I love it:
-
Almost everything is MIDI-controllable, including the RGB color of each of the 34 button/pads, each of the 25 little red LEDs above the touch strip (on/off), and even the text on the mini display screen. (Since the manual doesn’t reveal that this is possible, I document the MIDI codes for you below.)
-
The 8 encoder dials at the top are velocity-sensitive endless encoders. So they feel like absolute encoders (faster turns change values by more), but any automated parameter changes (e.g., when switching songs) don’t leave them in the “wrong positions” because they’re endless. They work perfectly with Cantabile’s “sign bit” relative binding mode, making binding them a snap.
-
The 34 button/pads are velocity-sensitive, so you can bind them to beats or sound fx; or just use them as on/off buttons.
-
The touch strip sends a fine CC (pitch-bend) MIDI message for finger slides, and a coarse CC message when tapped.
-
Build quality is excellent. Everything feels completely solid, and it’s light (feels like two nanoKontrols). Here’s a size comparison with the nanoKontrol2 sitting on a Nord Stage 3:
One drawback:
- I wish the 8 endless encoders had light-rings on them, like the X-Touch Mini. But this can be partially overcome with a Cantabile binding to reprogram the LED light strip (see details below).
MIDI Protocol Documented:
The SQ’s MIDI protocol is undocumented by Presonus (which is sad since it could be such a strong selling point). With a fair bit of experimentation I managed to reverse-engineer it; here are the details:
Sending MIDI data to the SQ:
- IMPORTANT: The first MIDI message you send to it should be a note-off on channel 16 with velocity 127 (hex:
0x8F 0x00 0x7F
). I use an “on song load” Cantabile sysex binding with sysex expressionx"8F007F"
. This puts the SQ in “native control” mode. (By default it’s in a “local control” mode that’s unresponsive to most MIDI messages.) Sending this message more than once is harmless, so it’s okay if all of your songs send it on-load. If for some reason you want return it to “local control” mode, send it the same message with note-off velocity 0 instead of 127.
Now that it’s in native control mode, you can send it the following messages to control lights and colors:
- The 34 lighted pad colors are controlled via note events for notes 36-51 (bottom row), 52-67 (top row) (hex
0x24
-0x33
and0x34
-0x43
), and 0-1 (+/- buttons at left of top row). Note events on channel 1 control the light state (velocity 0 = unlit, velocity 1 = blink, velocity 2 = breathe, and velocity 127 = lit). Note events on channels 2-4 set the Red, Green, and Blue (respectively) hues equal to note velocity.
Example: To set the bottom-left pad (hex 0x24
) to solid (0x7F
) red (R=0x7F
, G=0x00
, B=0x00
), send this: x"90247F" x"91247F" x"922400" x"932400"
.
- The following buttons can be unlit (CC value 0) or lit (CC value 127) by setting the following CCs on channel 1:
- A-H buttons: CCs 0-7
- Shift button: CC 31 (
0x1F
) - Named buttons left of the digital display: 32-35 (
0x20
-0x23
) - Three buttons above display: 36-38 (
0x24
-0x26
) - Three buttons below display: 39-41 (
0x27
-0x29
) - Left/Right buttons below the right-side rotary dial: 42-43 (
0x2A
-0x2B
) - Each of the red LEDs above the touch strip: 55-79 (
0x37
-0x4F
) - The up/down/left/right buttons below the display: 87, 89, 90, 102 (
0x57
,0x59
,0x5A
,0x66
) - The stop/play/record/metronome buttons: 111, 109, 107, 105 (
0x6F
,0x6D
,0x6B
,0x69
)
Example: To light the Shift button, send: x"B01F7F"
(channel=1, CC=31 (0x1F
), value=127 (0x7F
))
- To change the text on the digital display, send a sysex message with the following format:
- 6 bytes (message header):
0xF0 0x00 0x01 0x06 0x22 0x12
- 1 byte (text field to change): one of
0x00
-0x0D
(see below) - 3 bytes (text color): three 7-bit bytes (red, green, blue)
- 1 byte (text alignment): 0 = centered, 1 = left aligned, 2 = right aligned (+4 to invert text color)
- variable length: a string of 7-bit ascii characters (see below for special characters)
- 1 byte (message end):
0xF7
The available text fields are: (0 = top-left, 2 = top-center, 4 = top-right, 6 = middle, 8 = bottom-left, 10 = bottom-center, 12 = bottom-right). Add 1 to select the bottom line of the field instead of the top. For example, the bottom line of the middle area is field 6+1=7.
Example: To change the middle bottom line (field 0x07
) to green (0x007F00
) centered (0x00
) text saying “Hello” (0x48 0x65 0x6C 0x6C 0x6F
), send this sysex: x"F00001062212" x"07" x"007F00" x"00" x"48656C6C6F" x"F7"
The ascii text string can contain some special characters:
- 0x0A = folder icon
- 0x0B = 8th notes glyph
- 0x1B = power icon
- 0x1C = check mark
- 0x1D = X mark
- 0x1E = thin circle
- 0x1F = thick circle
- 0x7F = degree symbol
Receiving MIDI from the SQ:
The SQ sends velocity-sensitive note-on/off messages for the 34 pads (notes 0-1 and 36-67, same as above) on channel 1, and sends CC on/off (value 0/127) for all button-presses as documented above. In addition, it sends the following extra outputs:
-
The 8 endless encoders at the top send CC messages on controller numbers 14-21 using Cantabile’s “sign bit encoding” (relative mode binding).
-
The main encoder on the right of the device is not velocity-sensitive. It’s a rotary dial that sends +1 or -1 when turned right or left on CC 29 (channel 1). Use Cantabile’s “2’s complement encoding” (relative mode) to bind it.
-
The touch strip sends pitch bend MIDI messages (values 0-16383) when swiped, and sends CC values 0/127 on CC 64 when pushed.
Tip: Making the LED strip act like a meter in Cantabile
The only thing I dislike about the SQ is that its endless encoders don’t have any light rings, so you can’t see at a glance the values of whatever parameters they’re bound to. This can be partially overcome by using a Cantabile binding to reprogram the row of red LED lights to act like a meter. I use a Cantabile expression binding that receives CC messages on CC=126, and translates them into a series of on/off messages for the 25 lights. That way I can bind any encoder-controlled parameter to CC=126, causing its level to show on the LED strip. Here’s the binding I use:
With the sysex data expression set to the following:
x"B037" (value>0 ? 0x7f : 0x00)
x"B038" (value>1 ? 0x7f : 0x00)
x"B039" (value>2 ? 0x7f : 0x00)
x"B03a" (value>3 ? 0x7f : 0x00)
x"B03b" (value>4 ? 0x7f : 0x00)
x"B03c" (value>5 ? 0x7f : 0x00)
x"B03d" (value>6 ? 0x7f : 0x00)
x"B03e" (value>7 ? 0x7f : 0x00)
x"B03f" (value>8 ? 0x7f : 0x00)
x"B040" (value>9 ? 0x7f : 0x00)
x"B041" (value>10 ? 0x7f : 0x00)
x"B042" (value>11 ? 0x7f : 0x00)
x"B043" (value>12 ? 0x7f : 0x00)
x"B044" (value>13 ? 0x7f : 0x00)
x"B045" (value>14 ? 0x7f : 0x00)
x"B046" (value>15 ? 0x7f : 0x00)
x"B047" (value>16 ? 0x7f : 0x00)
x"B048" (value>17 ? 0x7f : 0x00)
x"B049" (value>18 ? 0x7f : 0x00)
x"B04a" (value>19 ? 0x7f : 0x00)
x"B04b" (value>20 ? 0x7f : 0x00)
x"B04c" (value>21 ? 0x7f : 0x00)
x"B04d" (value>22 ? 0x7f : 0x00)
x"B04e" (value>23 ? 0x7f : 0x00)
x"B04f" (value>24 ? 0x7f : 0x00)
Note that the binding’s “Fire” condition is set to “When Result Changes”. This is important to avoid sending spurious meter-change bytes when the bound parameter hardly changes.
Here’s a video of the result:
Sorry for such a long post! (It took a while to gather and document all this info.) Hopefully it will help someone.
–Kevin