Introduction: Midi Bass Pedal

This is my MIDI bass pedal. It plays MIDI notes or MIDI Control Change signals via USB, it has a transpose function and fully adjustable velocity.

It runs off a $5 Arduino Pro Micro and a 74HC4067 Multiplexer. So it's a cheap build..

Supplies

1x 74HC4067 Multiplexer

1x Arduino Pro Micro

4x Guitar footpedal switches

13x microswitches

17X 10k resistors

Some wood and some screws

Step 1: Planning and Ideas

The first step to building any big project is to solidify the ideas about what you want it to be able to do.

My journey to this pedal came from my previous project.

https://www.instructables.com/id/USB-Midi-Foot-Ped...

After some time, the Teensy 3.0 chip died and I did a little research into other ways of achieving the same thing without buying another $50 chip.


You can see that research here:

https://www.instructables.com/id/Arduino-Midi-Clas...

I had seen a few people make Midi pedals out of old organ pedals. I wanted to do the same, Organ pedals are actually pretty cheap and easy to get hold of, except, they usually come with a giant organ. I'm a bit of a parts hoarder, but I felt like maybe with my small shed, hoarding a whole organ might be a bit much.

So, I thought I would make one. I used Inkscape to explore the ideas and then I used Autodesk Fusion 360 to model the initial idea. You might notice that the initial idea has a heap of features that didn't make the final cut. Sometimes it's handy to start with the big dream and then narrow down to what is most important and what you can be bothered building. I figure that many of the other features can easily be added when needed, so I kept it simple. I have found that I don't miss them, so I saved a heap of work.

I narrowed it down to a few features:

1. I wanted to be able to plug it into any computer and have MIDI through the USB.
2. I wanted to be able to transpose it so that I could play along to my guitar with a capo and think in one key.
3. I wanted to have a full octave.
4. I wanted to have the ability to have it send midi control change signals as well as note signals and to switch easily.

5. I wanted it to be velocity sensitive.


I thought of a range of ways to get number 5, but instead chose to be able to vary the velocity at the push of a button so it could be changed quickly and easily, but was easy to code. I could use a single switch for each of the pedals and didn't need to figure out an elaborate way to do it. For me, this was the difference between starting the project and forever researching.

Step 2: Assembly

My choice of process is to do the build and then code around it. I knew that I was going to have 13 note switches and four footswitches. I was going to use an arduino pro micro, because it's cheap and easy to convert to a usb midi device and I was going to use a multiplexer to read all the inputs.

I decided to just drill all the pedals in the top corner, nail through that and mount a microswitch on the bottom corner, so stepping on the pedals clicks the switch. This works reasonably well, except that over time, the holes that the pedals are mounted through have developed a bit of play which means that on occasion, the pedal is too far forward to click the switch. I think that a hinge on top would work better, or just a bit more support and a slightly tighter fit.

I don't have much else to say about assembly, have a look at the pictures.
I routed a panel into the top of the pedal so that I could easily mount the footswitches in some thinner ply.

Step 3: Coding

If you don't know much about arduino and MIDI, please visit my other instructable:

https://www.instructables.com/id/Arduino-Midi-Clas...

Then you want to work out what you want to achieve.

I wanted to use a multiplexer, so I need a code for that.
I wanted to push a pedal and get the MIDI note associated, so I need a code for that.
I wanted to be able to step on a foot switch and transpose the note, so I need a code for that.
I wanted to be able to step on a foot switch and send control signals instead of notes, so I need a code for that.
I wanted to be able to step on a foot switch and decide on the velocity, so I need a code for that..

So... Some variables.

Transpose for transpose
Velocity for Velocity
And ModeState changes reads the switch for changing between notes and control change.

This means that main code remains the same, but I can change the variables to change the outputs.

I've also gone with a code that checks if the pedal has been pressed or unpressed and only sends the note on or off signal when it's changed. Otherwise you get thousands of MIDI on notes each time you press a button down. Some other codes tackle this by adding a delay. So you get one sustained note for each button press and it turns off after the delay. I don't like that though because it means you can't easily control the timing and you can't have multiple notes playing at once.


