Sunday, January 23, 2011

MIDI to CV With Arduino Part 1

Source and Schematic to Change PWM Output to Corresponding Voltage
So, this is the beginnings of my modular synth. I have some keyboards around, but most all of the modular synths use Control Voltage inputs for notes. As I also have plenty of soft synths, I was looking to keep this project mostly analog. My first question was this: Can I use Arduino to help with the conversion from MIDI (digital) to Control Voltage?
So, I start my research in the forums. This project comes from the perspective of one who is not too familiar with analog electronics. So, I find 2 ways to accomplish this conversion.
  1. Digital to Analog IC
  2. Resistor-Capacitor Filter
Option number one was too simple. I don’t know that I would be learning much from plugging an IC into the board, reading the datasheet, and continuing. So, onto number two. Let’s make the RC Filter work.
The Resistor-Capacitor filter involved some calculations to find the right pairing. I would suggest research in:
  1. Passive Low-Pass Filters
  2. RC Time Constants
The intricacies of both concepts are far beyond the scope of this post. However, I can explain the gist of what we need to do.
The PWM (Pulse Width Modulation) that comes out of some of the Arduino’s pins is used in many microprocessors / microcontrollers as output. At first I thought this would be a limitation, but now see this as an advantage (that is, after I wrapped my head around the concept and discovered that I can easily convert this to an analog voltage when necessary).

This is what the output from the Arduino’s PWM pins will resemble. The trick that we are trying to pull is to make this wave form (square) into what would appear in an oscilloscope as a straight line – one constant voltage.
After trying many pairs of resistors and capacitors, I just could not get the waveform to lose the ripples. I could get it down to squares that Ymax  - Ymin  <  the original, but it still didn’t lose the square wave completely to make it totally linear.  I researched this some more and found that if I pushed the Arduino’s PWM pin(s) to run at a higher frequency, this would help solve my problems.
Enter the solution. You may want to reference the 8-bit AVR Instruction Set Reference to go beyond the comments in this sketch.
For references on changing the frequency of PWM pins, review this post:  http://usethearduino.blogspot.com/2008/11/changing-pwm-frequency-on-arduino.html
For more information on low-level programming on the Arduino, look at posts from this blog:
http://usethearduino.blogspot.com/
Here’s the code you can use. I will be using this as a base to extend a nice voltage output class for the project. For now, we can use this to test our design:
//Change to the pwm duty cycle you need (0-255)
int pwm = 127;

void setup()
{
// set pin 11 to low-impedance state
pinMode(11,OUTPUT);

// Set Frequency to 61.5 kHz.
TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
TCCR2B = _BV(CS20); 

//duty cycle defined at the top of code
OCR2A = pwm;
}
void loop()
{
OCR2A = pwm; 
}
So, now, after this we are left with a faster frequency coming out of pin 11. Couple this with some RC filter knowledge, schematic below, and you will have a nearly perfect analog output, from 0v to 5v, ready for the next step.

image

One can double an unused analog pin, make it read values, and input it into one of the many useful Arduino Oscilloscope applications to verify that your wave is correct.
Here is one I use most of the time:
Arduino -> Serial Scope

Enjoy!
Wes