Quad Graphical Envelope Generator Module for Eurorack Synthesizers
by baritonomarchetto in Circuits > Arduino
711 Views, 10 Favorites, 0 Comments
Quad Graphical Envelope Generator Module for Eurorack Synthesizers
We are all used to segmented envelope generators, those (often but not always) 4-knobs modules with separate attack time (A), decay time (D), sustain level (S) and release time (R). These have been used for decades, work great and are a common device in any synthesizer.
They are not flawless, anyway (shame on meee!), the biggest limit being the flexibility of the voltage profile they can output.
Here it comes the idea: what if we could directly draw our envelope on a touch screen and have voltages proportional to our drawings outputted?
In this instructable:
- I will show you how I layed down my prototype graphical envelope generator
- I will describe its functions, strenght points and limits
- I will share with you all files needed to have the boards manufactured and running in little to no time
Let's go!
Supplies
The project calls for a limited number of components. Here is the BOM, for back board and front board:
Back board:
- 1x Arduino Nano, ATmega 328p (the ATmega 168 will not work!!)
- 1x MCP4728 DAC, 12BIT, QUAD
- 1x TL074 OP AMP
- 8x BAT42 zener diode
- 3x 0.1 uF ceramic capacitors (104)
- 3x 10 uF electrolitic capacitors
- 8x 1K ohm resistors
- 12x 10K ohm resistors
- 2x 4.7K ohm resistors
- 8x PJ301M female MONO Jack Connector 3.5mm
- 3x WH148 potentiometers
- 1x FC/IDC connector 08X2
- 1x pinheader, female 1X19
Front board:
- 1x TFT 28" SPI display with touch screen
- 4x B3F-4050 OMRON PCB momentary switch 12X12
- 7x 2.2K ohm resistors
- 1x 5.1K ohm 9 pins resistor network (8 resistors in parallel, one common pin)
- 1x pinheader, male 1x4
- 1x pinheader, male 1x14
- 1x pinheader, female 1x4
- 1x pinheader, female 1x14
You are also in the need for a soldering station, solder wire, a magnifying glass, patience, patience and patience :)
From the Idea to the Prototype
At first my idea was the development of a single output graphical envelope generator based on Arduino nano and a MCP4921 12-bit DAC. These are devices I had already used in a previous ADSR project and I knew I could manage them easily.
The novelty, at least for me, was on the touch screen side. Luckily, they are available, cheap and, most important, supported by the Arduino community.
Screens with touch controller come in a variety of sizes and, as you know, in eurorack synthesizers modules size matter (the smaller, the better). On the other side, drawing a complex profile on a 1.44" screen is unpractical.
I then bought different sized touch screens, in order to put my hands on them and find a good compromise between module dimensions and screen dimensions. I first ended candidating a 2.4" sized screen because it was a perfect fit for a 16 HP module*.
Once module dimensions were defined, I had another decision to take: fill the module with functions (i.e. output inversion, DC offset, activity LEDs, gate and trigger inputs and so on) or increase the number of outputs.
Being that:
- My DIY eurorack synthesizer has 4 oscillators and could take advantage from a quad envelope generator
- I have all the listed extra functions (and more) covered by the Blocks project
- I have already had a very satisfactory and fun experience with quad DACs in my MIDIXCV project...
... the obvious choice was to take the multi-outs way and switch to the MCP4728 quad DAC.
After a few tests on breadboard I was confident enought that the project could be realized. One big question was left, anyway: will the arduino nano be capable to handle (and STORE) four, different and independent envelopes, potentially triggered at the exact same time?
The answer in the followings :)
*Later on, while testing, I realized that those screen have big border "dead" zones where touch is not well recognized. The one I had bought was also super-sensitive to the touch. I switched to the 2.8" screen, in the end, which forced the module to a 16+ HP minimum width ("plus" because it's one tenth of an inch bigger than the standard 16HP).
The Hardware
The module is made of two boards: a main board hosting the digital and analog circuitry, and a front board for the touch screen and push buttons.
Main components have already been "revealed" in the previous step, with Arduino nano (ATmega 328p) as the brain of the module, a MCP4728 QUAD DAC it's right arm and a 2.8" ST7789 screen with XPT2046 touch controller the "skin".
What else?
DAC's outputs are limited to 4V in origin, but here boosted to 8V with a TL074 in 2X gain, non inverting amplifier configuration. This extends the envelope generator operating voltage from 0 - 4V to 0 - 8V.
The amplifier acts also as DAC's outputs protection against over/inverse voltage.
Gates inputs are voltage protected via a series resitor and two zener diodes each.
To guarantee electrical connection between the touch screen and the faceplace, this is made of FR4 instead of aluminum. This gave me the opportunity to free some vital space on the main board by allocating the needed voltage dividers to the screen inputs (the screen microcontroller is not 5V tolerant) directly on the faceplate.
All power supply voltages are filtered with electrolitic and ceramic capacitors.
The module hosts four buttons, four output jacks (1/8 inch), four gate inputs (1/8 inch) and three potentiometers (I will describe their functions in the following Steps).
All components are cheap and common. Mono female jacks are those PJ301M you can buy everywhere online. Potentiometers are those most often labelled WH148. These are horizontal mounting pots, but by bending and "elongating" pins with some single pole conductor they can be easily mounted vertically. As a side effect, they give to the populated PCB a vintage feeling that I like a lot :)
Hardware Limits
Even if Arduino nano is well known for being short in SRAM capacity (2Kb on ATmega 328p), I think this is the first time I actually pushed it to its limits. Most of this is due to the need to store not one but four envelopes in memory to have them ready to be triggered at any time .
Another limit reside in the microprocessor speed. It's 16MHz are more than enough for most applications (just for an unfair comparison: the Fairlight CMI dual processors cycle speed was 1MHz), but here we want to process four envelopes, and we want them as "snappy" as possible at extreme settings.
How did I managed these limits? See next Step.
The Code
The main tasks of the code I wrote are:
- being able to store and visualize a user drawn envelope
- being able to output a voltage proportional to the instant envelope amplitude at any time
Four channels are handled and can be triggered at different, independent times.
Envelopes can be copyed and pasted between channels (see "How to Use" Step for details).
Envelopes can be triggered both by button press or by an actual, incoming gate signal (+5V).
To face the microcontroller memory limits, my main solution was the "compression" of the 2-bytes variables defining the envelope profile to 1-byte. These are then rescaled when needed to generate outputs voltages.
Another trick that helped facing memory limits was fixing the envelope resolution. This makes not necessary to store the "position in time" of each point, being that they are equally spaced. A fixed resolution has the drawback of "quantizing" the envelope, but also makes its execution faster.
Being that drawing a few-points-only envelope (then snappier envelope) is not that simple on these tiny screens, two potentiometers can stretch (from half position to right most position) the time scale or reduce (half position to left-most position) the resolution of the two envelope's sector. A resolution decrement means that user can draw a well defined envelope, but code will skip the execution of some of its points.
The code makes use of different libraries from Arduino community:
- Adafruit_GFX.h - graphic library
- Adafruit_ST7789.h - Hardware-specific library for ST7789
- XPT2046_Touchscreen.h - XPT2046 touch library (Paul Stoffregen)
- SPI.h - SPI communication library
- Wire.h - I2C communication library
- mcp4728.h - DAC MCP4728 library (Benoit Schilling)
All these can be sourced directly throug the IDE's library manager, with the exception of Benoit Schilling's MCP4728 library.
How to Use
When we first turn the module on, we are welcomed by a pre-loaded envelope. The screen is divided into two sectors by a vertical line. We are on channel A and we can directly use the envelope already loaded or draw a new one for that channel.
Envelope Shapes and Sectors
Envelopes appear differently from the classic ADSR shapes we are used to. The screen is divided into two sectors with a vertical line. This separates what is equivalent to the attack/decay section from the release section. In other words: everything drawn in the first sector is played as long as there's a gate on signal, everything drawn in the second sector will be outputted when the gate goes out (release).
When sector one finishes, the latest voltage is held (sustain). For the sake of ease of visualization, the sustain level is marked by a violet circle on the vertical line.
Envelope Offsetting and Stretching
The first potentiometer (red knob in my prototype) sets a DC offset to the drawn envelope. The offset can be positive or negative, but the output is always a positive voltage. This is mainly used to set the zero volt level of the envelope, being not always easy to spot while drawing, but helps finding the "sweet range" of operation of the destination module.
Second and third pots (yellow knob) sets the time stretch in each of the two envelope sectors (from half position to right-most position) or the envelope resolution (from half position to left-most). This means that one could have e.g. a fast envelope on sector one, slower on release or viceversa.
Potentiometers and touch screen are, all-in-all, your weapons to shape the envelope.
Change Envelope Channel
Channels are independet and we can jump from one to the other by pressing the corresponding button. If an EG has already been stored in a channel, it will be loaded and visualized.
Envelope Triggering
We can trigger envelopes in two ways: by pressing the channel button and keeping it pressed untill the end of the envelope (thus emulating a gate signal) or by sending a gate signal at the corresponding channel input.
Envelope Copy
User can copy an envelope from one channel to another simply by keeping pressed the button of the source channel, then pressing the destination channel button.
LFO mode
If we draw an envelope inside sector one only, this will be looped "forever". One possible use for this could be the realization of a "name-a-shape-here" low frequency oscillation or even a stepped wave (S&H-like effect) at extremely low resolutions and time stretch.
Does It Work?
Now, after all these words it's time to give an answer to the question: "can arduino nano handle and store four independent envelopes, potentially triggered at the same time?"
Yes, but with some limitation (I knew!!).
A well defined envelope with maximum resolution can take more than one second to reach the release phase. One with the resolution potentiometer set at the extreme left position, less than 50 ms. Very low resolutions means a "digitalized" envelope, but also snappy.
Attached are pictures of different (tipical and atipical) envelopes and LFOs. The last one shows the effect of cranking the resolution to lower settings.
If you are "a person skilled in the art" and imagine to apply those curves to e.g. a resonant low pass filter, you can even heard how do those modulation voltages sound... :)
Soldering Hints
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 stylus soldering station. Some suggestion follow.
General Procedure:
- solder the DAC first. You want space around your solder tip and you don't want to trash other components in the case of problems.
- use a thin iron to solder the chip
- use a magnifing glass to zoom the soldering area (even better would be one of those "cheap" microscopes they sell nowadays, but it's not everybody priority I know)
- use soldering flux. I had the best results with those siringes containing dense flux, lately.
Soldering Method:
- melt a little amount of solder on PCB's IC pads. You want to see a certain amount of solder over the pads, but no shorts between them.
- place the DAC over it with the right orientation and apply soldering flux. Be 100% sure the IC has the right orientation!!
- remelt the pad-solder with a clean iron tip while applying a very 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 set temperature of 350-370°C.
When the DAC is soldered, check for continuity between IC's legs and TL074 inputs vias.
Alternatively...
If you don't feel confident in soldering such a small SMD component, be aware that most PCBs manufacturing Companies offer an SMD assembly service you can take advantage from. I have always being very happy with JLCPCB SMD assembly service and this project made no exception.
Please notice that the DAC is the only SMD component in this project, so it's the only element you will find assembled.
Acknowledgments
Many thanks to the nice girls and guys at JLCPCB for sponsoring the manufacturing of PCBs and SMD assembly service for this project. Without their contribution this project would have never seen the light.
JLCPCB is a high-tech manufacturer specialized in the production of high-reliable and cost-effective PCBs. They offer a flexible PCB assembly service with a huge library of more than 350.000 components in stock.
3D printing is part of their portfolio of services so one could create a full finished product, all in one place!
By registering at JLCPCB site via THIS LINK (affiliated link) you will receive a series of coupons for your orders. Registering costs nothing, so it could be the right opportunity to give their service a due try ;)
All Gerber files and sketches I realized for this project are stored >>HERE<< (Github). I always upload the most recent file's versions, so it could be the case that some PCB looks a little different ("better" in my intentions) from those published in this instructable.
My projects are free and for everybody. You are anyway welcome if you want to donate some change to help me cover components costs and push the development of new projects.
>>HERE<< is my paypal donation page, just in case ;)