Midi Bass Pedal

5.4K4816

Intro: 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..

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; } }

}

14 Comments

Hola buenas! Saludos desde España.
Quiero aprender a conectar 16 botones al 74hc4067, y recibir la señal al arduino. Cada botón quiero que haga un sonido en un buzzer. ¿Cómo se puede hacer? Gracias de antemano!
Thanks,
I’m not sure that I can tell you how to do it, but it is possible. First find a code for reading the inputs in the multiplexer, then find a code for the buzzer. Then put them together. Try do a code to read all the switches and use serial.print(nameofinput); to test it. Then try do a button outputting the buzzer sound… copy and paste it until you have all the input working.
You can do audio out with wav files on an SD card through speakers too.
I would really like to make the Midi Bass Pedal but I need a schematic to know how to wire it. Is one available, please.
Its many years since I soldered my own circuit boards so your advice was much appreciated while I am finding my way with Arduino. I am now 91yo and hope I have time to finish my project.
I didn’t make one for it, but it’s very similar to this..https://arduinoproyek.wordpress.com/2019/04/27/multi-analog-read-by-mux74hc4067/
The only difference is that I use buttons instead of pots... So it looks a bit more like this, https://www.arduino.cc/en/tutorial/button, but with the button going to the multiplexer instead of to the arduino.
Just check the code for the right digital pins or update the code based on where you wire it, because they are using different arduino boards, then the one that I used.

The footswitches on the top aren’t through the multiplexer... they just go directly to the Arduino board. Arduino button tutorial good for that. I put an LED running off the power when the switch is on so that I can see when the switches are on.

I would do it in stages.. ie. try to get one button to say “hello world” in the serial monitor or something first. Then wire up a few other ones, try those.

Then go through the multiplexer.

I also made it harder for myself by being cheap... you can buy boards designed to handle more buttons and then it’s super easy.

If you just go straight from no experimenting or knowledge to the whole project without learning a few steps in between, it will be a real nightmare trying to figure out why it doesn’t work if something isn’t quite right.

You kinda have to just start small and work your way up. Then you know how to add features and make the exact pedal board that you want. I just bought some Bluetooth modules to add to mine... Have no idea how to use them, but I’ll just google tutorials until I can find something fit for purpose.

The main handy bits from my instructable are all the sneaky ways I added tweaks for velocity and transposing into the midi code. Everything else is pretty standard...
How hard would it be to add a standard MIDI out connector? Certainly would streamline things for me.
I always have to wonder why opt for USB, when standard MIDI eliminates the need for a host? I could go directly to my MIDI rack instead of needing a PC. That's one less piece of gear I need on stage.
I just do it because I already have a laptop, and no rack gear. It’s easier for me to jam that way.
I’m actually going to add Bluetooth so I can connect straight to my phone and muck around with it.
Bluetooth is a cool concept, but another added layer of latency. I have known a few who have tried bluetooth for stage monitoring, and gave it up because of the latency.
Yea, I’m a bit worried about that too, I’ll probably add a mode switch so it’s only doing Bluetooth when it’s on Bluetooth mode, and doesn’t interfere with the current performance on USB, but I haven’t looked too hard into it just yet. Still waiting on chips to arrive from China and then I’ll have a play.
Certainly Bluetooth audio is too slow for musical applications.
I have a wifi chip too, but I’ve not got it working yet.
You are one smart guy. I really like your invention.
Neat! There's some really nice shaping in the woodwork. Thank you for sharing :-)