Master circuitry

The EnsembleBot master circuitry parses the EBP packages from the host, and redirects the instructions to the relevant instruments or instrument groups depending on the MIDI channel.

We placed the master circuitry on the backside of the EnsembleBot cabinet along with power connections and driver circuits for the local instruments. The local instruments are controlled either directly by the Arduino I/O ports (e.g. most of the percussion instruments) or indirectly by an I/O expander controlled by the Arduino through I²C (e.g. the tubular bells and the glockenspiel). The central EnsembleBot cabinet physically houses all local instruments.

Arduino Mega2560

The master circuitry is the main microcontroller and a number of supporting devices for communication, I/O expansion, power regulation and power protection.

The hub of the Quadrivium EnsembleBot is an Arduino Mega 2560 R3 microcontroller. In short, Arduinos are easily programmable microprocessors with a lot of built-in ways of communicating and interacting electronically with the rest of the world. We use the official Arduino IDE to program the microcontrollers. The IDE combines a code editor, a C compiler, lots of built-in support libraries, a microcontroller programmer and a serial monitor.

The Mega has a lot more memory and general I/O ports than e.g. the more popular Arduino Uno or Nano, which makes it ideal for our purposes. So far its 16 MHz processor has proven sufficient. But if it becomes a bottleneck, it is easily replaceable by the (almost) pin compatible but far superior Arduino Due (84MHz 32-bit ARM processor). You can read much more about the different microcontrollers in EnsembleBot here.

The Arduino firmware has two main tasks: (1) Routing EBP messages (MIDI) from the host to the instruments, and (2) Managing local instruments, i.e. instruments directly or indirectly attached to the master Arduino.

EnsembleBot master circuitry

Message routing is very simple. Like MIDI messages, the EBP messages contain a destination – MIDI channel and port – as well as a MIDI event payload. We use the channel number (0-15) to identify the instrument for which the message is intended. We use the same addressing in the CAN bus for addressing the specific slave instrument hardware.

Certain channels are reserved for external slave instruments, and the master relays their messages unaltered onto the CAN bus to the slaves. However, messages to channels reserved for instruments in or on the master cabinet (what we call local instruments), are processed by the master controller itself.

Local instruments are simple instruments attached to physical I/O ports or extended ports (see below) of the master Arduino. These are primarily instruments based on linear solenoids that are actuated by activating a port for a number of milliseconds. This is handled by a queued scheduler.


Even though the Arduino Mega has many I/O ports (in principle 54 digital ports), we are going to need a lot. The glockenspiel alone uses 27 ports, and the tubular bells use another 15 ports. Reserving additional ports for SPI and I²C does not leave many ports for e.g. percussion. So we need more I/O ports. More! MORE! MORE!!!

Master controller I/O

With four MCP23017 I/O expander (or IOX) chips we use two I²C bus ports to get 64 new digital (output) ports. The ports are easily controlled through a simple hardware abstraction on the master. This makes it transparent to the scheduler if the port is a physical Arduino port or an expanded/remote port on a MCP23017.

Master circuitry I/O expanders

We are currently using 2 x 16 of these extended ports for the glockenspiel, 1 x 16 ports for tubular bells, leaving 16 ports for future needs.

The outputs are made as simple pin rows, making it easy to attach ribbon cables with dupont connectors.

As will be discussed in the pages about the PipeDream24, PipeDream61 and PipeMare projects, we find many more uses for the MCP23017 I/O expanders.


First, a bit of physics: Our instruments are all based on physical actions by motors, servos, solenoids and such. This is a family of components called inductive devices, meaning they behave electrically more or less like an inductor (or a coil). They are wonderfully useful because they translate electric current into some kind of motion. But they do have a dark and terrible side. [Cue scary music]


While they are more than happy to move stuff when electrical current is flowing through them, they don’t take kindly to the same current suddenly stopping. Being essentially electromagnets, they build up a strong electromagnetic field when current flows through them. When the current stops, the inductor still has that stored magnetic energy to deal with, and it reacts by inducing a reverse voltage. Since the circuit is basically broken (usually a MOSFET entering its’ closed state), the induced current has nowhere to go, and the voltage spikes to potentially very high and damaging levels, even resulting in sparks, if nothing is done about it.

Now, this so-called fly-back current is relatively easily managed by placing an appropriate diode across the inductive device, making a circuitry path for the induced reverse current, preventing direct damage to components.


But even when the fly-back current is handled, these devices still generate a lot of E/M noise, and the heavier and more current-hungry components can even cause temporary voltage drops, so-called brown-outs, which is pure hell for a microcontroller environment.

