monome part mono

May 12, 2015

I got a monome kind of recently. It looks like this:

Alt text

It is a beautiful thing, impeccably constructed and lacking in any branding or other such disfigurement. As for what it is… functionally, well, it’s an instrument, basically… often used with programs like Max Msp or Ableton live to make bleeps and bloops and sounds and etc. But, more basically, it’s a completely open source grid controller. The buttons can light up, too, but their leds are decoupled by design from the buttons, and they depend completely on the application being run. Like this one, or this one, or this one… Likewise, any sound you might hear is generated by the program that the grid is controlling- it contains no samples and produces no sounds on its own; you can’t just plug it into an amp or anything like that.

I’m never going to know less about this piece of equipment than I do right now, so it’s a great (and maybe my only) opportunity to try to reverse engineer the protocol.

Special thanks to my coworker Fred, who I totally nerd sniped into helping me computer at this thing.

I know from working with arduinos recently that a serial device will appear in the /dev/ directory as a normal looking file that can be read from and written to using standard utilities like cat and >. And indeed, when I plug the monome in, a new file appears there called tty.usbserial-m1000065.

So I cat /dev/tty.usbserial-m1000065 and just start mashing buttons, and this is what I get:

!!!!
    !!!!   !

       !
          !
              !  !


                            ! !!
                            !!!!!!

                                 ! !      !

Look at all that junk!

This tells me two things:

Next, I write some of this output to a file. I run

$ cat /dev/tty.usbserial-m1000065 > afilename

and press the top left button one time. Nothing comes out for reasons I might figure out later, but when I close the connection and cat the resulting file, it looks like this:

!

Next, I used the xxd utility to view this data as a hex dump (xxd is super awesome and useful, by the way, if you didn’t know about it!) …

$ cat afilename | xxd

0000000: 2100 0020 0000                           !.. ..

The contents of the file have been made into:

2100 0020 0000

Each digit represents one of 16 values, which is 4 bits. Each two digit pair, then, is a single byte. From one button press, then, I’ve gotten six bytes:

21 00 00 20 00 00

This might be a good time to point out that 21 is the hex code for the ascii char !.

Just out of curiosity, let’s see the -b flag on xxd, which outputs binary instead of hex.

00100001 00000000 00000000 00100000 00000000 00000000

Let me try the same thing again, but this time I will press the second button once instead of the first. This outputs the following:

21 01 00 20 01 00

So… a lot of that is the same. What’s happening?

Each button event on the device sends three bytes: a signal byte (21 for a press and 20 for a release), and two address bytes that correspond to the coordinate of the button the signal belongs to. I press the button once, and I get six bytes… three for the press and three for the release. Let’s see what a hex dump looks like if I press the buttons sequentially across the top row:

0000000: 2100 0020 0000 2101 0020 0100 2102 0020  !.. ..!.. ..!..
0000010: 0200 2103 0020 0300 2104 0020 0400 2105  ..!.. ..!.. ..!.
0000020: 0020 0500 2106 0020 0600 2107 0020 0700  . ..!.. ..!.. ..
0000030: 2108 0020 0800 2109 0020 0900 210a 0020  !.. ..!.. ..!..
0000040: 0a00 210b 0020 0b00 210c 0020 0c00 210d  ..!.. ..!.. ..!.
0000050: 0020 0d00 210e 0020 0e00 210f 0020 0f00  . ..!..!.. .....

It’s tough to parse this, visually, but if you look close at the groupings of threes, you can really see the pattern:

21 0000 20 0000
21 0100 20 0100
21 0200 20 0200
21 0300 20 0300
21 0400 20 0400
21 0500 20 0500
21 0600 20 0600
21 0700 20 0700
21 0800 20 0800
21 0900 20 0900
21 0a00 20 0a00
21 0b00 20 0b00
21 0c00 20 0c00
21 0d00 20 0d00
21 0e00 20 0e00
21 0f00 20 0f00

You can see how the “x coordinate” is increasing as I move left along the top row, and you can probably guess that the second row will start with 0001, and so on.