Another MIDI to CV Box

40K6661

Intro: Another MIDI to CV Box

Another MIDI to CV box is a project I developed when a Korg MS10 knocked my door and took place in my studio. Being that my setup heavily relates on MIDI to automate and syncronize all the instruments, when I bought the MS10 the first problem I had to face was how to implement such control.

Korg MS20/10 are not the easiest synths to implement MIDI to: first of all, they rely on Hz/V control (linear correlation between the control voltage and note frequency), instead of oct/V (1V per octave); second, to trig a note you must send a negative gate signal and short the input to ground (S-Trig), not a +5 V signal (V-trig).

There are various commercial solutions to control such instruments nowadays (i.e. Arturia Beatstep Pro, Korg SQ-1, Kenton Solo) but I am a cheap bastard and even 100 euros are too much for a "not sounding" device :).

Here we are then: let me show you how to build a low budget MIDI to CV box to control/automate a pre-MIDI synth's pitch, gate, velocity and cutoff frequency with an external MIDI controller (Keyboard, DAW, sequencer or whatever).

"What about the new MS20 mini?"

As almost anyone know, the new MS20 is actually MIDI ready :IN with a 5 poles MIDI connector and IN/OUT with USB connector.

"So, if I have a MS20 mini this thing is useless!"

Well, no. MS20 mini recognize only note on/off messages and keyboard is not velocity sensitive. There's no way to overcome this with the MS10/20 vintage or mini keyboard, but with midi box and a velocity sensitive keyboard you are golden. In addition, with the MIDI box you can automate filter cutoff (or any other voltage controllable parameter) or have it modulated by the incoming MIDI note on velocity. Again, the only MIDI channel MS20 mini responds to is channel 1. With this box you can overcome this limit too.

"What if I have a Oct/V synth?"

No problem! The code I wrote is compatble with Oct/V synthesizers (untested, but I am confident that will work out-of-the-box ;)).

STEP 1: !! Note of Caution - Disclaimer !!

Your equipment is very valuable and should not be used to perform tests.

Toying with electricity can severely damage your equipment or harm yourself.

I cannot be held responsible for damages to your equipment/hardware or even yourself coming from any of the software or schemes or informations or links I reported in this instructable.

You have been warned!

STEP 2: Engineering the Hardware

Arduino comes handy when dealing with projects like this. The existence of a big Community and very good libraries that span almost every common task make it the right choice. Here the board will be programmed such that it will read incoming MIDI data and then will send appropriate voltages to drive:

- Pitch, by converting a pwm output into an analog voltage to drive the VCO via a digital to analog converter (DAC)

- Velocity,by filtering a pwm output to drive the VCA with a simple RC filter

- Filter Cutoff Frequency,by filtering a pwm output to drive the VCF with a simple RC filter

- Gate, directly from a digital out in case of V-trig (put a 1Kohm in series with the output to reduce the current drain) or by a simple pnp transistor switch out of the digital out (see schematic attached to the schematics step).

Arduino is not capable of outputting directly steady voltages, but 0/+5 V pulses with various periods (PWM). We are in the need for digital to analog converters (DAC) for the pourpouse. RC filters are the easiest DAC I can think of. A RC filter is good enought for the voltage controlled amplifier and filter (VCA and VCF). The RC filters are tailored to result in a cutoff frequency < 20Hz (lowest audible frequency).

I made some test with low capacity non polarized capacitors and I ended with a capacity value of 0.1uF to be the best fit. Tested good on a MS20 MKII.

Unfortunately, we can't rely on a RC filter to drive the voltage controlled oscillator (VCO) since it would be not accurate enought (in Hz/V scale, on the lower end two adiacend semitones differ for less than 0.02V; in V/oct two adiacent semitones differ for 0.083 V); we are going to use an IC DAC (MCP4725) for this.

Known Limits

Limiting the drive voltage to 5V (the Arduino output voltage), the full 0 to 5V range is covered for velocity; the cutoff is half covered (-5V to +5V); the VCO range is partially covered being that in Hz/V a voltage of 8 V would be required to reach the 440 Hz A4. With a 5V output limit we can pitch the oscillator up to the D4 frequency in Hz/V.

STEP 3: Components List

You are in the need for:

1X Arduino UNO (or nano)

1X MCP4725 DAC board

4X 1/8" or 1/4" mono connectors

1X MIDI connector

1X 6N138 optocoupler

1X 1N4148 diode

1X 220 ohm 1/4 W resistor

1X 470 ohm 1/4 W resistor

1X 10K ohm 1/4 W resistor

4X 1K ohm 1/4 W resistor

