Bass Pedal MIDI Controller Video

I’ve put together a short video showing the Bass Pedal project in its current state. Enjoy.

The next step will be to add voice control, so that I can shift it form the default piano voice and perhaps an LCD display panel showing the currently selected options. This could display the current octave, transpose setting, voice and volume.

Multi Button MIDI

I’ve now mixed the single button MIDI code with the I2C code to create a Multi Button MIDI. This is just the starting point but it works perfectly. Using the same board layout as the earlier post, upload this sketch and you’ll have sixteen inputs for your MIDI device, perfect for wiring into your Bass Pedal!

// MultiButtonMIDI.ino
// Driving MIDI using a Multiple Buttons
// Rob Ives 2012
// This code is released into the Public Domain.
 
#include <MIDI.h>
#include <Wire.h>
 
int keyispressed[16]; //Is the key currently pressed?
int noteisplaying[16]; //Is the Note currently playing?
unsigned char data1; //data from chip 1
unsigned char data2; //data from chip 2
 
void  setup() //The Setup Loop
{
  Wire.begin(); // setup the I2C bus
  for (unsigned int i = 0; i < 16; i++) { //Init variables
    keyispressed[i] = 1; //clear the keys array (High is off)
    noteisplaying[i] = 0; //no notes are playing
  }
  MIDI.begin(); //initialise midi library
}
//---------------------------------------------
void loop() //the main loop
{
  readkeys();
  sendMIDI();
}  
//-------------------------------------
void readkeys() { //Read the state of the I2C chips. 1 is open, 0 is closed.
  Wire.requestFrom(0x38, 1); // read the data from chip 1 in data1
  if (Wire.available()){
     data1 = Wire.read(); 
 
  }
  Wire.requestFrom(0x39, 1); // read the data freom chip 2 into data2
  if (Wire.available()){
     data2 = Wire.read();    
  }
 
  for (unsigned char i = 0; i < 8; i++) {// puts data bits from chip 1 into keys array
       keyispressed[i] = ((data1 >> i) & 1); // set the key variable to the current state. chip 1
       keyispressed[i + 8] = ((data2 >> i) & 1); //chip 2
  }
}  
//-------------------------------------
void sendMIDI() { // Send MIDI instructions via the MIDI out
  for (unsigned char i = 0; i < 16; i++) { //for each note in the array
    if (keyispressed[i] == LOW){ //the key on the board is pressed 
      if(!noteisplaying[i]){ //if the note is not already playing send MIDI instruction to start the note
         MIDI.sendNoteOn(36+i,127,1);  // Send a Note ( vel.127  ch. 1)
         noteisplaying[i] = 1; // set the note playing flag to TRUE
      }
    }
    else{
      if(noteisplaying[i]){ //if the note is currently playing, turn it off
        MIDI.sendNoteOff(36+i,0,1);   // Stop the note
        noteisplaying[i] = 0; // clear the note is playing flag
      }
    }
  }
}

This is just the start. My next step will be to add a volume control and an octave switch.
Possible plan for octave switch: Two foot buttons, one for up, one for down, Four LEDs showing which octave is currently selected.

Testing the I2C bus

I’m using the I2C bus to read the keys in from the bass pedal. The breadboard layout is shown in an earlier post. To make sure that everything is working properly with the chips I have set up a piece of code that will read the sixteen pins in I2C chips and display their output via the Arduino serial monitor.
The code is here:

// MultiButtonTest.ino
// Driving MIDI using a Multiple Buttons
// Rob Ives 2012
// This code is released into the Public Domain.
 
#include <MIDI.h>
#include <Wire.h>
 
int keyispressed[16]; //Variable. Is the key currently pressed?
int noteisplaying[16]; //Variable. Is the Note currently playing?
unsigned char data1; //data from chip 1
unsigned char data2; //data from chip 2
 
void  setup() //The Setup Loop
{
  Wire.begin(); // setup the I2C bus
  Serial.begin(9600); // serial set up for debugging
  for (unsigned int i = 0; i < 16; i++) { 
    keyispressed[i] = 1; //clear the keys array (High is off)
    noteisplaying[i] = 0; //no notes are playing
  }
 
  //MIDI.begin(); //initialise midi library
}
//---------------------------------------------
void loop() //the main loop
{
  readkeys();
  displaykeys();
}  
//-------------------------------------
void readkeys() {
  Wire.requestFrom(0x38, 1); // read the data from chip 1 into data1
  if (Wire.available()){
     data1 = Wire.read(); 
 
  }
  Wire.requestFrom(0x39, 1); // read the data freom chip 2 into data2
  if (Wire.available()){
     data2 = Wire.read();    
  }
 
  for (unsigned char i = 0; i < 8; i++) {// puts data bits from chip 1 into keys array
       keyispressed[i] = ((data1 >> i) & 1); // set the key variable to the current state. chip 1
       keyispressed[i + 8] = ((data2 >> i) & 1); //chip 2
  }
}  
//-------------------------------------
void displaykeys() { //Display the keys presssed for debugging purposes
  for (unsigned char i = 0; i < 16; i++) {
    Serial.print(keyispressed[i]); //print out each value from the array on one line.
  } 
  Serial.println("<<"); 
}

Wire up the chip and run the sketch.

