How It Works
The simple and boring answer is that its all done in code, and you can take a look at that right here on GitHub. However you probably want to know about the electronics right, what is all that stuff on the board? Hopefully this little description might help you turn your curiosity into understanding and might inspire you to make your own projects
First of all, like I say, LE STRUM’s functionality is done in code - its a computer program. So, where is the computer? Well… see IC1, the little black box next to the MIDI socket, thats a computer! No really, its a Microcontroller, which is a complete computer on a chip. With its 8 bit CPU running at 8MHz, 1K of RAM and 14K of flash memory its actually more powerful than a lot of 1980s home computers! This one happens to be a PIC16F1825 but there are literally thousands of different types of microcontrollers with different specifications running everything from Smartphones to Toasters
How does the program get on the microcontroller? well - it was already loaded on there when I sent out the kit, so don’t worry about that. The program is stored in the flash memory, which keeps its data when the power is off. You’d only need to worry about putting programs on the microcontroller if you ever wanted to change or upgrade the program later. Microcontroller programs are called “firmware” (like they are a bit “firmer” than “soft”ware but not quite as hard as “hard”ware - Engineers, eh?) and the programming process is often called “burning” the firmware (there is a historical reason for this, once upon a time the programming process did physically and permanently “burn” data into the chip, though these days re-writable flash memory is normally used instead)
So our little PIC microcontroller might have more power than an old school home computer, but where the computer wins is user-interface. Our microcontroller has no keyboard, no screen, no sound.. In fact all it has are a few connector pins that it can use to talk to the outside world. The little PIC on LE STRUM has just 14 pins (connections) of which two are used for power. The other pins can only be switched on and off by the firmware, or be used to read an input voltage or signal from the outside world. That sounds pretty limiting! so how can the remaining 12 pins be used to check 36 switches, 16 pads, control an LED and send MIDI?
Well, that’s where all the other components come in, together with some little electronics tricks. First lets look at the 36 switches that are used to control the chord that is playing. Of course we could read 36 switches using a microcontroller with 36 input pins, but that would be incredibly wasteful of inputs, besides which we don’t have 36 pins available!
A more efficient way is to make a keyboard “matrix” by connecting the switches into rows and columns. LE STRUM uses 12 columns and 3 rows (the switches are connected as they are laid out). Now we could, for example detect that the switch on column 5, row 2 is pressed because we would see an electrical connection made between column connection 5 and row connection 2.
With 15 wires (12 columns, 3 rows) we could read 36 buttons. We would need to create a firmware routine that can “scan” the matrix by perhaps switching the columns ON one at a time and reading back from the three rows. using 12 outputs and 3 inputs we can read the 36 button matrix, so this is already quite a lot better than using 36 inputs! (in fact if we were using this type of approach, a 6x6 matrix with 12 pins - 6 output and 6 inputs would be most efficient)
However, that approach is still using more pins that we have spare, and still a pretty inefficient use of input/output pins. To improve things again we will add some extra components called “shift registers”. There are two of these on LE STRUM - they are the little black boxes below the strum pad.
To explain what a shift register does, lets imagine we have a type of display where black or white billiard balls show through a row of 8 little windows. We can show specific patterns of black and white windows by placing the balls behind the windows - lets assume we want to convey some information this way. Two methods we might use for assembling the sequence of 8 balls are - load all 8 balls directly into position by placing each ball directly behind its window - load the balls one at a time by inserting them behind the first window, shoving all the others up one position to the next window, until all 8 are in the correct place
The first method is obviously simpler, but it needs direct access to all 8 window positions. In electronics terms this would be a “parallel load”. If we talk about electrical ON and OFF values instead of coloured balls, and we think about setting them up from a microcontrollers, we would need 8 separate connections/pins to do this (Real components that work like this - for example a “line driver/buffer” - usually need additional connections to “latch” the new values and “reset” them)
The second method is a “serial load”. It takes more work and more time, but it is much more efficient in terms of the number of pins we need to drive this. At a minimum we just need one pin for “Serial Data” (i.e. the colour of the next ball) and another pin for “Clock” (we pulse this pin to do the “shove” of the values). With just these two pins we can load up all 8 windows.
What I just described is the action of a “serial in, parallel out shift register” chip like the 74HC595s which are used on LE STRUM. These chips can be connected in a chain so the “overflow” (i.e. the ball which drops off the end of a full row when a new one is inserted) can be fed into the input of the next register. All shift registers in a chain can share the same clock, so with just 2 pins we can actually load any number of outputs! The downside of a serial load is that it takes 8 times longer than the equivalent parallel load, but these chips can run very fast indeed, up to tens of millions of clock cycles/”shoves” a second!
So back to our keyboard matrix… using a chain of two shift registers we can control 16 outputs. The first 12 outputs are fed to the 12 columns of our keyboard matrix and we can “scan” the matrix by moving a single ON value along the shift registers (i.e. one white ball is shoved along to each position). This ON value starts in the first column of switches, we read back from the three rows and we know if any of the switches in this column are pressed. Then we shove the ON value to column 2, read again, and so on. So now we can read 36 switches uses just 5 pins (2 outputs, 3 inputs)
What about the stylus pads? there are 16 of those… assuming we will scan the pads like the keyboard (i.e. read back from the stylus) do we need to use another pair of shift registers? Well, no actually, we use the same ones! The stylus is effectively a fourth row of the keyboard matrix. So when our ON value is connected to keypad column 1, it is also connected to strum pad 1. Just like we can read back rows 1-3 of the switches, we can read back from the stylus to see if it is touching pad 1.
The pair of shift registers gives a total 16 outputs, which are used for the 16 pads. The first 12 outputs are shared with the keyboard matrix. Now with 6 pins (2 outputs, 4 inputs) we are reading 36 switches and 16 pads!
Now, there are a couple of things we need to think about here… firstly the input pins of a microcontroller are very sensitive. It might surprise you that when nothing is connected to an input pin, it is not necessarily OFF (more correctly we say “LOW”). In fact the input pin might actually read ON (“HIGH”) due to stray electrical noise and fields. When a pin is unconnected to anything we say is is “floating”. This state can be great for generating randomness, but it is best avoided when you are doing something like scanning a keyboard matrix.
However, when no keys are pressed on our matrix, the input lines are all “floating” and could read random noise. We can fix this by adding a high value resistor to “pull” the input to a known HIGH or LOW value when it is otherwise floating. Because the resistor has a high value (usually tens of thousands of ohms) this HIGH or LOW value is “weakly” held and is easily overcome when a “real” input comes in. It is most common to tie floating lines HIGH via a “pull-up resistor” and have them pulled low when an input comes in, however due to our matrix scanning approach, we will instead use “pull-down resistors” on LE STRUM. These are 10,000 ohm resistances which the HIGH pulse from the shift register outputs can easily overcome, but which will hold our input lines LOW at other times, preventing garbage readings from electrical noise etc.
One other thing we need to think about is what happens if two switches in one row are pressed together, or the stylus bridges two pads at the same time. In this situation the HIGH output from the shift register would be directly connected to other LOW outputs on the same/other shift register on each scan. This is bad news… it is a “short circuit” situation where a current can flow between two shift register pins and potentially damage them. In order to prevent problems due to these situations LE STRUM protects each shift register output with a diode. These components only let current flow in one direction - in this case “out” of the pin. The diodes block a flow of current from a HIGH shift register pin to a LOW one when the keyboard matrix or stylus is shorting them together.
So now we can scan all of our inputs using minimal input/output pins and a few external components, but what about all that complicated MIDI stuff? Well that is actually pretty simple! MIDI is just a “serial protocol” which means its a bunch of special messages sent down a wire as 1’s and 0’s at a standard rate. MIDI runs at 31250 bits every second (31.25 kBaud). We can send MIDI message just by turning one of our microcontroller pins on and off at the correct pattern and speed!
Even better, our microntroller has a special built-in feature that can take over this pin switching for us. This feature is called a “universal asynchronous transmitter/receiver” (UART for short) and it really does make our job easier. By setting the UART to the correct bit rate we can just start sending out the MIDI messages. If you want to know how MIDI messages are structured, there are web sites that will explain it much better than I can, but basically LE STRUM sends out MIDI “note on” and “note off” messages based on what you do with the keyboard matrix and pads.
This leaves us with a couple of spare input/output pins for directly attaching the activity LED and the MODE switch, and there you have it. The rest is down to the computer program that makes up LE STRUM’s firmware. What did I tell you.