The full code is below:

/**

* For more about the interface of the library go to

* https://github.com/pAIgn10/MUX74HC4067

*/

#include "MUX74HC4067.h" // Creates a MUX74HC4067 instance

MUX74HC4067 mux(10,4,5,6,7); // 1st argument is the Arduino PIN to which the EN pin connects, 2nd-5th arguments are the Arduino PINs to which the S0-S3 pins connect

//Spaces to save the buttons int buttonState0 = 0; int buttonState1 = 0; int buttonState2 = 0; int buttonState3 = 0; int buttonState4 = 0; int buttonState5 = 0; int buttonState6 = 0; int buttonState7 = 0; int buttonState8 = 0; int buttonState9 = 0; int buttonState10 = 0; int buttonState11 = 0; int buttonState12 = 0;

//Debounce states int prevbuttonState0 = 0; int prevbuttonState1 = 0; int prevbuttonState2 = 0; int prevbuttonState3 = 0; int prevbuttonState4 = 0; int prevbuttonState5 = 0; int prevbuttonState6 = 0; int prevbuttonState7 = 0; int prevbuttonState8 = 0; int prevbuttonState9 = 0; int prevbuttonState10 = 0; int prevbuttonState11 = 0; int prevbuttonState12 = 0;

int footswitch1 = 2; int footswitch2 = 3; int footswitch3 = 20;

int Transpose = 0; int Mode = 0; int Velocity = 70;

int TransposeState = 0; int ModeState = 0; int LoopState = 0;

int prevModeState = 0; int prevLoopState = 0;

void setup()

{

Serial.begin(38400);

mux.signalPin(A3, INPUT, DIGITAL); // The SIG pin connects to PIN A3 on the Arduino,

pinMode(footswitch1, INPUT); pinMode(footswitch2, INPUT); pinMode(footswitch3, INPUT); }

void noteOn(byte channel, byte pitch, byte velocity) { MIDIEvent noteOn = {0x09, 0x90 | channel, pitch, velocity}; MIDIUSB.write(noteOn); }

void noteOff(byte channel, byte pitch, byte velocity) { MIDIEvent noteOff = {0x08, 0x80 | channel, pitch, velocity}; MIDIUSB.write(noteOff); } void ctrlChg(byte channel, byte pitch, byte velocity) { MIDIEvent ctrlChg = {0x08, 0xB0 | channel, pitch, velocity}; MIDIUSB.write(ctrlChg); } // Reads the 16 channels and reports on the serial monitor

// if the corresponding push button is pressed

void loop()

