When I left off from Part 1, I had plugged the Teensy into the computer and loaded the flash program to make sure it works. The next phase involves loading Firmata onto the Teensy, and getting some sensor input into MaxMSP. Note that Firmata and MaxMSP are just two of many software possibilities. Other programs that are great for doing stuff with sensors include the free open-source PureData, and Processing applications.
To load Firmata onto Teensy, download and install the Teensy loader if you haven't already done so. Then, pick up the special Teensy version of Firmata from here. Follow the instructions for loading Firmata onto the Teensy and you're good to go.
For my first sensor I'm going with the pressure sensitive resistance pad. When you press on it, the resistance goes up! I have soldered it to the end of a 3.5mm male cable. One lead of the pressure pad is connected to the ground wire of the 3.5mm cable, and one to the positive wire (tip). You can ignore polarity for the pressure pad. This diagram shows the circuit (Teensy on the left, audio breakout on the right, pressure pad assembly is not shown - it's plugged into the breakout):
- +5V to TIP
- GND to GND (10k ohm resistor)
- A0 (38) to GND
If you omit the +5V line all you'll get is noise. When I load the Max patcher and press the pressure pad, I can get a good signal. Woo-hoo! This could be set up to go to a pitch bender, bit crusher, purple spotlight, vacuum cleaner, or whatever. You can alter the response of the pressure sensor by placing other thin materials on top of it (if you're building it into something you will probably do this anyway). My feeling was that it tends to dampen the response a bit. This is good since at light pressure the reading is a bit jittery. Also you can play with the resistance on the +5V to change the high limit. 120k ohms worked for me but your mileage may vary. If you are building this into something a trimmer resistor might not be a bad idea here.
And the code:
If you like making Arduino talk to MaxMSP, there are few things as nice and simple as Maxuino. A while back I wrote about using Maxuino and Firmata, and included my own patch which I unfortunately named "Maxuino simplified". Looking at it now, it doesn't really simplify anything! It did help me with understanding how to use Maxuino, but that's about it. As I bust out my Arduino once again, I have done a bit of work to actually simplify using Maxuino in my patches (see the bottom of this post for the MaxMSP code). I encapsulated Maxuino into a patcher that you can load into a bpatcher object. The inlet accepts OSC messages to Maxuino, the output spits out messages from Maxuino. From the panel you can select a COM port and activate the Maxuino example GUIs since they do come in handy. Here is an action shot:
Another thing I do is use a coll to initialize my pin modes. Put your pin mode settings into the coll using this format:
1, /0/mode 1;
2, /38/mode 2;
3, /39/mode 2;
Connect the coll to the inlet of the Maxuino bpatcher and send a dump message to the coll.
Here is the MaxMSP code (copy to clipboard, open Max, select File, Open from clipboard). Be sure to install Maxuino into your Max search path.
If you like the idea of controlling music and other stuff using sensors, then you will probably love the Oplab from Teenage Engineering. It's a really smart, inspiring piece of kit which takes physical input (taps, gestures, pressure, shaking, etc.) and outputs the resulting signals in USB, MIDI, and even control voltage, which you can plug in to your favorite electronic instrument or software. I love the idea of Oplab, but I can't justify spending $300 on it. I figure I can create a microcontroller-based sensor-oriented I/O system with an eye toward modularity, expandability, and ease of use. I'm thinking that once the initial work is complete, it should be something I can just reach for and use with a minimal amount of fiddling around.
For a microcontroller, I chose the Teensy++ over Arduino. It's also AVR-based, it's got more pins, it's native USB/HID/MIDI, it's smaller (fits on a breadboard) and it's cheaper. You can even program Teensy boards using the Arduino software if the C language isn't your thing. You can pick up a Teensy for a measly $16, $24 for the Teensy++. The regular Teensy actually has a few more analog ins than the Teensy++ so that's one thing to consider.
As for the sensors, I put together an assortment of items including a piezo disc for a percussion sensor, a pressure-sensitive resistor pad, an accelerometer, and an ambient light sensor. Those should be a good starting point. To make it modular, I am using standard 3.5mm audio connectors to connect the sensors. For cables I picked up some 3.5mm male to male connector cables (the kind you use to hook your iPod to a stereo). I'll cut those apart, and solder the sensors on, probably with some heat-shrink to make everything tidy. This approach will also transition nicely to an enclosure should that stage be reached. For now, everything takes place on a breadboard, which the Teensy++ plugs directly into. Since Teensy supports USB, you don't need to fuss with a power supply (of course it can run on batteries if needed).
What a nice collection of items! If only I had some sort of special container to store it all in, like maybe a tray or something.
In terms of software, my first choice is MaxMSP and the Maxuino library. Maxuino requires the Firmata library to work. I wrote about this a while back: Interfacing MaxMSP and Arduino. In a nutshell, you load Firmata onto your Teensy (or other Arduino-compatible). Maxuino communicates using the OSC protocol, and facilitates I/O from within MaxMSP. My initial step is to make sure Teensy works by following the instructions here. I got a blink, so far so good!!! Next step: get a sensor and send a signal into MaxMSP.
Today I received the first prototype enclosure kits, and they are quite awesome! The instrument feels quite solid. Here is a finished black anodized kit that contains a monome mk with some pretty blue LEDs.
Once we nail down the pricing we are going to do our first limited edition run. We're doing them in editions to keep manufacturing costs down (batch runs make sheet metal forming and anodizing much cheaper). In addition this will enable us to fulfill orders more rapidly.
Stay tuned for more details!!
Building the Bliptronome got me thinking about microcontrollers in general, and how cool they are. I've been teaching myself to program using an Arduino Duemilanove, and it's a blast. Inevitably I began to wonder how to communicate with Arduino using MaxMSP. The Arduino and the Bliptronome are similar in many respects. Each can use what is known as a serial proxy to communicate with host software. The serial proxy is device-specific, and functions to translate serial messages to and from the USB port to which the devices are connected. The Bliptronome and its cousins Monome and Arduinome can all use a purpose-specific serial proxy that makes it easy to write MaxMSP code for 'nomes. But how do you set things up quickly and easily for a standalone Arduino? You could write your own serial proxy, but who has time for that? Arduino kindly offers one on their site, but it only works to move data between serial port and a network connection, not USB. This is great for Flash users. But what about MaxMSP users, particularly those who want to get straight to I/O with a minimum of fuss?
Thankfully you don't have to reinvent the wheel, as there are a couple of brilliant free solutions that work very well together: Maxuino and Firmata. Firmata is a generic protocol that provides the foundation for MaxMSP (and many others) to communicate directly with Arduino. Maxuino is a collection of Max patches that uses the Max serial object to implement Open Sound Control (OSC). Together, they provide the magic of communicating with your Arduino by using OSC.
Get started by visiting Maxuino.org, and following the instructions. I won't duplicate any of that here, since it's fairly straightforward, although I will note that they have their own customized version of Firmata. Once you've got the files all nicely ensconced in your search path, and Firmata Standard is loaded on your Arduino, test it out to make sure it works (hit pin 13 with a digital out or something). Be sure that maxuino.help.maxpat is set to the correct port. If this is your first time, be warned that getting Max to talk to Arduino can be somewhat fiddly. If it doesn't work the first time, you can try hitting the reset button on the Arduino and then resetting to the correct port. If that doesn't work try unplugging and replugging the Arduino, and then resetting to the correct port.
Minimal Max Patch
I don't know about you, but after poking around in those patches I wanted to create my own patch for a fuller understanding of the bare minimum required to get things working. There is a lot going on in there! To be clear, so far all I want to do is send a signal to the Arduino to light up the default status LED on pin 13. Once that all-important task is done, I can be sure that communication is enabled, and attempt to send data back to Max. The first thing to address is setting the correct port number for the Arduino. I lifted the function straight out of maxuino.help.maxpat and plopped it into my patch:
That's a good start, but I still need to flash that LED. The example patchers in maxuino.help.maxpat demonstrate how to set pin modes and use the various outputs. I took the code on the far right side and added it to my patch. I connected the output of the prepend object to the first input of maxuino-gui.maxpat. Now it looks like this:
Now I should be able to click "update", set to the correct patch (in this example it's COM4), set the pin number for pin 13, and click the toggle to turn my LED on, and then turn it off! Again if this doesn't work the first time try resetting your Arduino and setting the port again. The message box at the bottom shows what the OSC message looks like. This will only work on a digital pin, as we're sending a digital out message.
Get Some Input
Although flicking an LED on and off can be hours of fun, it's only half the fun we could be having. What if we were to interpret a signal sent from a digital pin on the Arduino? That would be so awesome. The part of maxuino.help.maxpat that shows how to handle input is the Analog-Digital-Inputs patcher. In order for it to work though, the pin of choice on the Arduino must first be set to mode 0 for digital input. This is demonstrated in the Pin-Modes patcher. I went ahead and copied both of those, pasted them into my patch, and connected them as shown here:
NOW we're really ready for some hot Arduino on Max action! Connect one lead of a button to digital pin 7, and the other to ground. Now open the Analog-Digital-Inputs patcher, and watch what happens when you press the button. More hours of fun!!! At least three hours and 27 minutes by my last estimate.
The maxuino a subpatcher has a couple of gswitches that you can use to print out messages and see what they look like. Open the subpatcher, toggle the switches, and watch what happens when you press buttons in the maxuino-gui.maxpat interface. Set a digital pin to PWM and move the slider around. A handy way to monitor what's going on when you use the Maxuino patches. Of course you can also attach your own print objects wherever you like.
What's the most popular kind of input? Analog input! Well okay, I'm not sure if that's 100% true, but wouldn't it be fun to get a potentiometer wired up and watch it moving a slider around? I think so! First, wire up a potentiometer according to these instructions. Next, open the Pin-Modes subpatcher and set your analog pin of choice to mode 2 for Analog In (I selected pin 0). Finally, open the maxuino-gui subpatcher and turn on the pin of choice in the list of Analog pins. Now twist the pot, and you should see your slider moving around. For extra fun you can add a print object and watch the values come out. I connected mine to the output of the maxuino a subpatcher along with a gswitch.
As promised, Maxuino and Firmata together enable you to completely program the functionality of your Arduino from within MaxMSP. At this point you can add any type of functionality you want, from something as simple as connecting the button to the LED, to reading input from a sensor and adjusting a parameter on a synthesizer, to detecting input and dynamically generating user interface elements to match. You could write a patch to control a dancing monkey with LEDs for eyes. And all you need to do is use OSC to make calls to Maxuino from within MaxMSP. Pretty sweet!!
Obviously the excellent Maxuino patches serve well for instructional purposes, and I found it really helpful to break them down and simplify them to have a closer look at how (most of) it works. When I write an actual Max patch, I foresee a somewhat different design pattern. First of all, my code is going to be directed at an Arduino-based device that is hard-wired for a specific purpose. I think it would be easy to come up with a subpatcher to initialize the Arduino with the correct configuration at startup (loadbang), so that all of the pins are set to the right values, activated, etc. I'm still not sure if enabling/disabling pins has any effect on the performance of the unit. Obviously UI design is a consideration, and the Maxuino patches are a wonderful starting point for that. I think my design would probably still include judiciously placed Print objects, since I like to see values when I'm programming (who doesn't).
There are other issues as well, such as whether it is possible to have multiple instances of a Maxuino patch running at the same time. I did run into some behavior while writing this posting that suggested you can only have one instance open at a time. I'm not sure which steps to take to bypass this seeming limitation. Another issue is "how would this work in Max for Live?" and you will find that there is a Maxuino.amxd patch included. I intentionally did my experimentation in Max proper to avoid having to deal with any Live-specific issues, although I did run the .amxd and it worked fine.
Here is the source code for my humble little patch: maxuino-simplified. Copy it to your clipboard, and then use File/New From Clipboard to open it in Max. Note that none of this will work unless you have properly set up Maxuino on your system.