A brown-out is when some part of a circuitry suddenly uses a very high current, making the power supply circuitry unable to keep up the nominal voltage levels. This is non-critical for simple components like solenoids or motors – in the worst-case scenario we may experience a transient lower pulling force in a solenoid or a motor running slower for some milliseconds. But a microcontroller is much more sensitive to sudden drops in supply voltage, and we can’t have our master microcontroller restart spontaneously while the music’s playing.

To prevent this we are operating with two different power domains: one for microcontrollers, communication and supporting circuitry (the A-side), and one for all the noisy, power-hungry inductive devices (the B-side). The point is, the two power domains are electrically isolated. Control signals from the microcontroller to the moving parts and their power drivers must cross this isolation barrier without risk of B-side noise or voltage fluctuations having any influence on the A-side circuitry.

There are basically two ways of communicating across a galvanic isolation (not counting the more exotic methods). These methods are called respectively optical and capacitive. We use both methods in different parts of the EnembleBot. However, in the master circuitry we only use optical isolation.


Optical isolation is done using a so-called optocoupler or opto-isolator, which essentially is an encapsulated LED as input end and a photosensitive transistor as output.

Basic non-inverting optocoupler

The small schematic here shows a basic wiring of a single non-inverting opto-isolated output port. D(out) is the TTL signal from an Arduino port, and D*(out) is the isolated non-inverted signal on the B-side. In this setup the optocoupler inverts the signal (low input gives high output and vice versa). The 74HC14 is a Schmitt-trigger, that both inverts the signal again and ensures a nice and clean high/low TTL level as shown on the oscilloscope image.

As long as you don’t need any high speed signals to pass the isolation barrier, these optocouplers are great and reliable. However, when using PWM signals at higher frequencies (maybe even from a few hundreds of Hz), some timing compensation for the falling edge (and thus the duty cycle) might be required.

24-channel optocoupler

The image to the right shows an array of 24 opto-isolated ports, currently only used for simple percussive instruments on, in and under the master cabinet.

As you can see in the schematic before, the input of an optocoupler is basically an LED, which needs at least 5-10mA to sufficiently activate the output. In a worst case scenario all ports are activated simultaneously, resulting in a current drain of 24 x 10mA = 250mA, which is too much for the Mega’s tiny voltage regulator to supply, and even the 5-10mA per port is too much, should we choose to upgrade the Arduino Mega to a 3.3V Arduino Due.

So, the inputs are buffered through darlington-coupled transistors (ULN2003A), making it possible to plug in this case 24 of the Arduino’s ports into the isolator array (A-side), and have perfectly synced output signals (B-side) without any crossover noise or risk of damaging power spikes/dips.

The 24 double-protected ports are currently used primarily for controlling the local percussion instrument drivers.

EnsembleBot isolation scheme

While the optocouplers are great for simple and relatively slow TTL signals, we sometimes do have the need to send more complex signals across the barier to the B-side domain. So far, we’ve only had to have I²C busses cross the barrier. I²C busses usually run at 400kHz or 1MHz, and this is too much for our simple and cheap optocouplers, not to mention the need for bi-directional bus lines.

I²C isolator

Fortunately, there are several devices that can help us. Texas ISO1540 and Analog Devices ADUM1250 are small (SOIC-8-N) chips that effectively isolates to power domains galvanically while permitting I²C communication. This is done with capacitive isolaton.

16-channel MOSFET drivers for electromagnet organ valves
16-channel MOSFET drivers for electromagnet organ valves

Much of the master circuitry were designed and built in the early stages of the project. All the many modules with MCP23017 I/O expanders, optocouplers and MOSFET drivers could easily have been replaced with the modular driver boards designed much later for the PipeMare project. Three of these boards stacked, combined with a single I²C isolator, could replace the huge, ugly driver board for both the Tubular Bells and the Glockenspiel.


As the EnsembleBot project grew, the demands for power grew as well. As mentioned above, we need two isolated power domains, but we also need a fine grained control and monitoring of the power usage and routing.

So in the end we built an immensely complicated power supply, containing no less than 5 switched mode power supply blocks, a dedicated microcontroller, tons of relays and switches and 24 individually controlled outputs.

A number of current sensors (INA219) constantly monitor and control the power usage on all power rails across both power domains, and may cut power to individual rails, if critical conditions arise.

This power supply is orders of magnitude more complicated than it actually needs to be, but it was just so much fun to design and build. But also quite challenging. To keep cost down, we used the cheapest Chinese components for switches, relays etc., and as we found out, there is a reason why these components were so cheap. But all in all it works fine does the job.

Next: Read about the Tubular bells

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.