2X 0.1 uF capacitor

1X BC547 npn transistor (in case of S-trig)

1X ABS box (at least 55 x 70 x 100 mm)

... and obviously breadboard or perfboard, solder iron, solder wire and cables (2 meters of 28 AWG should be enought).

Notice that in the pictures above my prototype mounts 100 uF electrolitic caps, but they are too slow because of the capacity charge time. A capacitance of 0.1uF is the right choice.

I used a additional connector to supply power to my arduino; it's not necessary being possible to juice the microcontroller directly via the onboard mini USB connector.

STEP 4: Connections/Schematics

MIDI IN

The MIDI IN circuit is simple and well described on the net. Take THIS excellent instructable on MIDI and Arduino by Amanda Gassaei, for instance. I made the nth schematic on the matter anyway.

Notice that i added a switch in the MIDI IN scheme (switch 1): this is necessary when uploading a new sketch to Arduino because the opto interfere with the RX line even without incoming midi messages. You must open the switch before uploading your sketch or the IDE will fail to upload the new sketch.

You can eventually modify the sketch to use a serial software communication.

DAC, RC Filter, Synthesizer

Connection for DAC, RC filters and Synth (pitch, gate and velocity) are shown in the diagram on top. I took for reference a Korg MS20 patch panel, but I tested everything on a MS10 too. The direct connection of the velocity CV to VCA "initial gain" patch point has no effect (I must dig this thing further) but if you connect it to the "Total" patch point and rise your total external pots (MG/T.EXT), you will hear nice tone variations as a function of the note velocity.

My schematics (and my prototype too) do not use a current limiting resistor at the DAC output, but it's always a good idea to place one to ensure long life to your circuits. A 220 ohm resistor will be enought.

Notice that in the schematics above 100 uF electrolitic caps are reported, but they are too slow because of the capacity charge time. Non polarized, 0.1uF caps are the right choice.

Gate Out

In case you are going to sequence a synth compatible with V-Trig (voltage trigger) signals, a 1k ohm series resistor to reduce the current drain will be sufficient; in case of a S-Trig (switch trigger) synth, you could use a simple npn switch circuit (see attached scheme).

STEP 5: The Software

I tried to keep the sketch as clear and "readable" as possible.

I worked on a simple calc sheet i found HERE to derive a Voltage Vs Note# curve and use directly the equation in the microcontroller. The equation is shown in the graph on top. I used C2 as reference note to obtain a Arp/Korg compliant Voltage Vs note relation (C0 - 0.25V, C1 - 0.5V, C2 - 1V, C3 - 2V, C4 - 4V, C5 - 8V and so on).

I had to define some variable to toy with in order to get a good tuning... take your time to find the correct values. A tuner is necessary.

We are going to increase the pwm frequency of a Timer/Counter to reduce output voltages ripple (as easy as a line of code).

To keep the code responsive to incoming bytes, the code rely heavily on functions callbacks.

You are in the need for the Sparkfun's "Adafruit_MCP4725.h" and Forty Seven Effects/Francois Best's "MIDI.h" libraries to compile! (Many thanks to these persons: without their efforts this project would never be realized!).

I will assume you have Arduino IDE ready in your PC and you know how to load a sketch to your Arduino board.

I am not a coder in real life, so it is well likely that the sketch could be written in a better way. I am open to suggestions (I always learn something looking at coder's code ;))

Additional notes are written in the code below. Install the two libraries, open the attached code on your IDE, connect your board, select the type of board and upload.

STEP 6: Troubleshooting

Even if the project is low level, there are tons of things that could go wrong. If you are experiencing issues while attempting to create your own MIDI to CV box, follow these steps:

1. Be sure that Arduino is correctly receiving MIDI messages

Check the output channel your keyboard or DAW or Sequencer is outputting MIDI messages to. Arduino is listening to channel 1 by default. Upload "TEST_MIDI_IN.ino" to read a incoming noteON message.

2. Double check your wirings

... or even better: triple check them! Keep your time for this.

3. Check the DAC address and output

The DAC could be set to receive data on a different address than the one i set in the sketch. Check the address by running "I2C_scanner.ino". If a "no device found" error happens, check your DAC wiring (SDA and SCL inputs are different on different Arduino boards!). If you have an oscillocope (even those 15 euros digital oscilloscopes are good enought... and fun to toy with!) you can check the output of your DAC by uploading the trianglewave generator example included with the DAC library installation.

Remember that when a optocoupler is connected to the RX input of your arduino board, you will not be able to upload a new sketch!! Place a switch (it could be a simple jumper) before the RX pin.

Most of these test sketches are not mine or at least based on existing online material.

This thing sounds out of tune to me!?

This is not a real issue: the equation derived for Hz/V control is "ideal". Some drift from the ideal behaviour can rise from the +5V you are supplying being not 5.000V, from the DAC and from the instrument itself. To solve you must act on your synth tune/fine tune potentiometer and "voilĂ " a perfectly tuned MIDI control ;)

