I’ve added a couple of extra controls to the MIDI board. There are two buttons, to the bottom of the board, which control the octave. One for up, one for down. I’ve set the range of the board to four octaves with four LEDs to display the currently chosen octave.
There is also a potentiometer used to set the volume (velocity in MIDI parlance)
I’m still using a floating wire to test the board, next step will be to wire it into the pedal. The layout of the board is clearer in the Fritzing picture below.
Code shown below:
// MultiButtonMIDIOctave.ino
// Driving MIDI using a Multiple Buttons
// Added variables for Octave, Transpose and Velocity
// Rob Ives 2012
// This code is released into the Public Domain.
#include
#include
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
int octave = 2; //set currently played octave
int transpose = 0; //transpose notes on the board
int velocity = 127; //set note velocity
//--- Octave LED output pins
int octave1 = 8;
int octave2 = 9;
int octave3 = 10;
int octave4 = 11;
//--- Octave Switches
int octaveup = 7;
int octavedown = 6;
//--- Pot
int potpin = 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
}
//--- Set up pins
pinMode(octaveup, INPUT);
pinMode(octavedown, INPUT);
pinMode(octave1, OUTPUT);
pinMode(octave2, OUTPUT);
pinMode(octave3, OUTPUT);
pinMode(octave4, OUTPUT);
MIDI.begin(); //initialise midi library
displayoctave(); //display the current octave
}
//---------------------------------------------
void loop() //the main loop
{
readkeys();
sendMIDI();
checkoctave();
}
//-------------------------------------
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
int note; //holder for the value of note being played
velocity = analogRead(potpin)/8;// Read velocity from the pot
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
note = i + (octave*12) + transpose;
MIDI.sendNoteOn(note,velocity,1); // Send a Note ( vel.127 ch. 1)
noteisplaying[i] = note; // set the note playing flag to TRUE and store the note value
}
}
else{
if(noteisplaying[i]){ //if the note is currently playing, turn it off
note = noteisplaying[i]; //retrieve the saved note value incase the octave has changed
MIDI.sendNoteOff(note,0,1); // Stop the note
noteisplaying[i] = 0; // clear the note is playing flag
}
}
}
}
//----------------------------------------
void checkoctave(){
int up = digitalRead(octaveup);
int down = digitalRead(octavedown);
if(up == HIGH){ //up button pressed
if(octave < 4){ octave++; } while(up == HIGH){// wait until button is released up = digitalRead(octaveup); delay(20); } displayoctave(); } if(down == HIGH){ //down button pressed if(octave > 1){
octave--;
}
while(down == HIGH){// wait until button is released
down = digitalRead(octavedown);
delay(20);
}
displayoctave();
}
}
//-------------------------------------
void displayoctave(){
// clear all the LEDs
digitalWrite(octave1, LOW);
digitalWrite(octave2, LOW);
digitalWrite(octave3, LOW);
digitalWrite(octave4, LOW);
// ...and then display the current octave
switch(octave){ // display the current actave
case 1: digitalWrite(octave1, HIGH);
break;
case 2: digitalWrite(octave2, HIGH);
break;
case 3: digitalWrite(octave3, HIGH);
break;
case 4: digitalWrite(octave4, HIGH);
break;
}
}