Synthdriver is a wireless music instrument and MIDI controller. The orientation and movement of the synthdriver in space is sensed by an accelerometer and gyroscope to provide 3-axis of command control output that can be mapped to any MIDI device parameter. A membrane potentiometer is used to trigger notes along a single octave, while a second potentiometer is used to control stereo pan. The components are mounted in the detached steering wheel of a 1991 Chevy Trailblazer and powered by 4xAA batteries. Wireless communication is facilitated via Bluetooth.
- 6DOF Digital IMU ADXL345/ITG3200
- 2x SoftPot Membrane Potentionmeters
- BlueSMIRF Bluetooth Module
- 4AA Battery Pack
- Some hookup wire and resistors
- Acrylic, screws, and nuts, for mounting
- Steering Wheel
The components are mounted on laser-cut acrylic. If you try to replicate this project, you very likely wont have access to your very own ’91 Trailblazer steering wheel, so I haven’t posted vector files for the laser. Some general tips to keep in mind while mounting hardware:
- Choose a steering wheel with an airbag slot (without the airbag; please be careful removing an airbag from a steering wheel as they can cause injury if triggered).
- The mounting panel was secured by using 2″ through-hole machine screws that secured into a second piece of acrylic mounted on the rear of the steering wheel. Other strategies for securing the mounting panel include glue (probably not recommended), or tapping into existing screw holes in the airbag mount.
- The SoftPots come mounted on clear plastic with single side adhesive. They hold really tight. I’d suggest cleaning any surface on which you are about to place adhesive with rubbing alcohol and a cloth to remove dirt.
- Arduino and the IMU use standard metric M3 screws which require holes of ~3.2mm diameter.
- The battery pack attaches via double-sided tape, and is fairly secure.
- I used a protoshield mounted to the Arduino to preserve space and to make wiring easier. You may find that you need a larger breadboard if your design is more complex.
- The protoshield I used has a plug-and-play slot that accepts the bluetooth module. It made connecting the bluetooth module very easy.
Wiring it all together is fairly straightforward. Please see the diagram below. Some things to keep in mind:
- DON’T CONNECT THE IMU TO THE 5V RAIL.
- The IMU has SDA, SCL, and Interrupt connections (also 3.3V and ground). SDA and SCL are the two-wire connections required for I2C protocol serial communications which the digital IMU uses to communicate with the Arduino. I didn’t use the interrupts, but you can program the IMU to send events to the interrupt pins when it detects certain events such as free-fall, tap, or double-tap.
- SDA (Serial Data) goes to analog 4.
- SCL (Serial Clock) goes to analog 5.
- The SoftPots are analog sensors so they are wired to analog pins.
Download the Arduino source code for synthdriver.
Working with a digital IMU means only using 2 wires for communication with the Arduino. A 3-axis accelerometer and gyroscope using analog communications would require 6 analog connections at minimum. This means that the digital IMU makes for a smaller footprint and cleaner wiring, however it also requires a different approach to programming.
2-wire digital communication is handled through a protocol called I2C which is widely used in the world of microcontrollers. In Arduino, we use a library called Wire to help us send and receive data from the IMU. Whenever we want to grab a value from the IMU, we send it a byte-register representing the address in memory of the value that we’re after. Then we wait while we receive the data we requested. One of the benefits of this model is that we can configure how the IMU operates on the fly by writing values to the memory of the unit. This is done in a similar way through sending values to the correct register address. For more information about I2C check out the Wire library. Don’t forget to read the datasheets (ACCEL/GYRO) to understand the role of the individual byte registers, the correct device addresses, and the units and multipliers for the values you receive from the IMU.
Reading and interpreting the accelerometer
(I’ve glossed over a lot of the math in this section and the gyro section as well. Please read the formulas in the source code and let me know if you have further questions. I’m not incredible strong in math.)
The goal of getting the accelerometer values is to determine the tilt of the device with respect to the ground (the force of gravity). To accomplish this, we need to measure along the the two axis that are usually parallel to the earth’s surface while holding the wheel. When the wheel is turned and tilted, the values change from (assuming no gain from the force of turning) 9.8 to 0 to -9.8 and back. By using the atan2 function we can use some trigonometry to figure out a particular axis’ angle to the ground in radians, and then finally convert that value into degrees. We can then map the degrees (-90 to 90) based on a turning radius of 180 (this means we are only concerned about turns and tilts that go half way around) onto a 7bit range of 0 to 127. Now we have 2 axis output as values of 0-127 that can give to our MIDI commands.
Reading and interpreting the gryoscope
Upon beginning the task of interpreting the gyro readings, I had believed that I’d have to integrate the angular acceleration of the gyro turns. However, upon inspection, the values the gyro returns are angular velocity. This makes the math much simpler by taking the sample rate (125 times per second) and then grabbing the velocity at the sampling interval (on average every 8ms). You can then divide the velocity by the sample rate, then by the analog multiplier to determine the distance you have traveled along the curve.
Working with MIDI
Working with MIDI is surprisingly easy. Each midi command is a set of 3 bytes. The first byte determining the message that the command is to send. A value of 176 indicates that it’s a “Control Code” that will manipulate DAW parameters, while 144 means that we’re sending a NoteOn command via the primary MIDI channel. The second byte usually indicates the control parameter or the note to trigger. And, the third is typically a 7bit value indicating the parameter value or the note velocity. There are a lot of other MIDI command paradigms that exist in the MIDI Specification, but these are the only ones we’ll need for this project.
Bluetooth wireless with the Bluesmirf module for Arduino is surprisingly simple. When paired with your computer, it shows as a bluetooth serial device, and information is sent to a COM port the same way it would be sent through a USB cable. The magic occurs incoming serial MIDI data into MIDI commands that are read by our audio software. To accomplish this, I used a simple app called S2MIDI and an internal loopback MIDI driver called LoopBe1. S2MIDI converts the incoming serial data to MIDI commands and sends it to the MIDI-in of the internal driver. The LoopBe driver takes the incoming data and sends it to its outgoing port. The DAW picks up the MIDI commands being sent out from the internal driver as if it were a normal hardware MIDI device.
For the purpose of this demo, I used a popular digital audio sequencer and composing workstation called Ableton Live. One of the many virtual instruments available through this suite is a 4-oscillator analog synthesizer called “Operator.” Using the MIDI mappings command (Ctrl+M) you can click on any parameter of Operator, send a single MIDI command and have the command be bound to that parameter. For the demo video, I bound controls to a band filter frequence and resonance, as well as the rate of a chorus effect that I chained to to the synthesizer. I also used one of the potentiometers to control the stereo pan. The other potentiometer engaged the notes in a 7-note octave (C,D,E,F,G,A,B) whenever pressure was applied along the SoftPot.