In the Arduino environment on your computer go to Tools -> Serial Monitor
where you should see a display spitting out rows of sixteen ones over and over.
Try connecting each of the data pins on the I2C chips to ground and if all is well, the corresponding one will turn to a zero.

First Draft of Code

First draft of the code to convert keyboard input to midi. There is a bug somewhere, the midi sounds continuously with new notes added but not switched off.

// Convert thirteen input wires from bass pedal into midi output
// Rob Ives 2012
// This code is realeased into the Public Domain.
 
#include <wire.h>
unsigned char data1; //data from chip 1
unsigned char data2; //data from chip 2
unsigned char keys[16]; //storage array for key states.
byte notevalue = 0; //lowest note on the bass board
 
void setup() // the setup loop
 
{
  Wire.begin(); // setup the I2C bus
  Serial.begin(9600); // serial set up for midi
  for (unsigned int i = 0; i < 16; i++) { //clear the keys array
    keys[i] = 1;
  }
}
// ----------------------------------------------------------------
void loop() // the main loop
{
  byte velocity; //note velocity
  velocity = 90; //initially set at 90 - add volume control later
  Wire.requestFrom(0x38, 1); // read the data from chip 1 into data1
  if (Wire.available()){
     data1 = Wire.read(); 
 
  }
  Wire.requestFrom(0x39, 1); // read the data freom chip 2 into data2
  if (Wire.available()){
     data2 = Wire.read();
  }
 
  for (unsigned char i = 0; i &lt; 8; i++) {// puts data bits from chip 1 into keys array     if (keys[i] != ((data1 &gt;&gt; i) &amp; 1)){ // edge detect. If the key state has changed.
      if (keys[i] == 1){// if the key was on send an Start Note midi command
        playnote(0x90, notevalue + i, velocity); // channel 1 midi on
      }
      else{ // send a end note midi command
        playnote(128, notevalue + i, 0); // channel 1 midi off
      }
    }
    keys[i] = ((data1 &gt;&gt; i) &amp; 1); // set the key variable to the current state.
  }
 
 /* for (unsigned char i = 0; i &lt; 8; i++) {// puts data bits from chip 2 into keys array     if (keys[i+8] != ((data2 &gt;&gt; i) &amp; 1)){ // edge detect. If the key state has changed.
      if (keys[i+8] == 1){// if the key was on send an start Note midi command
          //Serial.print(i+8);
          //Serial.println(" Midi On");
          Serial.print(0x80); // channel 1 midi on
          Serial.print(notevalue+i+8); //note value
          Serial.println(velocity); // note velocity
      }
      else{ // send a end note midi command
        //Serial.print(i+8);
        //Serial.println(" Midi Off");
        Serial.write(0x90); // channel 1 midi off
        Serial.write(notevalue+i+8); //note value
        Serial.write(velocity); // note velocity
      }
    }
    keys[i + 8] = ((data2 &gt;&gt; i) &amp; 1);
  } */
 
  /* for (unsigned char i = 0; i &lt; 16; i++) {
      Serial.print(keys[i]);
  }
  Serial.println("-"); */
}
 
//-------------------------------------
//play note
void playnote(byte cmd, byte data1, byte data2) {
   //--------------- debug
   Serial.print(cmd);
   Serial.print(" | ");
   Serial.print(data1);
   Serial.print(" | ");
   Serial.println(data2);
   //-----------------
   Serial.write(cmd);
   Serial.write(data1);
   Serial.write(data2);
 }

Cabling up the Keys

A small step today. I’ve removed the old bundle of cable and replaced it with a ribbon cable. Its a twenty strand flat ribbon, I’ve used thirteen strands for the keys and one for ground leaving six wires unused. I’ve left them as part of the cable on the grounds that they might come in for something later on.

Electronics – First Steps

The pedal board is ready with all the parts cleaned and screws tightened. I have a bundle of thirteen wires, one for each pedal. I’m planning to convert the input from these wires into a midi output. I’m using the Arduino Uno board to convert between the two. Rather than clogging up all the arduino inputs with wires I’m using a pair of PCF8574A port expander chips to encode the keyboard inputs.

The white wires in the above diagram are all inputs, sixteen of them, three spare. the diagram above was prepared using Fritzing, a fabulous open source tool for circuit design.

Here’s the result  set up on a breadboard.

I’ll be testing this out with a few jump leads before wiring in the keyboard wires. Code next. Meanwhile, I’m thinking of replacing the bundle of cable with ribbon cable which would be easier to connect to the completed circuit board.

Bass Pedal to midi-fy

By the power of eBay, I have acquired this 13 key bass pedal, just what I needed for a bit of midi hacking. As it comes, this pedal is simply a set of thirteen switches. My plan is to  add a midi output to the back of the box.
Bass Pedal

Inside, each key is switched so that as the pedal is pressed it connects to horizontal common bus running across the full length of the pedal. ( you can see it running across the botton of the brass coloured section below.)

Each switch then has its own colour coded wire running in the bundle, top left of the picture above.

From the side, you can see the spring wire bending and touching on the bus rod as the pedal, to the left of the picture, is pressed.

Okay, so that’s the mechanics sorted out, next step, take the thirteen switches and turn them into a midi output. The Arduino, my choice for microprocessor comes with 14 digital inputs, one for each key and one for the output. Alternatively I might use an I/O expander chip such as the PCF8574AN then I’d have more inputs available for other switches  and cool stuff.