A Note on Code

While describing each line of my code would be far beyond the scope of this blog, I realise the I have barely mentioned this vital part of my modules, and so thought I should dedicate a post to at least explaining the overall structure of my sequencer’s code.

Arduino files are referred to as ‘sketches’, and the sketch for my euclidean sequencer contains about 800 lines of code. Thankfully, the Arduino IDE allows us to separate this code into tabs, as shown below:

When the code is run, only the first tab is used, but it can reference other tabs to run as processes, rather like the subpatchers I used in my Max patch earlier on. My first tab contains four parts:

  1. Libraries to be used – this lets my code know where to find the used libraries which are referenced later on. In this case, I have used one to help with the maths of the Euclidean rhythm and one for controlling the LED matrix.
  2. Set values – not only do initial values of things like the sequence length and number of hits need to be set, but the code needs to know what values need to be stored. I have categorised these into I/O, sequence, timing and control variables.
  3. Set pinmodes – the Arduino needs to be configured so that it knows what each pin (connection to the outside world) should be listening for or outputting. This section also includes initialisation of the LED matrix.
  4. The loop – this is the part of the code which runs repeatedly, thousands of times a second, once the first three stages have been completed. It contains the vast majority of our code, so to keep things simple and readable, I have arranged it into six discrete processes to be run sequentially, which are spread out over the other tabs but referenced and run from here.

buttonFunctions()

This process checks to see what the current state of the two buttons on the module are, and updates other values accordingly. The left button handles start/stop, and the right button randomises the values of the sequences using the random() function. The second button can also be held down and used as a modifier, allowing a full reset if the first button is pushed, or an individual lane reset by pressing the appropriate encoder.

encoderInputs()

This is the most complex step, at 219 lines of code. It considers the movement of the encoders, as well as their push states and the position of the toggle switch, and passes this information on to the next step as increases or decreases to various values. It allows not only sequence hit and offset changes, but also changes to the tempo, length of the sequence, and global hit and offset modifiers.

setValues()

This step takes the information from the previous process, and uses it to update all important values. It also has the vital job of checking if any illegal values have occurred – for example, has the number of hits moved below 0 or above 16? If it finds such an illegal value, it will correct it appropriately – in the case of hits the number is limited at a minimum or maximum, and in the case of offset it rolls around, so -1 becomes 15, and a 16 becomes a 0, etc. These examples assume a 16 step sequence – for shorter sequence length the roll around or maximum values will be different.

generateSequences()

This process does the important job of taking the values of each sequence (the length, number of hits and offset), and converting this into an array. An array is a set of data values that can be referenced by step – in this case either 1s or 0s. For example, seq1[] might contain the following data for a 16 step sequence with 8 hits and no offset:

1010101010101010

Finding the value of the third hit can be done using seq1[3], which in this case would return a value of 1. These arrays hold our Euclidean rhythms and are vital to the whole endeavour!

setDisplay()

Unsurprisingly, this process takes the values from our recently generated arrays and converts them into signals which are sent to update the LED matrix displays. To avoid the displays jittering and constantly updating, it starts out with a little bit of code to see if anything has changed since the last update, and skips the rest of this stage if it has not.

runSequence()

This final stage relies on a counter, which calculates how many milliseconds need to pass between steps (depending on the tempo), and once this amount of time has passed it outputs any 1 values found in sequence arrays for the current step as a positive voltage on the output pins. It also allow for manual timing input from the ‘next step’ input jack, and automatically resets the sequence to its beginning each time the sequence length has been reached.

Laser Cutting Faceplates

This Adobe Illustrator file was used to cut my design. Red lines cut all the way through whereas blue areas are just etched.

After recently reading about improving design, and also being rather disappointed with the crudely drilled holes in the faceplates on my first two modules, I did some talking with the workshop team at UH and was given an induction on using the laser cutting machines.

As well using the laser to cut plastic, they can also etch into it, meaning that my next module could have labels and a design – great! After taking measurements of the project box, and also the sizes of hole need for the jacks and pots, I came up with the design shown to the right, and got this printed onto a perspex offcut. Unfortunately the font I had chosen was not installed on the printer, so the result was slightly different to what I had designed, but I was still very pleased with the improvement in look over my previous models.

Euler – Quad EG and Mixer

This diagram shows each mixer channels’ circuitry. Note that the code on the chip is incorrect, as there is no LM324 build into Fritzing.

My third post in this blog, posted a year and a half ago, shows an image of my next prototype module – an envelope generator, VCA and mixer.

