MIDI4CV - Arduino MIDI to 4xCV Interface for VCO Pitch Control

by baritonomarchetto in Circuits > Arduino

2797 Views, 8 Favorites, 0 Comments

MIDI4CV - Arduino MIDI to 4xCV Interface for VCO Pitch Control

IMG_20210831_172548_slim.jpg


THIS BOARD IS NOW OBSOLETE. IT HAS BEEN REPLACED BY >>THIS<< PROJECT


One of my first instructables was a MIDI to CV module in Hz/V format. I needed it to gain some automation level with my MS10 (and MS20 afterwards).

Now, I am working on my first DIY modular synthesizer and since the realization of my first oscillator module I was intrigued by the possibility to push things further and target some paraphony.

In this instructable I will show you how to realize a simple but effective MIDI to CV module with up to four CV outputs for pitch scaling (V/oct format) and up to four additional outputs (gates or other control voltages).

I will also share a link where to have your PCB manufactured by professionals at low cost to speed up the project realization process.

Let's go!

Other Instructables in this series:

3340 Voltage Controlled Oscillator Module

Arduino Wavetable Voltage Controlled Oscillator

4 Channels Mixer

Voltage Controlled Multimode Resonant Filter

Discrete Voltage Controlled Amplifier

Arduino ADSR Digital Envelope Generator

Variable Waveshape Low Frequency Oscillator

DIY Linear Regulated Eurorack Power Supply (and Power Bus Bar)

Fiberglass Panels for DIY Modular Systems

Hardware and Features

activeBufferCircuit.png
overInverseFiltered Outs.png
MIDI_IN_Circuit.png

Main features of this hardware are:

- built-in MIDI input circuit

- up to four, op-amp buffered control voltage outputs (DAC outputs)

- up to four, passively overvoltage/inverse voltage protected PWM pins

- up to two additional digital I/O pins (unprotected)

- built-in 2 poles DIP switch for setup settings

- built-in 1 pole switch for other settings

- dual power supply input (+/-12V) protected against inverse polarity

Quad DAC outputs are overcurrent and overvoltage protected by a dedicated buffer IC, with one amplifier for each CV channel (see attached schematic). For the first time I adopted an active overcurrent protection for DAC outs in place of the simple current limiting resistor most often seen in DIY projects. This not only because it works better, but also because being the MCP4728 a surface mount device that will ask for some extra effort to solder in place with a common soldering iron, we don't want it to die because of an incorrect patching!

Gate outs are wired to Arduino's PWM pins. This way we can use them to deliver digital, on/off signals like gates signals, or use them to deliver control voltages by toying with Arduino PWM capabilities. Gate outs are inverse voltage and passively over voltage protected by zener diodes (see attached schematic), but I also placed a RC filter downstream for such PWM-to-CV possible applications.

MIDI input (schematic attached) is the classical arduino circuit based on 6N138. To reduce CPU load, I prefer to use the hardware serial to upload sketches when possibile in my projects. A dedicated hardware switch unhook arduino's receiving pin (Rx) from the MIDI circuit and makes loading a new sketch possible.

Components values are silkscreened directly on the PCB because it's way easier to assemble a PCB this way instead of having a comparison sheet.

As a reference, hardwired arduino's pins are:

Arduino pin - PCB component/header

D4-SW2
D5-GATE1
D6-GATE2
D9-GATE3
D10-GATE4
D11-RDY
D12-/LDAC
D8-DIP1
D7-DIP2

The module asks for +5V and dual +/-12V to work properly.

PCB and BOM, Faceplate Notes

IMG_20210831_103401_slim.jpg
IMG_20210831_103410_slim.jpg
IMG_20210831_103415_slim.jpg
IMG_20210831_103421_slim.jpg
IMG_20210831_103431_slim.jpg
IMG_20210831_181811_slim.jpg
IMG_20210831_181806_slim.jpg

The project is made up of two boards: main PCB and faceplate.

Main PCB

All components values are silkscreened on the PCB to make assembly easier.

The board is intended to be mounted on the bottom of the case with the MIDI connector facing out, and with used outputs connected to the faceplate through wires.

Here is the list of components required to populate the whole main PCB:

Microcontroller, DAC, Op-Amp

- 1x Arduino nano 328p
- 1x MCP4728 12 bit quad DAC
- 1x TL074 quad op-amp
- 1x 6N138 opto coupler

Capacitors

- 4x 0.1 nF non polarized
- 8x 100 nF non polarized (4 are optional)
- 3x 10uF electrolitic

