In 2013 I got an idea to make a USB MIDI pedalboard at home, just with simple electronic and household parts, costing around $40, including all electronic and mechanical parts. You might guess that there is some trade-off here, as just the wooden material should cost around $500 for a real pedalboard. Well, take a look at my first prototype:
The trick is capacitive sensing, driving the pedals just by touching. So you need to be in socks or bare feet, and clearly some stuff would be harder or different than on a normal pedalboard, but still is a great aid in learning hand-foot independence, sharing our attention, practice harder parts, the footing, or just to play the organ at home for fun. (Most of my interest goes anyway to casual music players, not for professionals.)
My (beginner) experience is that before performing in the church, one should practice 1-2 hours on site, to get accomodated to the differences. Though this is nothing special, there are virtually no two organs with the same sizes and controls, so unless you are quite experienced, you need that extra practice time anyway.
On the video above you can see, that the "mechanical" part consits of plain household aluminum foil.
So for the full project you'll need the following parts (some of these are best to order from some Chinese gadget shop, so you'll probably need 3-6 weeks to get everything).
From a household/diy shop:
- aluminum foil
- paper glue
- paper glue
- duct tape
- 20 A4/letter paper
- 150cm polyfoam or similar insulator
From an electronics shop:
From an electronics shop:
- 60m cheap insulated wire
- 32 pieces of alligator clips
- 4 pieces of CD4021 IC
- 32 pieces of 680kOhm resistor
- Terminal block for 32 points (spring or screw based, doesn't matter)
- 10kOhm linear potentiometer
Electroincs shop or China (e.g. dx.com):
- Terminal block for 32 points (spring or screw based, doesn't matter)
- 10kOhm linear potentiometer
Electroincs shop or China (e.g. dx.com):
- breadboard (either 1260 point solderless or a cca. 10x20 cm solderable)
- jumper cables for the breadboard
Tools:
- scissors
- soldering station (with a solderless breadboard you don't necessarily need it)
- multimeter (not a big deal, if you don't have one, just without it harder to find possible errors in building.)
- multimeter (not a big deal, if you don't have one, just without it harder to find possible errors in building.)
You will need a computer, which can run http://www.hauptwerk.com/ organ sampler (but I guess you have one anyway, as this is only the pedal, and you'll probably need 2 more MIDI keyboards as manuals). Also the computer is needed for programming the Arduino.
Let's see what to do.
Let's see what to do.
Electronics
Arduino is the most popular "brain" in DIY hobby electronics - it is a microcontroller, ie. something like a very small computer, which is cheap, small and directly can handle electronics components. There is an official store for officially produced Arduinos, but you can find some cheaper clones as well - mostly they do as well (though I have one clone failed from the 3. The original official one still works perfectly.)
Arduino UNO R3 version is usable for our goals, with some extra electronics we can connect 32 capacitive touch sensors and then upload a program which will turn the Arduino UNO R3 into a MIDI pedalboard with USB output.
When you're building the electronics, it's quite important to do it step by step and always check your work, check the solderings, whether every connection is looking good, there are no shortcuts etc.
When you buy an Arduion the software inside it blinks the small LED. As a first step I recommend uploading our pedalboard software to let us check its working during build.
Programming
Programming our microcontroller take two parts. First, you need to upload a program to the central unit (the atmega328 microntroller), then upload the USB-controller program (changing the firmware in the atmega16u2 chip on the Arduino board) - this will transform the Arduino from a programmable device into a USB musical instrument.
Programming the central unit
Download the microcontroller software from here: organ_pedal.cpp.hex
Using http://www.hobbytronics.co.uk/arduino-xloader you can upload it onto the Arduino (assuming you've already got the drivers, for Windows you can download it from http://arduino.cc/en/guide/windows#toc4).
Programming the USB controller
Somewhat complicated, and I recommend doing this when building the electronics is mostly done, to let us check that the central unit's programming is already done correctly. We'll use HIDUINIO: https://github.com/ddiakopoulos/hiduino/blob/master/Compiled%20Firmwares/HIDUINO_MIDI.hex
For details see: http://bartruffle.blogspot.hu/2013/09/dfu-programming-atmega16u2-on-arduino.html
For details see: http://bartruffle.blogspot.hu/2013/09/dfu-programming-atmega16u2-on-arduino.html
Circuit
I'm not going to show you a big schematic here, but instead a breadboard view for 8 keys. For 32 keys it is straightforward to expand.Not the most beautiful drawing, the point is to show every connection points. Indeed, this is a very simple circuit, just having quite a lot of wires. In real life you don't need so much place (as you can get the resistors standing e.g.), you should not need more than 2 big or 4 small breadboards.
You can see the following in the picture:
- CD4021 IC, having 16 pins. 8 pins are connected to the pedal notes themselves, the purple wires show that going to the terminal then to the notes (the foils) themselves.
- Upper left pin (no. 16) goes to 5V input (+), a lower right (8) goes to the ground (-)
- The IC pins assigned as the following:
- Highest note (G, on 2nd IC D#, on 3rd B, on the 4th G again)
- not connected
- Goes back to the Arduino - lowest notes to pin 7, then 6, 5 and 4 respectively.
- Lowest note (C)
- C#
- D
- D#
- Ground
- Control signal from Arduino pin 8
- Clock signal from Arduino pin 9
- Ground
- not connected
- E
- F
- F#
- Variable resistor (aka potentiometer): 3 pins, side pins go to 5V and ground, middle pin goes to A0 of Arduino. This resistor will set the sensitivity of the capacitive sensors.
- Arduino 5V, GND etc. is connected according to the picture
- While you have only one CD4021, testing the first 8 notes, the inactive inputs, pins 6,5 and 4 on Arduino should be connected to the high signal level, ie. 5V
When everything is connected we can power up the Arduino using the USB cable from the computer. The computer should be connected to the wall socket (to provide some consistent grounding, otherwise there could be problems with sensitivity).
After some blinking the "ON" LED should light up on Arduino, but the L LED should not.
If everything is correct by this time, we can try the electronics with some metal (a piece of wire, a knife etc.) - touch the terminals and the L LED should light up while touching. (Make sure your body, your skin is connected to the terminal via the wire, as you body will act as the capacitor.)
Soldered on a breadboard. |
Testing MIDI output
When also the USB programming is done, our computer should recognize the electronics as "HIDUINO". Starting Hauptwerk you should be able to make real sound using by touching the terminals.
The hard part is done, now let's do the "paperwork".
The hard part is done, now let's do the "paperwork".
The physical pedalboard
Pedalboard template
I've created a template that you can print on simple A4/letter papers. Then you just print it glue it with duct tape and can just glue the aluminium foil strips. HERE you can download it. Two white pedals should be 63.5 mm (2.5 inches) from each other (measure at the bottom of the black keys).
My original pedalboard was linear, not curved, but you can do whatever you like. I think because of playing without shoes and just touching, not pressing, the radial pedalboard template is more practical.
You don't have to be very very very precise, your feet will be quite big relative to the pedal size, and also every pedalboards differ a bit in size anyway.
You don't have to be very very very precise, your feet will be quite big relative to the pedal size, and also every pedalboards differ a bit in size anyway.
Keys (pedals)
Unfortunately aluminium foil tears easily, but hard to cut with scissors, my recommendation is to cut a sized paper template, draw the border line on the aluminium foil, and then you can easily fold and cut it. You'll need 19 pieces of long and 13 pieces of short keys.During preparation. In the middle of the picture the key template and the cutting appliance. |
Pedalboard base
2 more layers needed, the first is a polyfoam layer which will make the paper more stable and give some sense of pressure.
Wiring the keys
Take appropriate length of wires, solder onto the alligator clips, and connect them to the respective notes - white notes will have the clip at the bottom, black notes at the top. Lead the wires under the polyfoam. (Don't lead neighboring wires very close to each other, otherwise they will sound together in some cases).
Grounding
To make the electronics work really stable, under the polyfoam or under yourself (that is you should sit on it) take a big aluminium foil plane and connect it to the GND of the Arduino.
After this you can start playing, given you can sit comfortably. A little help for this:
Extra: organ bench
Just for some inspiration:
The respective Sketchup model can be downloaded here, you can see the measurements there. This bench is special, because you can change the bench height.
When you're ready, you can have something like this (or something much more beautiful):
The 1st keyboard is a 25 years old Yamaha, that's why it's yellowish. |
If you create this, and want to discuss, just comment!
Extra 2: MIDI electronics for a normal pedalboard
The same electronics and microcontroller software can be used for normal MIDI pedalboard electronics as well. Just use switches that connect CD4021 to the ground at the note pins. Parallel to the switch you need a 10kOhm pullup resistor (connecting to 5V). Pushing the switch will push the note's voltage to 0 (ground) and that will mean the pushed state.
Source code of pedal program:
#include <MIDI.h> #include "pitches.h" #include <wiring_digital.c> #define _DEBUG 0 /** The time to wait after putting a LOW level on the input lines. In us. */ const int SIGNAL_CHANGE_DELAY = 500; /** the level of the shift registers normally, when there is no test signal, no input etc. */ int clearLevel = LOW; /** the level of the test signal - we are waiting for this to appear on the shift registers. */ int testSignalLevel = 1-clearLevel; const byte LED = 13; const byte BUZZER = 12; /** This is the signal which is input to the shift register P pins through a resistor and a capacitor. */ const byte TEST_SIGNAL_OUT = 10; volatile uint8_t *testSignalOutReg; uint8_t testSignalOutBitMask; /** Connected to pin 10 of the shift registers. */ const byte SHIFT_CLOCK = 9; /** Connected to pin 9 of the shift registers. */ const byte SHIFT_CONTROL = 8; /** MIDI Output pin */ const byte TX = 1; const byte THRESHOLD_SETTING = A0; /** Number of shift registers */ const byte nOfRegs = 4; /** These are the inputs where the shift registers writes the values serially. These should be connected to Q8 of the shift registers. */ byte fromShiftReg[] = { 7, 6, 5, 4 }; byte incoming[nOfRegs]; int noOfSamples = 100; int maxWait = 1; const int DEFAULT_THRESHOLD = 0; int capacityThreshold = DEFAULT_THRESHOLD; /** The frequencies of sounds played on the buzzer when pressed the keys. */ int freqs[] = { NOTE_C2, NOTE_CS2, NOTE_D2, NOTE_DS2, NOTE_E2, NOTE_F2, NOTE_FS2, NOTE_G2, NOTE_GS2, NOTE_A2, NOTE_AS2, NOTE_B2, NOTE_C3, NOTE_CS3, NOTE_D3, NOTE_DS3, NOTE_E3, NOTE_F3, NOTE_FS3, NOTE_G3, NOTE_GS3, NOTE_A3, NOTE_AS3, NOTE_B3, NOTE_C4, NOTE_CS4, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_F4, NOTE_FS4, NOTE_G4 }; const byte lowestMidiNote = 36; byte velocity = 127; byte midiChannel = 1; /** This array stores which keys are pressed. The value corresponds to the capacity measured at the given key. */ int keys[8 * nOfRegs]; boolean soundingNotes[8 * nOfRegs]; void initMidi() { MIDI.begin(); } void initDebug() { Serial.begin(9600); } void initPins() { for (int i = 0; i < nOfRegs; i++) { pinMode(fromShiftReg[i], INPUT); uint8_t timer = digitalPinToTimer(fromShiftReg[i]); if (timer != NOT_ON_TIMER) turnOffPWM(timer); } pinMode(TEST_SIGNAL_OUT, OUTPUT); pinMode(SHIFT_CLOCK, OUTPUT); pinMode(SHIFT_CONTROL, OUTPUT); pinMode(BUZZER, OUTPUT); pinMode(THRESHOLD_SETTING, INPUT); pinMode(LED, OUTPUT); pinMode(TX, OUTPUT); } void setup() { #if _DEBUG initDebug(); #else initMidi(); #endif initPins(); digitalWrite(LED, LOW); } void dw(int pin, int val) { uint8_t bit = digitalPinToBitMask(pin); uint8_t port = digitalPinToPort(pin); volatile uint8_t *out = portOutputRegister(port); uint8_t oldSREG = SREG; cli(); if (val == LOW) { *out &= ~bit; } else { *out |= bit; } SREG = oldSREG; } int dr(uint8_t pin) { uint8_t bit = digitalPinToBitMask(pin); uint8_t port = digitalPinToPort(pin); if (*portInputRegister(port) & bit) return HIGH; return LOW; } void loadShiftRegisters(int level) { dw(TEST_SIGNAL_OUT, level); dw(SHIFT_CONTROL, HIGH); } void zeroKeyCapacities() { for (int i = 0; i < sizeof(keys)/sizeof(int); i++) { keys[i] = 0; } } void parallelShiftIn() { for (int reg = 0; reg < nOfRegs; reg++) { incoming[reg] = 0; } for (int i = 0; i < 8; ++i) { dw(SHIFT_CLOCK, HIGH); for (int reg = 0; reg < nOfRegs; reg++) { incoming[reg] |= dr(fromShiftReg[reg]) << i; } dw(SHIFT_CLOCK, LOW); } } void measureTime() { int total = 0; while (total < maxWait) { dw(SHIFT_CONTROL, HIGH); // try to jam in the test signal dw(SHIFT_CLOCK, HIGH); dw(SHIFT_CONTROL, LOW); // it seems that with this P8 is already at Q8, so clock must be already high at this point parallelShiftIn(); // at this point incoming contains the values from the shift registers // if one value is still at the clear level, we increase the corresponding "key" count for (byte reg = 0; reg < nOfRegs; reg++) { for (byte i = 0; i < 8; i++) { if ((incoming[reg] & (1 << i)) == clearLevel) { keys[8 * reg + i] ++; } } } total ++; } } void doMidiNotes() { boolean hasNote = false; for (int i = 0; i<sizeof(keys)/sizeof(int); i++) { int note = lowestMidiNote + i; if (keys[i] > capacityThreshold) { #if _DEBUG Serial.println(String("Capacity of note ")+i+": "+keys[i]); #endif if (!soundingNotes[i]) { soundingNotes[i] = true; #if !_DEBUG MIDI.sendNoteOn(note, velocity, midiChannel); #else Serial.print(0b1000, HEX); Serial.print(midiChannel, HEX); Serial.print(note, HEX); tone(BUZZER, freqs[note-lowestMidiNote]); #endif } hasNote = true; } else { if (soundingNotes[i]) { // todo might need to filter fast note off after a note on, e.g. by checking the time of the last note on #if !_DEBUG // for compatibility with Ebay-cheap MIDI-USB gear send note on with zero velocity MIDI.sendNoteOn(note, 0, midiChannel); #else Serial.print("NoteOff "); Serial.println(note, DEC); #endif soundingNotes[i] = false; } } } if (hasNote) { dw(LED, HIGH); } else { #if _DEBUG noTone(BUZZER); #endif dw(LED, LOW); } } void updateThresholdSetting() { int newValue = constrain(map(analogRead(THRESHOLD_SETTING), 100, 1023, 0, 100), 0, 100); #if _DEBUG if (newValue != capacityThreshold) { Serial.print("new capacity threshold: "); Serial.println(newValue, DEC); } #endif capacityThreshold = newValue; } void loop() { zeroKeyCapacities(); updateThresholdSetting(); for (byte sample = 0; sample < noOfSamples; sample++) { // clear the shift registers loadShiftRegisters(clearLevel); delayMicroseconds(SIGNAL_CHANGE_DELAY); // try to jam the test signal level in the shift registers loadShiftRegisters(testSignalLevel); measureTime(); } doMidiNotes(); }
pitches.h
/************************************************* * Public Constants *************************************************/ #define NOTE_B0 31 #define NOTE_C1 33 #define NOTE_CS1 35 #define NOTE_D1 37 #define NOTE_DS1 39 #define NOTE_E1 41 #define NOTE_F1 44 #define NOTE_FS1 46 #define NOTE_G1 49 #define NOTE_GS1 52 #define NOTE_A1 55 #define NOTE_AS1 58 #define NOTE_B1 62 #define NOTE_C2 65 #define NOTE_CS2 69 #define NOTE_D2 73 #define NOTE_DS2 78 #define NOTE_E2 82 #define NOTE_F2 87 #define NOTE_FS2 93 #define NOTE_G2 98 #define NOTE_GS2 104 #define NOTE_A2 110 #define NOTE_AS2 117 #define NOTE_B2 123 #define NOTE_C3 131 #define NOTE_CS3 139 #define NOTE_D3 147 #define NOTE_DS3 156 #define NOTE_E3 165 #define NOTE_F3 175 #define NOTE_FS3 185 #define NOTE_G3 196 #define NOTE_GS3 208 #define NOTE_A3 220 #define NOTE_AS3 233 #define NOTE_B3 247 #define NOTE_C4 262 #define NOTE_CS4 277 #define NOTE_D4 294 #define NOTE_DS4 311 #define NOTE_E4 330 #define NOTE_F4 349 #define NOTE_FS4 370 #define NOTE_G4 392 #define NOTE_GS4 415 #define NOTE_A4 440 #define NOTE_AS4 466 #define NOTE_B4 494 #define NOTE_C5 523 #define NOTE_CS5 554 #define NOTE_D5 587 #define NOTE_DS5 622 #define NOTE_E5 659 #define NOTE_F5 698 #define NOTE_FS5 740 #define NOTE_G5 784 #define NOTE_GS5 831 #define NOTE_A5 880 #define NOTE_AS5 932 #define NOTE_B5 988 #define NOTE_C6 1047 #define NOTE_CS6 1109 #define NOTE_D6 1175 #define NOTE_DS6 1245 #define NOTE_E6 1319 #define NOTE_F6 1397 #define NOTE_FS6 1480 #define NOTE_G6 1568 #define NOTE_GS6 1661 #define NOTE_A6 1760 #define NOTE_AS6 1865 #define NOTE_B6 1976 #define NOTE_C7 2093 #define NOTE_CS7 2217 #define NOTE_D7 2349 #define NOTE_DS7 2489 #define NOTE_E7 2637 #define NOTE_F7 2794 #define NOTE_FS7 2960 #define NOTE_G7 3136 #define NOTE_GS7 3322 #define NOTE_A7 3520 #define NOTE_AS7 3729 #define NOTE_B7 3951 #define NOTE_C8 4186 #define NOTE_CS8 4435 #define NOTE_D8 4699 #define NOTE_DS8 4978
(c) Bertalan Fodor, 2014, All rights reserved