Arduino Voltage Controlled Wavetable Oscillator
by baritonomarchetto in Circuits > Arduino
5385 Views, 15 Favorites, 0 Comments
Arduino Voltage Controlled Wavetable Oscillator
Lurking for a simple digital filter for my modular synthesizer, I got aware of the existence of a library capable of turning any arduino board into a wavetable oscillator... WHAAAT!
I could not resist (how could I! Korg DW8000 is still one of my favourite synthesizers!) and immediately started developing a pcb for an eurorack wavetable oscillator based on Mozzi library.
In this instructable I will show you how I designed my voltage controlled wavetable oscillator prototype for modular systems.
I will also share with you the PCB I designed for the pourpouse.
Other Instructables in this serie:
Discrete Voltage Controlled Amplifier
Arduino ADSR Digital Envelope Generator
Voltage Controlled Multimode Resonant Filter
DIY Linear Regulated Eurorack Power Supply (and Power Bus Bar)
Features
I designed the board layout with very specific functions in mind (see "The Sketch" step), but given the possibility to upload any custom sketch/firmware, this can be seen as a base for a lot of different modulars (i.e. Mozzi oscillators, but not only that).
In general the PCB is designed to handle:
- up to four potentiometers, for direct control of parameters
- up to three analog/digital pins, overvoltage (>5V) and negative voltage protected
- up to seven additional digital pins , not protected
- one built-in trimmer for fine, permanent settings (i.e. V/oct scaling)
- small footprint
- eurorack power supply ready (2x8 pins IDC connector)
- built-in Midi IN circuit
- open firmware
The community around the Mozzi library made an incredible work in these years. Not only the libray itself is very deep, but there are also utilities that can help make this thing even more interesting. In example: what about the possibiliry to create your own wavetables from wav files! O_O'
Hardware Design Choices and Circuits
Using arduino and Mozzi library for this project makes the pure sound generation "simple", but some boundary/slave circuit are needed to accomodate an arduino into a module that will coexist with other, external modules.
A necessary precaution concerns input/output voltages: Arduino sends and receives "logical" inputs, therefore it is limited to the 0-5 V dc range both in input and output. To overcome this, I have included three voltage limiting circuits, one for each analog pin. This circuit can be done in various ways: frequency divider, use of a Zener diode, use of Schottky diodes... just to cite the most common. The circuit adopted in this board is made with schottky diodes as per Doepfer specifications. The circuit lowers any voltage above 5V (in a modular system we can expect up to 10-12V for a control voltage), "stops" any negative voltage, and transfers variable voltages below the 5V threshold voltage.
Notice that the afromentioned circuit works to protect an input from overvoltage/negative voltage, but also an output from external applied voltages.
Another built-in circuit is MIDI input. The circuit is built around a common optocoupler (6N138) and it's shown above. To optimize the code, I generally prefer to use hardware serial instead of software serial. This project makes no exception. Being that the MIDI circuit interfere with arduino Rx pin even when nothing is connected, I placed a simple jumper, labelled "JRx". This has to be removed/switched every time you want to upload a new sketch and then inserted back in for MIDI to work. A little annoying, but keeping the code lean has priority in a project that deals with waves generation (you will get used at that, don't worry!).
To use Mozzi library at its best, audio output is made compatible with both STANDARD PLUS and HIFI modes.
In HIFI mode, bit depth is increased and effective noise floor reduced. It does not have an effect on distortion or unwanted PWM frequency interference, anyway.
To have your hardware ready for HIFI mode, populate R1, R2, R3 and C1 with:
R0 - 1M ohm
R1 - 1M ohm
R2 - 3.9K ohm
C1 - 4.7nF
To have your hardware ready for STANDARD PLUS mode, instead, populate R2 with a 330 ohm resistor and leave the other components unpopulated.
Setting HIFI mode asks for both the described components in the output stage, but also for a software mod. Go to "Documents\Arduino\libraries\Mozzi-master", open "mozzi_config.h" and change
#define AUDIO_MODE STANDARD
//#define AUDIO_MODE HIFI
to
//#define AUDIO_MODE STANDARD
#define AUDIO_MODE HIFI
In this shield, all arduino nano analog inputs are wired: four are dedicated to the front panel potentiometers, three can be used for external analog inputs/outputs (with overvoltage protection) and the latest (A7) is hard-wired to a utility trimmer.
A total of seven digital inputs are accessible for user functions.
Please notice that the sketch I wrote cannot be uploaded into an Arduino nano with ATmega168 processor because of memory limits. Be sure to buy a nano with ATmega328P.
Even if the board is equipped with a full 8x2 IDC connector, being 100% digital this projects is powered by +5V only.
The Sketch
I wrote a sketch as a starting point for future implementations and features.
Being this intended to be the oscillator of a modular synthesizer (mine :) ), you will not find a whole synth coded, but a steady, two waves generator.
So, what I coded here are two detunable, wavetable assignable, pure oscillators. Selectable waves are sine, triangular, saw, square, and white noise, in any combination.
The oscillator pitch can be controlled by MIDI or voltage.
In the followings the functions of potentiometers, buttons and incoming MIDI messages.
Potentiometers
The first potentiometer POT_A0 controls the relative detuning of wave two.
The second potentiometer (POT_A1) acts on the relative gain of the two waves: fully clockwise you will hear wave one only, fully counter-clockwise wave two only. Any other position results in a relative blend of the two waves.
The third potentiometer (POT_A2) controls the global output gain.
The fourth potentiometer (POT_A3) affects the main tuning.
The built-in trimmer is used for V/oct scaling.
MIDI
If a MIDI note-on messages is received, waves are tuned accordingly.
A gate out signal is output at A5 pin when a MIDI note-on (HIGH) or note-off (LOW) message is received, accordingly.
Default MIDI channel is set to 1 and can be easily changed by uploading a new firmware.
Both MIDI note-on and pitchbend are supported.
MIDI note priority can be set to latest, lowest or highest (default). You can change the behaviour at your will by repalcing the #define HIGHEST line of code with #define LOWEST or #define LATEST.
Control Voltages
This wavetable oscillator is not MIDI-only, but also voltage controlled. By sending a 0 - 5V signal to analog input A6 both waves will tune accordingly. As said, the trimpot acts on V/oct scaling.
A simple voltage control over wave two detuning is coded: if a reading other than 5V is available at analog input "A4", it is summed to POT_A0 reading and toghether detune the oscillator.
MIDI note-on message has the priority over voltage pitch control, and disables it. In order to re-activate CV pitch control, disconnect the MIDI cable then reset the microcontroller.
Please notice that I had not the possibility to test adeguately the CV part of the code (I have not a keyboard, nor a controller adopting the V/Oct standard at the moment), but I will in the near future.
Buttons
Two non-latching buttons are used to indipendently select wavetables on the fly. Wavetable one can be changed by pressing a normally open button/switch shorting D2 to ground; wavetable two with a button on D3. You cycle through waves at every button press. Waves are sine, triangular, saw, square and white noise in any combination, but they can be easily changed modifying the sketch.
Two non latching buttons connected to D4 and D5 are used to set the pitch height of each wave. You can transpose the base pitch up two octaves and down one octave.
The full code can be found HERE (Github).
Please notice that I have left some code lines for functions I planned and implemented, but in the end I have disabled. In example, I had planned some sort of modulation for at least one of the two waves (vibrato) to give some additional movement to the base sound. It's disabled, but still there for future reference :)
BOM and PCB
You can have your PCB manufactured at the following link (PCBWay):
https://www.pcbway.com/project/shareproject/Arduin...
Select a nice color, place your order, have it shipped to you, source components, assemble it and have fun in the process!
The board is intended to be mounted perpendicular to the front panel. If your case is not deep enought, you can lock the board on the case bottom and use wires to gain electrical connection with elements (potentiometers, buttons, jacks and so on) on the front panel.
All components values are silkscreened on the PCB to make assembly easier.
Follows the list of components:
Microcontrollers
- 1x Arduino nano (ATmega 328p, NOT ATmega168p)
Capacitors
- 1x 100n ceramic
- 1x 4.7n ceramic
Resistors, Potentiometers, Trimmers
- 4x 10K ohm potentiometer
- 1x 10k ohm trimmer
- 5x 1000 ohm resistor
- 1x 200 ohm resistor
- 1x 330 ohm resistor
- 2x 1M metal film resistor (HIFI mode)
- 1x 3900 metal film ohm (HIFI mode)
- 1x 330 ohm (standard_plus mode)
Diodes and optocouplers
- 1x 6N138
- 6x BAT42 Schottky
- 1x 1N4148
Others
- 1x DIN5 MIDI connector
- 1x 2x8 IDC connector
- 1x PCB switch
Future Plans - Paraphony!
Realizing a single, two waves oscillator was incredibly fun. When I start thinking at what could be next, I cannot stop to figure that a polifonic chain of such wavetable oscillators would be awesome...
... one of the next projects could well be a midi controller for a stack* of wavetable oscillators like this, or eventually for any CV oscillator!
* stack reasonably could mean four: I have these MCP4728 4 channels DACs on their way to me ... ;)
Acknowledgments
The PCB you can see pictured in this instructable was sponsored by those nice girls and guys at PCBWay - PCB Prototype the Easy Way. Their customer service in excellent and PCBs of the best quality (and I had the opportunity to test various batches for different projects, so I am not saying it just to say it!).
Thanks :)