Resistors, Potentiometers

- 5x 1K ohm ressitors
- 4x 10K ohm resistor
- 1x 330 ohm resistor
- 4x 4.7K ohm resistor
- 5x 220 ohm resistor

Diodes

- 8x BAT43 Schottky
- 1x 1N4004
- 1x 1N4148

Others

- 1x IDC connector female 8x2
- 1x DIN5 MIDI connector
- 2x PCB switch, ON-ON
- 1x DIP-2 switch
- 1x 14 pin IC narrow socket
- 1x 8 pin IC narrow socket


FacePlate

Faceplate in pictures is made of aluminum. Aluminum is a not-so-common material for PCBs (or at least I am not used to it), but it's a godsend for our application that PCB manufacturers offer 1.6 mm thick aluminum as base material, and at the cost of fiberglass!

This in particular is a generic (non silkscreened) 6HP faceplate with four holes for 1/4" jack connectors. It was sufficient for me to host three CV for my synth oscillators and a single, common, gate signal. As you can see from the pictures, this was also used to realize a simple but effective, passive multi for gate signal.

The faceplate gerber files can be downloaded at THIS link (Github). Please notice that I use 1/4" female connectors, not the standard 1/8" eurorack connectors. This means that faceplate holes of my faceplate file are too big for 1/8" connectors.

As an alternative, you can download my blank panels files (Github), modify the included panel source file (".brd") and have it manufactured. Eventually, you can have the blank panel manufactured and drill your holes afterneath.

Sketches

MIDI4CV_DIP_POSITIONS.png

Arduino is a nice piece of hardware, but what makes it great are those skilled persons sharing their work on it. Most of my past projects would not be possible without their indirect contribution, and this one makes no exception.

Here I used two libraries: Benoit Shillings's MCP4728 library and FourtySevenEffects's MIDI library. You can download the first one HERE (Github); the second is instead readily available from the Arduino library manager bult-in with the IDE. These are not delivered with the default IDE package, but can be easily installed following this guide.

Sketch #1 - MIDI4CV.ino

The sketch working principle is simple: up to four voltages in V/oct format are generated as a function of MIDI note-on/off messages and a single gate signal generated. There are 4 voice "slots" (one for each DAC channel) at disposal and notes are allocated one after the other at every note press.

Gate signal is adeguately turned high and low depending on keypresses.

Please let me underline one more time that the shield has 4 generic outputs hardwired for our use (labelled GATE 1, 2, 3, 4); only one is used in this sketch and actually delivers a gate signal.

Maximum number of voices/outputs the microcontroller will cycle voltages over (max paraphony) are user definable, by changing the DIP switch positions accordingly to the attached map.

There are two modes of operation: paraphonic and unison. User can switch between them by using the onboard switch (SW2).

When unison mode is selected, all user defined active outputs are set at the same voltage level. Note priority is set to "latest" and cannot be changed ATM.

When paraphonic mode is selected, MIDI messages/voices are allocated into any of the reserved slots independently. If the number of triggered voices is less than user defined max paraphony, unused voices voltages are set to that of a used voice. This makes the sound "fatter" and doesn't ask for a dedicated VCA for any voice.

As far as I know this voice handling has never been adopted before in a commercial product, nor in a DIY project

Voice stealing in paraphonic mode has to be coded: actually if the max paraphony is reached, additional keys are ignored.

To keep calculations on the lowest level possible and help maintaining the tiny ATmega328P CPU load at a minimum, I adopted a tabular strategy I learnt from a very skilled japanese tinkerer called Hagiwo. If you don't know him you should take a look at his note.org page and youtube page. In a nutshell, output voltages are set depending on the MIDI note-on message received and read from a table instead of calculated at every key event (this latest approach being the one I adopted in my first MIDI2CV project).

MCP4728 can be set to use an internal voltage reference (a straight 2.048V reference) or external (Vdd). Using the internal voltage reference has the advantage of a rock solid voltage tracking, but limited to a 0 - 4.096 V range. This means that by using the internal reference we have a span of four octaves instead of five, but voltage is more repeatable and reproducible. This sketch uses the internal voltage reference, but it is possible to modify it to use the external reference.

Not only MIDI note-on and off messages are effective, but also pitchbend. The current sketch doesn't handle clock, notes velocity, or any additional control change voltages.

Even if coding a polyphonic behaviour would be definitely possible (the four generic outputs could be assigned to four independent gate signals), I wanted to avoid overcoding the sketch and keep it on a reasonable level. The sketch is layed out such that coding individual gate outs, one for each voice, would be possible.

