Using Arduino and Pd for musical live performance
But sometimes Firmata is not the answer to every problem: You may want to turn on the built-in pull-up resistors for digital input pins, you may want to do some calculation on the Arduino before sending a message, or you may want to send a message from Arduino to Pd only on change.
In fact, I wanted to do all of the above, but not use Arduino for output. This led to the following electronics and code.
Connecting Inputs to Arduino
I have connected several push buttons to the Arduino, and one variable resistor. All push buttons are open an close on push. All connected devices:
- Three foot switches in a box.
- Three push buttons and a force-sensitive resistor mounted on a glove, worn on the right hand.
- A keypad consisting of 12 push buttons with a resistor matrix similar to this setup (in German). The main difference in my setup is the usage of values ten times as in the example, as the thin cables have a non-negligable resistance. This is mounted on my left forearm
The Arduino Shield
Message Passing between Arduino And Pd
I wanted to minimize the data sent from Arduino over USB to the host computer. I came up with the following "protocol", that uses 1 byte for a digital value and 2 bytes for analog values.
- Digital message
- Analog message
p denotes bits used for encoding the pin number,
v bits used for values.
As the Arduino Duemilanove - the one that I use - has 14 digital pins, 4 bits (0-15) are necessary to encode the values, 6 analog ins can be encoded in 3 bits (0-7). Digital pins only read 0 or 1, so only one bit is needed for encoding the value, analog pins read values 0-1023, which corresponds to 10 bits.
If a byte starts with a value of 11, then this byte and the following one starting with 0 together are an analog message. If a byte starts with 100, then the message is a digital message.
On Pd's side, messages are parsed and then output in the same way as
[pduino] does it:
(a|d) [pin number] [value]. That design allows you use it as a drop in replacement.
I first tried to parse messages with bit shifting and
[expr], but that was too CPU intensitive, so I have created my own external in C. That external does the bit shifting and then outputs messages as lists.
I am using the setup mostly for live performances, and the demo patch included in the source code is the actual patch that I use. It also makes heavy use of my abstractions.
A demo video will follow soon.