This was my first foray into analogue circuitry, and as such there are some pretty strange issues with this module, particularly when using full settings on any potentiometer. These are not bad enough to stop the unit from functioning, but I would be highly unimpressed if I purchased a mixer which seemingly swapped the phase of each half of the stereo signal above a certain output level!

An Arduino NANO was used to generate the envelopes needed, but everything else was achieved using op-amps and RC filters. The op-amps chosen were LM324 quad amps, and these were the first chips I experimented with other than the Arduino boards.

The mixer being tested before installation into its project box.

The Design of Everyday Things

This project has design at its heart, and so this book (recommended by my brother) seemed like a good read. Norman discusses the psychology and psychopathology of actions and responses, shows some excellent examples of both good and bad design. He explores conceptual models and how to utilise these to create more user-friendly products, and introduces the ‘Human-Centred Design Process’. I found his chapter blaming many so called ‘human-errors’ on bad design particularly interesting, and will aim to integrate these ideas into my future design work.

The Oscillator Module

Next up, it was time to build something that actually made some noise!

My goal was to create four discrete outputs, each of which would be fed into a VCA controlled by the four lanes from my sequencer. Each output should contain a different note, and these should make up a chord. This device would then need to be controllable via an external CV source. I had a think, and decided that my chords would be defined by four parameters:

  1. Root note (A through G, always using sharps rather than flats)
  2. Octave of root note (0-5)
  3. Chord type (major, minor, 7th, minor 7th, dominant 7th, diminished, 6th, minor 6th, augmented, augmented 7th, suspended 2nd, suspended 4th, powerchord, octaves and stacked major 3rds)
  4. Inversion (A-C as normal inversions, and 1-3 where the root note is pushed down 1,2 or 3 octaves)

I would then allow either the currently output or the ‘next chord’ to be modified by either rotary encoder or CV input, and then have a set of buttons and trigger inputs which switch between the two.

As analogue oscillator circuitry was still beyond my understanding, I decided to use Arduino to digitally create square waves at controllable frequencies as my sound sources. I found a library which allows each NANO to output two accurate square waves, but unfortunately I could not generate all four from the same board, meaning the two boards are used in this circuit – one managing all of the inputs, deciding what notes should be played and outputting the first two pitches, and the second just listening to commands from the first and outputting the other two signals. This meant learning how to get the two boards to communicate, for which I used the Wire.h library.

Due to the increased number of inputs and outputs compared to the previous module, this one has a far more complex circuit layout.

Project Boxes

The sequencer was now working, but needed to be built into a more robust housing. While the end goal is to miniaturise into Eurorack compatible modules, for now I decided that preliminary work on other modules would better improve my electronics skills before moving on to PCB design. As such, I did some searching and found these plastic ‘project boxes’ on Amazon. These are just the right size to safely hold my circuits, displays and controls, and also look much smarter than a half opened cardboard box!

The sequencer in its upgraded new home. Note the higher quality buttons used.

Small holes were drilled through the box to allow the LEDs mounted on the circuit boards to shine through, signifying when each output is active.

Another consideration was power. The Arduino UNO boards I had previously been using worked with a 12V input, but the NANO sacrifices this option for its smaller form factor. This meant the addition of a power regulation board (purchased again from Amazon). I also added twin power ports to allow daisy-chaining of power between this device and those to be built shortly.

Module Plan Overview

Now that I had a working prototype module, I decided to hold fire on the sequencer and have a think about how it could integrate into a larger system. The following sketch shows my ideas for three more modules which could create a full Euclidean rhythm, and all of their inputs and outputs. I also thought at this point about whether this would work better as a single unit with everything internally connected, but decided that four separate modules would be far more flexible and in keeping with the modular workflow.

The Sequencer Prototype

After a couple of weeks learning the Arduino IDE and tinkering with I/O devices such as LEDs and rotary encoders, I had a basic prototype built. Rather than documenting this entire process, I will instead focus on some points of particular interest.

The Display

Visual feedback is very important on a device like this, and I needed something which both displayed all the relevant information, but which was also cheap and simple to program. I settled on this pair of 8×8 LED matrices, which come with their own control chips and have an Arduino library written to allow for simple programming. My implementation uses the top row to show the tempo, the second row to show the number of steps, the third and bottom rows to show the current step, and the remaining rows to display the four lanes of the sequence. This is far clearer in the video footage below.

The Input Controls

While simple buttons would be fine for some functions, if every parameter in the device was controlled by these then I would need over 30 buttons, which would be both confusing and space consuming. It would also require more I/O pins than my standard Arduino will allow. I decided to keep buttons for a couple of functions (start/stop for example), but offloaded most input control to rotary encoders. These allow for both incremental increase and decrease in values, and also work as push buttons. Code-wise, these encoders were complicated to get right, and also hog a lot of computational power on the rather limited Arduino, so I will aim to replace them with a better solution in future revisions of the device.