Adopting some bit math/manipulation this sketch could be more effective than it actually is. On the plus side, this in turn makes it more readable and easy to modify. Anyway, if you have some tip on how to make it more efficent, please comment below: I always learn something new by reading real coder's code!

Sketch #2 - MIDI4CV4Voice.ino

This is the most updated sketch being the one I currently use in my synthesizer. Four voltages (no more, no less) in V/oct format are generated as a function of MIDI note-on/off messages received and a single gate signal generated.

As in sketch #1, there are two modes of operation: paraphonic and unison. User can switch between them by using the onboard switch (SW2).

In unison mode, all user defined active outputs are set at the same voltage level. Note priority can be user defined at code level by changing the constant NOTE_PRIORITY. Allowed values are:

0 - highest note priority

1 - lowest note priority

Being a constant, it cannot be changed on-the-fly, but it would be something easy to implement.

When paraphonic mode is selected, MIDI messages/voices are allocated independently. The voice assign logic is as follows: if a single key is pressed, all four voices are set at the same voltage level (unison), corresponding to the received note. If a key adds up while keeping pressed the previous one, two of the four outputs are set to the voltage level corresponding to the new note. The third and fourth key pressed steal an output to the second group and third group of outputs respectively.

As far as I know this voice handling has never been adopted before in a commercial product, nor in a DIY project

Voice stealing in paraphonic mode has to be coded: actually if the max paraphony is reached, additional keys are ignored.

Like in the previous sketch, CV values are tabulated: output voltages are set depending to the MIDI note-on message received and read from a table instead of calculated at every key event. Again, MCP4728's internal voltage reference is here in use, so we are limited to four octaves.

Not only MIDI note-on and off messages are effective, but also pitchbend.

The current sketch doesn't handle clock and notes velocity. Control change #1 (Mod Wheel) is used to activate and deactivate gate retrigger. If the mod wheel is in it's lower half, gate retriggering is not active. You can assign this function to any other CC message by simply changing the value of "controlNumber" variable ("1" means "mod wheel") in "handleControlChange" function. That function also holds the threshold value for retriggering.

The binary DIP switch has no associated functions in this sketch.

Debug/Utility Sketches

I wrote two simple sketches to test DAC functionality and MIDI input. They will be useful to throubleshoot your work in case of issues:

- The first one checkes the MIDI connectivity: when a note-on message is received, Arduino nano's built in LED turns on for a second.

- The second tests the four DAC's outputs: it cycles outputs voltages of 0V, 2.5V and 5V at a frequency of 1Hz.

All aforementioned sketches are available HERE (Github).

Soldering Tips

Being the DAC a 0.65 mm pitch integrated circuit, you have to adopt some strategy to succesfully solder it in place with a common stilus soldering station. My suggestions are:

- solder the DAC first. You will need space around your solder tip and you don't want to waste other components in case of problems.

- use a thin iron to solder the chip and a scanning electron microscope (just kidding! A magnifying glass will suffice)

- use some soldering flux. I had the best results with a cheap "no-clean" Rosing Mildly Activated (RMA) pen

Soldering Method:

- melt a little amount of solder on the IC pads on the PCB. You want to see a certain amount of solder over the pads, but no shorts between pads

- place the DAC over it (with the right orientation!) and wet everything with the soldering flux

- remelt the pad-solder with a clean iron tip while applying a veeeeery small pressure on top of the IC.

Re-apply the flux everytime you feel it's needed.

The iron temperature is very important: it should be high enought to fast melt the solder, but not too high or it will kill the IC. I had success with a temperature of 350-370°C.

When the DAC is soldered, check for continuity between IC's legs and the corresponding vias, close to each feet of the IC.

This is the method that works best for me. Again: keep attention to the IC orientation!

Having it well soldered could ask for some trial and error at first, but believe me: if I can do that, you can. As a precaution buy more than one IC.

The chip must be soldered with the right orientation!

Acknowledgments

Both main PCB and aluminum front plate pictured in this Instructables where sponsored by JLCPCB, a high-tech manufacturer specializing in the production of high-reliable and cost-effective PCBs.

Their customer service is very good and PCBs a great value for the money!

Please, let me stress out that this type of sponsorship is essential to experiment new solutions and share good quality and full working circuits and layouts.

It allows testing a first prototype and then share a second (or third, or fourth...), improved and corrected revision of the board.

This mechanism has a very positive impact in the quality and reliability of shared projects.

Many thanks!