{ // read all the ports

TransposeState = digitalRead(footswitch1); ModeState = digitalRead(footswitch2); LoopState = digitalRead(footswitch3);

buttonState0 = mux.read(0); buttonState1 = mux.read(1); buttonState2 = mux.read(2); buttonState3 = mux.read(3); buttonState4 = mux.read(4); buttonState5 = mux.read(5); buttonState6 = mux.read(6); buttonState7 = mux.read(7); buttonState8 = mux.read(8); buttonState9 = mux.read(9); buttonState10 = mux.read(10); buttonState11 = mux.read(11); buttonState12 = mux.read(12);

// Setting the Transpose when the Transpose button is on. if (TransposeState == HIGH) { if (buttonState0 == HIGH) {Transpose = 0;} if (buttonState1 == HIGH) {Transpose = 1;} if (buttonState2 == HIGH) {Transpose = 2;} if (buttonState3 == HIGH) {Transpose = 3;} if (buttonState4 == HIGH) {Transpose = 4;} if (buttonState5 == HIGH) {Transpose = 5;} if (buttonState6 == HIGH) {Transpose = 6;} if (buttonState7 == HIGH) {Transpose = 7;} if (buttonState8 == HIGH) {Transpose = 8;} if (buttonState9 == HIGH) {Transpose = 9;} if (buttonState10 == HIGH) {Transpose = 10;} if (buttonState11 == HIGH) {Transpose = 11;} if (buttonState12 == HIGH) {Transpose = 12;} //C octave above delay(1000);}

// What should this button do? Velocity? if (LoopState == HIGH) { if (buttonState0 == HIGH) {Velocity = 10;} //Min Velocity if (buttonState1 == HIGH) {Velocity = 20;} if (buttonState2 == HIGH) {Velocity = 30;} if (buttonState3 == HIGH) {Velocity = 40;} if (buttonState4 == HIGH) {Velocity = 50;} if (buttonState5 == HIGH) {Velocity = 60;} if (buttonState6 == HIGH) {Velocity = 70;} if (buttonState7 == HIGH) {Velocity = 80;} if (buttonState8 == HIGH) {Velocity = 90;} if (buttonState9 == HIGH) {Velocity = 100;} if (buttonState10 == HIGH) {Velocity = 110;} if (buttonState11 == HIGH) {Velocity = 120;} if (buttonState12 == HIGH) {Velocity = 127;} //Max Velocity delay(1000);}

else //~~~~~~~~~~~~~~~~~~~~~~~~~ Notes Mode ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\\ if (ModeState == LOW ) { //notes if (buttonState0 == HIGH && prevbuttonState0 == LOW) {noteOn(0x91, 36+Transpose, Velocity); MIDIUSB.flush(); prevbuttonState0 = buttonState0; } if (buttonState0 == LOW && prevbuttonState0 ==HIGH) {noteOff(0x81, 36+Transpose, 0); MIDIUSB.flush(); prevbuttonState0 = buttonState0; } if (buttonState1 == HIGH && prevbuttonState1 == LOW) {noteOn(0x91, 37+Transpose, Velocity); MIDIUSB.flush(); prevbuttonState1 = buttonState1; } if (buttonState1 == LOW && prevbuttonState1 ==HIGH) {noteOff(0x81, 37+Transpose, 0); MIDIUSB.flush(); prevbuttonState1 = buttonState1; } if (buttonState2 == HIGH && prevbuttonState2 == LOW) {noteOn(0x91, 38+Transpose, Velocity); MIDIUSB.flush(); prevbuttonState2 = buttonState2; } if (buttonState2 == LOW && prevbuttonState2 ==HIGH) {noteOff(0x81, 38+Transpose, 0); MIDIUSB.flush(); prevbuttonState2 = buttonState2; } if (buttonState3 == HIGH && prevbuttonState3 == LOW) {noteOn(0x91, 39+Transpose, Velocity); MIDIUSB.flush(); prevbuttonState3 = buttonState3; } if (buttonState3 == LOW && prevbuttonState3 ==HIGH) {noteOff(0x81, 39+Transpose, 0); MIDIUSB.flush(); prevbuttonState3 = buttonState3; } if (buttonState4 == HIGH && prevbuttonState4 == LOW) {noteOn(0x91, 40+Transpose, Velocity); MIDIUSB.flush(); prevbuttonState4 = buttonState4; } if (buttonState4 == LOW && prevbuttonState4 ==HIGH) {noteOff(0x81, 40+Transpose, 0); MIDIUSB.flush(); prevbuttonState4 = buttonState4; } if (buttonState5 == HIGH && prevbuttonState5 == LOW) {noteOn(0x91, 41+Transpose, Velocity); MIDIUSB.flush(); prevbuttonState5 = buttonState5; } if (buttonState5 == LOW && prevbuttonState5 ==HIGH) {noteOff(0x81, 41+Transpose, 0); MIDIUSB.flush(); prevbuttonState5 = buttonState5; } if (buttonState6 == HIGH && prevbuttonState6 == LOW) {noteOn(0x91, 42+Transpose, Velocity); MIDIUSB.flush(); prevbuttonState6 = buttonState6; } if (buttonState6 == LOW && prevbuttonState6 ==HIGH) {noteOff(0x81, 42+Transpose, 0); MIDIUSB.flush(); prevbuttonState6 = buttonState6; } if (buttonState7 == HIGH && prevbuttonState7 == LOW) {noteOn(0x91, 43+Transpose, Velocity); MIDIUSB.flush(); prevbuttonState7 = buttonState7; } if (buttonState7 == LOW && prevbuttonState7 ==HIGH) {noteOff(0x81, 43+Transpose, 0); MIDIUSB.flush(); prevbuttonState7 = buttonState7; } if (buttonState8 == HIGH && prevbuttonState8 == LOW) {noteOn(0x91, 44+Transpose, Velocity); MIDIUSB.flush(); prevbuttonState8 = buttonState8; } if (buttonState8 == LOW && prevbuttonState8 ==HIGH) {noteOff(0x81, 44+Transpose, 0); MIDIUSB.flush(); prevbuttonState8 = buttonState8; } if (buttonState9 == HIGH && prevbuttonState9 == LOW) {noteOn(0x91, 45+Transpose, Velocity); MIDIUSB.flush(); prevbuttonState9 = buttonState9; } if (buttonState9 == LOW && prevbuttonState9 ==HIGH) {noteOff(0x81, 45+Transpose, 0); MIDIUSB.flush(); prevbuttonState9 = buttonState9; } if (buttonState10 == HIGH && prevbuttonState10 == LOW) {noteOn(0x91, 46+Transpose, Velocity); MIDIUSB.flush(); prevbuttonState10 = buttonState10; } if (buttonState10 == LOW && prevbuttonState10 ==HIGH) {noteOff(0x81, 46+Transpose, 0); MIDIUSB.flush(); prevbuttonState10 = buttonState10; } if (buttonState11 == HIGH && prevbuttonState11 == LOW) {noteOn(0x91, 47+Transpose, Velocity); MIDIUSB.flush(); prevbuttonState11 = buttonState11; } if (buttonState11 == LOW && prevbuttonState11 ==HIGH) {noteOff(0x81, 47+Transpose, 0); MIDIUSB.flush(); prevbuttonState11 = buttonState11; } if (buttonState12 == HIGH && prevbuttonState12 == LOW) {noteOn(0x91, 48+Transpose, Velocity); MIDIUSB.flush(); prevbuttonState12 = buttonState12; } if (buttonState12 == LOW && prevbuttonState12 ==HIGH) {noteOff(0x81, 48+Transpose, 0); MIDIUSB.flush(); prevbuttonState12 = buttonState12; } }

//~~~~~~~~~~~~~~~~~~~~~~~~~ Control Change Mode ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\\ if (ModeState == HIGH ) { //notes if (buttonState0 == HIGH && prevbuttonState0 == LOW) {ctrlChg(0xB2, 36+Transpose, Velocity); MIDIUSB.flush(); prevbuttonState0 = buttonState0; } if (buttonState0 == LOW && prevbuttonState0 ==HIGH) {ctrlChg(0xB2, 36+Transpose, 0); MIDIUSB.flush(); prevbuttonState0 = buttonState0; } if (buttonState1 == HIGH && prevbuttonState1 == LOW) {ctrlChg(0xB2, 37+Transpose, Velocity); MIDIUSB.flush(); prevbuttonState1 = buttonState1; } if (buttonState1 == LOW && prevbuttonState1 ==HIGH) {ctrlChg(0xB2, 37+Transpose, 0); MIDIUSB.flush(); prevbuttonState1 = buttonState1; } if (buttonState2 == HIGH && prevbuttonState2 == LOW) {ctrlChg(0xB2, 38+Transpose, Velocity); MIDIUSB.flush(); prevbuttonState2 = buttonState2; } if (buttonState2 == LOW && prevbuttonState2 ==HIGH) {ctrlChg(0xB2, 38+Transpose, 0); MIDIUSB.flush(); prevbuttonState2 = buttonState2; } if (buttonState3 == HIGH && prevbuttonState3 == LOW) {ctrlChg(0xB2, 39+Transpose, Velocity); MIDIUSB.flush(); prevbuttonState3 = buttonState3; } if (buttonState3 == LOW && prevbuttonState3 ==HIGH) {ctrlChg(0xB2, 39+Transpose, 0); MIDIUSB.flush(); prevbuttonState3 = buttonState3; } if (buttonState4 == HIGH && prevbuttonState4 == LOW) {ctrlChg(0xB2, 40+Transpose, Velocity); MIDIUSB.flush(); prevbuttonState4 = buttonState4; } if (buttonState4 == LOW && prevbuttonState4 ==HIGH) {ctrlChg(0xB2, 40+Transpose, 0); MIDIUSB.flush(); prevbuttonState4 = buttonState4; } if (buttonState5 == HIGH && prevbuttonState5 == LOW) {ctrlChg(0xB2, 41+Transpose, Velocity); MIDIUSB.flush(); prevbuttonState5 = buttonState5; } if (buttonState5 == LOW && prevbuttonState5 ==HIGH) {ctrlChg(0xB2, 41+Transpose, 0); MIDIUSB.flush(); prevbuttonState5 = buttonState5; } if (buttonState6 == HIGH && prevbuttonState6 == LOW) {ctrlChg(0xB2, 42+Transpose, Velocity); MIDIUSB.flush(); prevbuttonState6 = buttonState6; } if (buttonState6 == LOW && prevbuttonState6 ==HIGH) {ctrlChg(0xB2, 42+Transpose, 0); MIDIUSB.flush(); prevbuttonState6 = buttonState6; } if (buttonState7 == HIGH && prevbuttonState7 == LOW) {ctrlChg(0xB2, 43+Transpose, Velocity); MIDIUSB.flush(); prevbuttonState7 = buttonState7; } if (buttonState7 == LOW && prevbuttonState7 ==HIGH) {ctrlChg(0xB2, 43+Transpose, 0); MIDIUSB.flush(); prevbuttonState7 = buttonState7; } if (buttonState8 == HIGH && prevbuttonState8 == LOW) {ctrlChg(0xB2, 44+Transpose, Velocity); MIDIUSB.flush(); prevbuttonState8 = buttonState8; } if (buttonState8 == LOW && prevbuttonState8 ==HIGH) {ctrlChg(0xB2, 44+Transpose, 0); MIDIUSB.flush(); prevbuttonState8 = buttonState8; } if (buttonState9 == HIGH && prevbuttonState9 == LOW) {ctrlChg(0xB2, 45+Transpose, Velocity); MIDIUSB.flush(); prevbuttonState9 = buttonState9; } if (buttonState9 == LOW && prevbuttonState9 ==HIGH) {ctrlChg(0xB2, 45+Transpose, 0); MIDIUSB.flush(); prevbuttonState9 = buttonState9; } if (buttonState10 == HIGH && prevbuttonState10 == LOW) {ctrlChg(0xB2, 46+Transpose, Velocity); MIDIUSB.flush(); prevbuttonState10 = buttonState10; } if (buttonState10 == LOW && prevbuttonState10 ==HIGH) {ctrlChg(0xB2, 46+Transpose, 0); MIDIUSB.flush(); prevbuttonState10 = buttonState10; } if (buttonState11 == HIGH && prevbuttonState11 == LOW) {ctrlChg(0xB2, 47+Transpose, Velocity); MIDIUSB.flush(); prevbuttonState11 = buttonState11; } if (buttonState11 == LOW && prevbuttonState11 ==HIGH) {ctrlChg(0xB2, 47+Transpose, 0); MIDIUSB.flush(); prevbuttonState11 = buttonState11; } if (buttonState12 == HIGH && prevbuttonState12 == LOW) {ctrlChg(0xB2, 48+Transpose, Velocity); MIDIUSB.flush(); prevbuttonState12 = buttonState12; } if (buttonState12 == LOW && prevbuttonState12 ==HIGH) {ctrlChg(0xB2, 48+Transpose, 0); MIDIUSB.flush(); prevbuttonState12 = buttonState12; } }

}

Instrument Contest

Participated in the
Instrument Contest