STEP 7: Useful Links

42 Comments

Solved, I changed the baud rate in the serial monitor to match the code (115200 or something) and it read the dac address as 0x61 not 0x60 so I changed the address in the code to 0x61 and it worked! It's just about 1/2 an octave out of tune. I can use the fine pitch to solve this or is there a way to adjust it on the circuit board with the Arduino with a potentiometer somewhere? Great little gadget by the way!

Glad that you solved. By looking at the code, I can see that I included the possibility to connect a potentiometer to arduino pin A0 to apply an offset.

Alternatively, you should be able to correct the pitch directly on the MS10 via the "master tune" potentiometer

Hi, newbie here

I made this to control an MS-10 from Logic and/or midi keyboard. The trigger seems to work upside down (note on when you release the key) and nothing happens from the CV out, it holds a note but doesn't change with the keys. In the photo have you linked the grounds on the jack sockets? So are they all linked in common with the grounds on the Arduino and DAC? I know nothing about coding so I just followed the schematics and uploaded the software. I feel like it's working but not quite there yet any pointers on where to start troubleshooting?

edit: I fixed the trig with a transistor so I just need to work out what's going on with the DAC

Thanks for the reply, I appreciate this thread is really old. Is this bad? Also, as the gate output is working as it should does that mean the midi is ok?

Hello, yes grounds are all shared (short circuited) between boards and jacks must have sleeves connected to ground. I wrote a full step to troubleshoot issues with this project (Step #6): you have to read it carefully and check I2C connectivity and MIDI activity via the shared TEST sketches.

It's a long time I wrote this Instructable, so I am sorry if I cannot be of more help than this.

Cheers

Ok for those who are interested, I just made a program with one MIDI in and 6 modulation CVs. I already have a MIDI CV and Gate for notes and velocity. Just tested on a breadboard. Tested and working. I haven't built it yet. It's my next step.

I have :
CC1 -> modulation Wheel
CC4 -> Foot controller
CC11 -> Another foot controller
CC6 -> Ribbon controller (An1x)
CC16 -> Joystick X controller (Homemade)
CC17 -> Joystick Y controller (Homemade)

Here is the program

#include <MIDI.h>

//set at your will ...
#define MIDI_CHANNEL 1 //the MIDI channel you want your box to listen to (1-16)
#define CC_NUMBER 01 //MIDI CC number
#define CC_NUMBER 04 //MIDI CC number
#define CC_NUMBER 11 //MIDI CC number
#define CC_NUMBER 16 //MIDI CC number
#define CC_NUMBER 17 //MIDI CC number

byte CCPin01 = 5; //pwm frequency is going to be increased for this in the setup
byte CCPin04 = 6; //pwm frequency is going to be increased for this in the setup
byte CCPin06 = 3; //pwm frequency is going to be increased for this in the setup
byte CCPin11 = 9; //pwm frequency is going to be increased for this in the setup
byte CCPin16 = 10; //pwm frequency is going to be increased for this in the setup
byte CCPin17 = 11; //pwm frequency is going to be increased for this in the setup

int CCOut01;
int CCOut04;
int CCOut06;
int CCOut11;
int CCOut16;
int CCOut17;

MIDI_CREATE_DEFAULT_INSTANCE();

void setup() {
//For Arduino Uno, Nano, and any other board using ATmega 8, 168 or 328
TCCR0B = TCCR0B & B11111000 | B00000001; // D5, D6: set timer 0 divisor to 1 for PWM frequency of 62500.00 Hz
TCCR1B = TCCR1B & B11111000 | B00000001; // D9, D10: set timer 1 divisor to 1 for PWM frequency of 31372.55 Hz
TCCR2B = TCCR2B & B11111000 | B00000001; // D3, D11: set timer 2 divisor to 1 for PWM frequency of 31372.55 Hz
pinMode(CCPin01, OUTPUT);
pinMode(CCPin04, OUTPUT);
pinMode(CCPin06, OUTPUT);
pinMode(CCPin11, OUTPUT);
pinMode(CCPin16, OUTPUT);
pinMode(CCPin17, OUTPUT);
MIDI.setHandleControlChange(MyCCFunction);
MIDI.begin(MIDI_CHANNEL);// start MIDI and listen to channel "MIDI_CHANNEL"
}

void loop() {
MIDI.read(MIDI_CHANNEL);
}

void MyCCFunction(byte channel, byte number, byte value) {
switch (number) {
case 1 :
CCOut01 = map(value, 0, 127, 0, 255);
analogWrite(CCPin01, CCOut01);
break;
case 4:
CCOut04 = map(value, 0, 127, 0, 255);
analogWrite(CCPin04, CCOut04);
break;
case 6:
CCOut06 = map(value, 0, 127, 0, 255);
analogWrite(CCPin06, CCOut06);
break;
case 11:
CCOut11 = map(value, 0, 127, 0, 255);
analogWrite(CCPin11, CCOut11);
break;
case 16:
CCOut16 = map(value, 0, 127, 0, 255);
analogWrite(CCPin16, CCOut16);
break;
case 17:
CCOut17 = map(value, 0, 127, 0, 255);
analogWrite(CCPin17, CCOut17);
break;
case 18:
break;
}
}
Thanks for sharing. You should describe your hardware too: arduino is not capable of outputting an analog voltage, but PWM. This means that it outputs a squarewave, with a duty cicle such that the mean value is your set voltage. This is not good for this application.
You have enought material to write a full featured instructable ;)
HI,

