Tuesday, January 29, 2008

monomuino: an Arduino-based monome compatible


I believe this is the first monome-compatible based on an Arduino (and possibly the first monome-compatible device, period). I call it the monomuino. I considered calling it a minimonome, since it is only 4x4, but I wanted to get some Arduino reference in there; as much fun as minimonomuino is to say, it's a bit of a mouthful. If I make a larger version, maybe I'll rename it. I'm pleased that, like the name of the original, there is a minimalist mathematical inspiration behind the term.


In an earlier post I presented a project that used the monome form-factor with the RGB colour blending in each button. That project, however, didn't communicate with a host computer, and had all of its software on the Arduino. This device uses the monome256 protocol to interact with MonomeSerial. The video above shows it pretending to be (one quadrant of) a monome sixty-four, interacting with several of the MaxMSP patches from the monome base collection. (Apologies as always for the lousy video quality!)

For information on how it works, read on.

This project does not use the full RGB capabilities of my earlier button pad, because the monome protocol doesn't support it. Instead, I've connected the blue channels directly to the Arduino in a standard 4x4 multiplex arrangement, and the buttons as before. This uses essentially all of the pins on the Arduino to power just a 4x4 grid, so it obviously can't scale directly; I do believe, however, that with a couple of inexpensive chips added to it, I could scale up to an 8x8 or possibly higher.

The trickiest part of this project was getting MonomeSerial on OS X to recognize the Arduino as a monome (note that all of this information applies only on OS X; your mileage may vary on other systems). From what I can tell, MonomeSerial looks for a device named tty.usbserial-m40h-xxx, tty.usbserial-m64-xxxx, tty.usbserial-m128-xxx, or tty.usbserial-m256-xxx, where the first part indicates the device, and the x's are a (presumably unique) serial number. I tried making links to the Arduino device with the correct name format, but that didn't work; looking over the source for MonomeSerial, it appears to look for an event from the Kernel. I tried figuring out how to change the source to recognize other device names, but my C++ skills aren't up to snuff. So, I realize I had to change the serial number of my Arduino (or, more specifically, the serial number of the FT232 chip in my Arduino). If there's an easier way to do this, I'd love to hear about it in the comments!

To do this requires programming the chip's EEPROM. (Obligatory WARNING: if you kill your Arduino trying this, it's not my fault!) I found some Linux programs to do this (Google for FTDI EEPROM for others), but couldn't get any to compile on OS X, so, despite my distate for it, I grudgingly went to a Windows box. FTDI offers a utility called MProg for programming EEPROMs. Note that it requires the D2XX drivers, which I gather aren't the "normal" drivers that you already have installed if you're using an Arduino. MProg has one of those terribly unintuitive user-interfaces that only an extremely niche product can get away with (or maybe that's par for the course on Windows), but it got the job done. Soon enough, my Arduino was renamed tty.usbserial-m64-0001, and was recognized by MonomeSerial.

After that, implementation of the monome256 protocol was pretty straightforward. The only annoying part was figuring out what speed the serial connection was set to: I couldn't find it documented anywhere, so it was simply a matter of guessing and checking until something worked. I assumed it would be pretty fast, so I started at 115200 baud and worked my way down; since it turns out to be 9600 baud, it was a bit of an exercise in frustration. After seeing how frustrated it can be working with an extremely well-documented protocol, I have renewed respect for any hardware hackers who do real reverse-engineering! There were also some timing issues with my serial implementation, which were easily resolved by making sure I wasn't calling Serial.available() too often (not entirely sure why it was a problem, but it did the trick), and timing problems in the other direction, making sure I wasn't dropping any received commands.

So what's next? I see two obvious directions: one is to see if I can get an 8x8 pad running off the Arduino. As I said above, I'm fairly certain I can, but it would cost me another ~$100 or so in parts if I got them off the shelf, and I don't think I'm willing to invest that much in it. I'd much rather pursue my improved design for the RGB button pad. That requires designing my own PCB, which I've never done before, so it holds a lot more interest for me. The problem is that a 4x4 button pad PCB is larger than the free version of Eagle allows, and I haven't been able to get KiCad running satisfactorily on OS X (if anyone can help with that, it would be greatly appreciated!). The beta for version 5 of Eagle is a pretty huge improvement on OS X, though, so I might be willing to shell out once that's released.

Thanks to the great folks over at monome for making their hardware and software so open! Congratulations, too, on the amazing success of their most recent offering; these products are hard to get than Hannah Montana tickets!

As always, questions and comments are welcome and encouraged.

3 comments:

mukelarvin said...

Rad.

I also bought an Arduino a little while back with the intention of learning about microcontrollers.

But a combination of busyness, laziness and mostly just forgetting I had one, my progress has been set back repeatedly.

Thanks for reminding me that I'm a total slacker. It's awesome to see the sorts of things people are coming up with.

Henri Vilminko said...

I was taking a look at your site to see if you have any updates on your RGB button board but this is interesting news too! :) I guess Monome compatibility opens up all kinds of cool opportunities as there's loads of software already available for it. Don't know how well the they work using just a 4x4 board though...

I ordered the same 4x4 button board from SparkFun and I'm eager to start experimenting with it... My original idea was to hack together a simple OSC client for Arduino and use serialosc2udp or similar tool to communicate to some OSC-aware software package. There are a some older implementations for avr but I'm not sure if I want to use them or just try and code a minimal client (and receiver?) myself.

Controlling the RGB board still remains an open issue for me. I'm a bit surprised that there aren't that many examples of driving an RGB matrix so I guess I need to try either your solution with the potentiometers or the one SparkFun describes in their Tetris board documentation. Please keep us informed in case you come up with a ground-breaking approach. :)

Anonymous said...

Wow! That's some great work. I have to order a Sparkfun button pad now ...