Hacking the Roli Lumi
The Lumi by Roli is a small keyboard controller with LED feedback. The Lumi is a product designed to teach you how to play piano by lighting up what keys to play. To take full advantage of the Lumi experience, customers are encouraged to sign up to a ongoing subscription service of lesson content.
I’m not interested in using this product for the purpose it is designed for, but I feel there is a lot of potential for controllers with LED feedback. I purchased the Lumi so i could use it for applications such as displaying a histogram of pitches, to control transposition of a polyphonic granular process or to visualize and edit a set of pitches used by a procedural generation process.
The first hurdle is overcoming Roli’s lack of documentation. There was a time when ever manufacturer of MIDI gear had to include a standardized MIDI implementation chart. While the MMA still strongly recommends this practice, it appears to be optional. I was spared the hassle of reverse engineering the protocol after a bit of research that uncovered the Lumi’s system exclusive implementation here at this github link.
Unfortunately, the Lumi’s usefulness for my desired applications is hindered by a few technical issues.
The Lumi does not support a fully-decoupled LED mode. While it is possible to light up a key with a MIDI message, the onboard ‘local’ LED triggering will also light up a key whenever a key is pressed. There is no way to defeat this that I have found. There are four prominent color modes to choose from the Lumi software, but none support fully decoupled operation like the way a monome works. A monome controller is a simple device. It sends a message to a computer when a button is pressed, and it lights up an LED when the computer sends a message to the device. These operations are entirely decoupled. This allows for any kind of LED interaction to be programmed: momentary, toggles, radio groups, faders, etc…
The Lumi can be ‘tricked’ into this operation by instantly sending a LED off message as soon as a note on message is detected. The downside to this is it can cause flickering because the entire state of ‘lit’ LEDs has to be sent to the device on any state change. In other words, when a key is pressed, the LED has to be turned off, and then the lit state of the device has to be restored.
The Lumi has a pair of shift keys that shift the range of the keyboard in octaves. While this will adjust what MIDI notes are sent from the keyboard, the shift keys themselves do not send a message, making it impossible for software to track what octave the controller is displaying.
The four color modes define the overall color LED behavior of the Lumi (the color mode defines what colors are used when pressed or not pressed), but lighting a key up with a MIDI message is processed through whatever the current mode is. Due to this implementation, even though the LEDs are RGB, a MIDI message has no control over what actual color is displayed, this is determined by the mode. This means using color to display data such as a pitch histogram or intensity is not possible.
The Roli Lumi is a truly promising controller and I can’t legitimately fault it for not doing things it wasn’t designed to do, but the lack of a truly decoupled LED mode, limited implementation of LED feedback over MIDI and inability to communicate keyboard register unfortunately limit the possibilities for musical applications outside of Roli’s walled garden. This is a shame because the Lumi has a lot going for it as a controller, with polyphonic pressure and a bezel-less physical design with 24 keys that allows you to create extended controllers simply by adding more Lumi units (brilliant!). I wish that Roli were more sympathetic to the hacker community and a good first step would be to acknowledge that their product has utility beyond the piano lesson model they are laser-focused on.
Here is the Max patcher I use for controlling Lumi’s LEDs. The Lumi must be in Mode 4 for this to work correctly.
<pre><code>
— — — — — begin_max5_patcher — — — — —
3677.3oc6cs0aaakD9Y6eEDB6iNBm6WVf9PS61rKpSaPSJJVztHfRhwgITjB
TTN1on829dtPQqKTGdn0QRNAxOXQKIxY9lYNyLmYFR+mWdwfQE2kLePz+L52
it3h+7xKtv7V523h5+9hASiuabV7byWaPdxmJF8gAWY+npj6pLucUzjESmE8
L3xOoXQUVRU08yRrW8A5OevUQCRyUmw+q9aMKtZ76Syu4skIiqreQgXH3pHB
ipeAxY5WPngflyIchghJt3YzkTKewzzbE8L7H7g2zxEl2Eoey+5xK0+5JOA6
zj4yiuIYKz5.lNwFBRzvgCXCo.0OHIBvPbpjbUDE3Bo3VQJpUjBeDHcGp0Om
EcSYwhY6FtW0Ej4bMtXTQKPF5Bxvd.YT3fbVQ7jQw42rSHa9PWPFhACIHLfQ
.TLfJXHEV4BrFrTgKHSHjdXQCCnE8eL35e8k+mneL494QO+5e969w+XviyDW
CdEBE1WfHfa7ROM106uRlw1VGCo9nhweoqhYFexLjWJXzoQAWEkEk838ZwLN
sfBazGtXHCSXPNlJHpWQvciXD4.GSZG.dQ9r3weLJMJcmnVG40i.vVriPV+1
NcQiPeoCVLh0lt0fcpzI1gmFr2Ix8XsKDysIY4DffSyR24IYQP2Nl6Z4acNj
HwPgfvP.IfHQHhfdUDl3LmCB9.m0QUwM2jk3zrsajgUISHYPJEBf.FPv3XEl
rHirKj03XZVbY7zjpjx2ljGOJyPZvgMlj5JLJozo+3Ni3VCcHvpToDIgH.PL
tqbmgOjkwdB8.tL9a9lHv9ZEPnlbpgPDipxyVvThBL1snfcZVTOpnL9NebV2
6W7HTFSNT6hmoVqvUNAD.oxEHnCAEuUAEtUAk7oh6cqgAUmbp18.korNXLrN
nlam8Ph7zXXLtHKK58IYSxKpRl6Nisq7HysZI.BNTI.vbAhATA0IBgVk61MA
EziH5j52cd7sISdq57UbvaiqpJSGsnxVRkKZjDWLHQ4+axJdaT7thmSmmVjq
eWl4MMRzmnx0VSThvoCgJwrTvAJOQTFgo15GxsTF9UjTt5fkCZqw4D8XiHP5
IJ478JxFVxFp7WivDNjIzIsg1Q5NcDnidhpX194+t8UYskGa+LEHec3bucqi
1RCpKmPzuhbBEfhYA4aaMUW8C2kyBR4mnxY8OfNby3FsTZKqcjTSFCBAhSfR
jP6C1oQDlefWTortpT1LgUqhTvQgRhtF7B.if3ctyQp3TtywcTAnOmFAQBGl
.KKTvxW6buBsJsXXiqWHWJHHIQHUuIk6zrnOAdvOc8015pDLQkUBfyjbBmHo
LJD0kuVL5qHWsyUbxLs.9vT2w11nZGUgTdZ5RlVFjl2iMz6QQIAPytVwZCLB
.voJWSbmY4g6ydIvGh5O6W1+d216V6LrsU36NBr7.KDbDAlQhf6SkJZssvDm
V7P1gttztw6iLoCHg7HAL+DUxtR0kMIxYVV9WPFFPtMtgX2C..C1iZvEvk2S
SmjptxC5BTBA0ruTBPJ4.j.SM0DwMl5S3PP3vzcZO1q.pGYMm4jVbPI3Ckq7
iPvbI.ZO+HRmlylq1frz7MGXICype+0kJyKVTNdI5VtPJ5AlZRx7pz73p5jE
98Ubmp+VsJ58kTpsWpV43lRX62YuoS2HBD.DYFUitok17N.zh3AsZ3n8jVXu
nUXvExCZoSpYuIkdyocSoP.J89chPcQIdHnDzCLg.ghRPenz9t.FI8ZEbHTT
HeVTgBFk5T7EBybjOKnL8xKLjB5Eo1aiBuLzCQbJjWF5xPfIfOXhD.LYxv3H
EoxjhZmBvkIdD.R0MrVWNWTNIob2aLHvDesuiJK5YEprJqyVSxGRU6CPkdLk
xYR.UpxeD.H55dHX63y1FGf8DGfiVNfMWkNTX3fQKnWzBFDZg7hVn8lVBexi
ILhPtWlFhfPK+RbOL3h3EsfAgVd45kRBhYnWAjozffKj23Z+okWtnHxfQKnW
zBFDZg2mPHPtvDm.f2d3dVFCY6Oae4ahetwCx5GS5ic5ZMHa70LJfdXmEDaZ
+Jd.IH4I4UwCfjf3a0qhGDDskOgA2ZUpsjYwylcaR4xlhYHwfowenvjOk3Jy
ella+SScHGTlbaSSzfldqMHtb76SqRFWsnLwVPQlcnRFLsPkZV9hz5rLUnSQ
y4U2msYc5ximZO0ucwjzhWWEWsX9aeYR9BaAAUn5cwKxpVWRL5l2klkMtHyx
eq18ukEubf8SW1Bvlu6uGAFhjDHT4d.LDCwbDybj5.JcE+d0mCb4IQnDI.o+
p51jSnliDHLEqOBrwogdfV.nzRAfT.H1iTukdXJV8zhyuw16bDWOQhMstrXV
Q4Rcp5TkMe+EUE2TFOIMIupIG3l9ZdUsgTo5SMhciLoVlNUIPSWdNqZ3stxX
Z5c6qRngAaWlh4pz6gFQhffgFgCYC4xiTbtgBOvJgPJq+dqvM5kjqcIteWQd
0xyQs19aKSiyhddQ1jMJPu1ug2fGLTPaNcMElm94ZJ.MBlPivnWUn6vP5SJj
BNDHc4spp+XbvZ726hW5q+gTwNuj6xilsZ7cbeLVOqRBiWvqWLNtGKX94YI4
QuNNedzqSllNZMmCqAZBmBwlf0HIVHsGQg.lbMPquAyT4wn.2ZmMGo9hlLEf
LNxFoW..v0UOlFpZNu2llqypJoQjikHHyRykoOf3Zs75WfQ2rFYk.BjKMNsj
TBmaNhfjbC6SYAvgviyTpwlUzjCjdJ+EB6QaArMMbYTfUbxz+vsGYuRGjjgp
ESwiGq9f0vMVqPLfkrjmzY.R1vrPYULcySkKTrtE6.nPXORcUPn5yMHKHzAK
g.abuNVWzVnh1iPBtZsegNBgDU3.VOsH6wE4UQ0Nl26qTbU0iQdd3jOw2EAQ
Q+RxMKxhKGDzql6bPNG55xCfF7YvFod.uhm0jmFM4gRadVidB0nnyR9Shj+r
b+zH2wmk6mD4NI3QNNuB5TnIQGfb.PM5xvcMwA+JRNauczs2NuF+3KyOGg73
KyCczQx4cTcJzhm8WcBj5zyx7itLmEB+U+PQYz0o2l3R+sila6nURfgL8jrf
CTIoeSRr4F8y+5jC1UcxEczKELmJD19vnevSX5HDlgABRH6kxaJiymaO6dzi
weYwnzOti1J5tCcbR2sFbsVw3nWftGpALcMJ8gEyqReW53UlBL3ouYg6vaxp
beebmnr14GrVE1nu5aKb2vve06z0VZ+nuW01VyrskSPVj7au4G5whi+88SJK
tII+MFKmVWi.0CWmsi0BfBulUFKGytcavCY3ZGAPNgIk0GAjadVmJqYu5b7I
eN.cOoTlvEFIKBRYV3n6iuQII8wadKF0T8ynCicIihgVUn55i7nm5DFDBryT
oDYdhAptbRnfKBoId7vOlzmoxJeRbVRzKKxKFzwfhHY.tvfc8iJJpwKkRvZd
ri4vV2u4gXmAaaW45hWVU49HlJhfnELOVBRG2CEwKRxStMdWS3iT6c4pVOxq
gzw2HwBrjaGzErTRf0Gwo396XpkgSF1OxDl7uEMgg19n.LkddLDJ6NDpzsyl
NU6gzV84q7TWqcK1U3MnEbhFMBn9nfyVeudpQepwTuHNM+u8jqLo8WmZv1GE
dVa9mRUVjtXtsrzf0VoO7qCBOgdRwT+37rzIKe1r6ms0Fbiynk95xdCGv6zw
QqYTbL8Obcxj9sNzWTvNL45Wy1uLtpL8twUkY6A2GTFR+bj7ucWbq9493ohE
xOULY4CfQO7J5YbYGQLO8.tWtP.GXCqeZk+WSzNyzlmpsCZd.XsWkNtpaY0I
We9pxj4IUO4x130iKlk3e5FObu6Iw5e5Nq+ipP9Mwi7GJdFDsMKmN8uDTPo1
30ndm.c64SzxFANrNNdyJ+q4IDoy5rV36nLoAFR+5zNt8ZOhIZ9aw2l7thxo
+cvkv8OySvPZf.2j3xO9r7zade0yLaA9b257oZAaU5cOuIi1QYFHMd13MUXu
oV6BiN2kaEIEUW8EpR5BpihEZ+9ok2tm2JrqyzDHjaXUVitBZpGXnqElmplu
ztA079zNJkoeiaWKoy6FocaJ2UUlChk7GLPHoD.16gk7gKEpOKNFkknxwvdW
g97hhUacaVRbouE5FDvZ45GY9hv6b6VnOXZs0A6dWpzfYxkl+QuSbfocDJZV
Lgq6RR24L3wI9H8Ntsc4C8L0PE7pGEflL3OjNh4Xbn6fuG5ucYbe0Z+tiMh3
AcZsDeNNsfrL4i1pK7a5GUOm5z9yzIE28lA2rJe.Io9V2WJwBd8QbgGa0k0j
yGswy6Ri4vgK6CX8mmsHw8Tn1VOWg754c3AVUdnXvxhOk2aN7XJB+t6i6OCB
PRpclA3bLFYmFKDT4LM7L3KJSRdDbnQ50TxIHSGhH7L2ujLo2rFuweNrIIE.
BSQxvye+2jrrhO08iFm0GjJpD.Dt77JPT63lvEPgIHk5bngM+10..5KQ.XJA
9KTadr+lHM6.lp1SM0NYOqFJOHL3r37jrt4u8L0GWXY0mHFal.Tmxfuld9uM
aQ4L2U8bmUPf2HKIlgNx3KV6sy8T+gAD.RZUA.lzHmPBJCEzA.qLYbR5staD
WaKOaxh+ALAB9NnKs4o8hNdhurdnYBiYqcoJdGudNjUNNjtm6riyB54I4Sl+
TKP4CBY2tY1Xbu4P.211HBCHqG2aNr6cEbjD0UidnvKO1RIdze12TEOqGr70
wUEQWq2.wffQ+4UIuaQVVU+5xiukYcyIaVPM+uQT4Yig4X63eyTNRBZW2VBp
iClPBd8fkhaVzhQRrT7TYqYUIyeZ8DeRG5LYRZUWN526hz6NUGlHP34S5BKb
eOVH+8okU2G8utoyopFnMIM66GWaIp.UceY7pcFdNe0sW9GnTBXh5X8j54Xf
A.163pcULdL6wYnXerLaZKpVTMeVsIo4+raW9WW9+AzPkEED
— — — — — -end_max5_patcher — — — — — -
</code></pre>
If you know a way around any the limitations I’ve outlined, please let me know!