I'm getting A1-1.83V A2-2.87V A3-3.92V A4-A.96V A5-5.18

Is there a value in the program I can modify to get a linear value?

Is there a value in the program I can modify to set the correct voltage?

Else than that, it works perfectly, thank you

Xavier
Hello,

V/oct is not tested and, if I remember correctly, there are no correction factors already coded. It's a long time I wrote this code and unfortunately I have not the time to work on it
BUT
you could take a look at my MIDI4CV instructable: I have adopted a simpler approach (tabulated values instead of calculated) and see if you can adapt it to your project.
Here is the link:
https://www.instructables.com/MIDI4CV-Arduino-MIDI-to-4xCV-Interface-for-VCO-Pit/

Hope it helps
Thank you for taking the time to answer, I'll check the MIDI4CV.
I noticed you specified a BC547 pnp transistor - I am guessing the pnp is a typo and you mean npn? This is not available as a pnp and the circuiot seems to show a npn used?
Yes, sorry: that's a npn transistor. Will fix the instructable text
Thankyou
Hi. Late to the party here.
So, i have an error showing regarding this line in the loop setup:
dac.setVoltage(dacValue, false);
The error message says:
'dac' not declared in this scope

This is my first attempt at Arduino. It's been a long day of troubleshooting the issues step by step. This one i can't seem to hurdle around. For what it's worth, i had to use the old bootloader version with a CH34x port reader to even begin testing. It does receive a midi note on/off signal.

Ideas, anyone?
Looks like you are missing the DAC library: Adafruit_MCP4725.h
Thank you. It seems i added the wrong mcp4725 library at first; not the one that is specifically Adafruit_MCP4725.h
i have since added the one above, but it doesn't show in my 'contributed libraries", only in the 'suggested libraries', and in the libraries manager it says it is installed. When i include the correct libraries the adafruit_mcp4725 does not highlight in orange like the midi, for example.
Now it's saying: Adafruit_BusIO_Register.h: No such file or directory
Do you have the same error with the I2C_scanner.ino file I uploaded?
Libraries change sometimes and brake the compatibility with older sketches, but there are evidences of users uploading the sketch succesfully from 3 month ago or so, so it is very unlikely.
The scanner had read fine, as far as i could tell. What i wound up doing was using the Arduino Web Editor. It all worked smoothly! The library is now loaded on my Nano! Whew! Now i can feel comfortable completing the build. Thanks so much for your willingness to assist! Leaving this up in case it is somehow helpful to others.
My son and I built this device and it worked well after we had checked all the wiring and found the mistakes :)

We found that the effect of the velocity CV input to the initial gain was too small, so instead we took the signal output and fed it back into the VCA module and used the velocity CV as the control input to the VCA. This worked much better as the amplitude range was now from zero up to full volume. We also made a small change to the code by commenting out the line which zeros the velocity output on note-off. This was overriding the envelope release of the MS 20 envelope generator, which was not what we wanted.

Later, we might add some extra CC outputs and we also want to modify the device to use MIDI over USB.
Thanks for sharing your patching and nice to see this old work of mine was still a good starting point for your project ;)
Hi! I've recently made Cv box for my moog werkstatt. It works but I have some troubles with cv gate. It seems the gate is triggering the second note after playing the 1st one. Has anyone run into the same problem?
More Comments