This test video shows a simplified version of the circuitry involved. In this instance, only two lanes of the sequencer are being used. The encoders change the number of steps for each lane, and if pushed and twisted modify the offset. Sound is all being generated by the UH modular synth.
This second short video shows the entire circuit being used, including a toggle switch to change between lanes 1/2 and 3/4. Note the more advanced sound design from the synth meaning that the sequence is less obvious.

Up until this point, the circuit had been entirely constructed on a breadboard, but the next stage was to move it into a self-contained unit. As PCB design and printing is currently beyond my level of experience, I decided to use soldered stripboard, and designed my circuit using the freeware Fritzing software package. As miniaturisation was now a point to consider, I moved from the full-sized Arduino UNO to the smaller but just as powerful Arduino NANO.

This circuit contains four separate boards to keep things as simple as possible – one for the Arduino, one for button and switch input, and two for the jacks. Note the three extra jacks on the top right board, which are clock I/O CV, and the third encoder which deals with functions such as sequence length and tempo.
Once the circuit had been built, it was crudely attached to a cardboard box as an initial housing for tests.
The finished sequencer prototype mk1! Jack connections were still loose around the back of the box, but the basic concept was successful and most importantly – it worked!

About Arduino

Now I had a concept which worked in software, the next step was to try and bring things over into the hardware domain. After doing a little research into the options available, Arduino seemed to be the best solution.

The Arduino UNO board is a great starting point for DIY electronics projects.

Arduino is a DIY electronics platform based around a software coding environment, and a range of programmable hardware ‘boards’ which can be connected to various electronic devices via inputs and outputs present on the board. These could be buttons, knobs, LEDs, motors, etc, and can be configured to achieve a wide variety of goals. Custom code is written by the user and then uploaded to the board via USB, meaning that applications of the platform are hugely varied.

Whilst there are other far more powerful options available on the market, including those with dedicated DACs (which Arduino does not have), I chose to go with Arduino primarily due to its low cost – you can pick up cheap clone Arduino NANO boards for as little as £3 each. These have 22 I/O pins, with 8 of these able to receive analogue input, and a modest but usable amount of processing power. They are also very small (hence the name!) which is very useful when trying to miniaturise a circuit.

Code wise, the Arduino IDE (Integrated Development Environment) runs on a slightly modified version of the C+ language. This is not something I had used before I started this project, although I found it relatively simple to pick up. Certain libraries of code (such as drivers for particular LED screens or rotary encoder input) are freely available, and I used a few of these within my programming to save myself some time.

The video below shows my first attempt at using Arduino, and is a simple counter with just two inputs – an up button and a down button, and four LEDs to display the current count.

More info about Arduino:

https://www.arduino.cc/en/guide/introduction

https://en.wikipedia.org/wiki/Arduino

The Max Groovebox

This project started out as a modular synthesiser built in Max/MSP, primarily as a means for me to reacquaint myself with the software, with the intention of being able to better support students who were also using Max. As modules were built and connected , I decided to create a sort of performance environment, inspired by an old Korg EMX-1 which I used to own. This afternoon I opened this patch back up, and made a demo video which not only shows off the main features of the patch, but also demonstrates the use of the Euclidean Sequencer found in the bottom left corner.

As is often the case with reopening old Max patches, I would be lying if I said that I understood everything I had programmed back then, but a look into the back end of the Euclidean Sequencer module does give an overview of how things all fit together.

The Presentation View of my Euclidean Sequencer module. The Divisor function at the top changes how the sequencer responds to incoming clock data, effectively halving/quartering the tempo. Note that individual steps cannot be clicked on or off – all input is done by changing the values at the left of the device.
Moving to Patch View reveals a bit of monster! Thankfully I was reasonably good with keeping things neat and organised, but this is still quite tricky to read. A closer inspection shows that this is mainly comprised of four copies of the same code – one for each lane of the sequence. The boxes to the bottom right are just parts of the user interface. Boxes which start with a “p” are subpatchers, shown below.
These three subpatchers allow sections of code to be hidden from the main view, streamlining things and allowing for easier editing of the patch. They also allow the same process to be used in multiple places without having to rewrite the code each time. Of particular interest is ‘p euclidean.division’, shown on the right in this image, which does the all-important job of taking our input values and converting them into a Euclidean rhythm, which can then be displayed and played back by other parts of the patch.

Create your own website, free on WordPress.com.Create your own website.
Start free