thanks very much trialex that is a really good resource I haven't seen before and its solved my problem. I am going to use 3 of the CD4021BE IC's daisy chained together to get 24 switches using only 3 pins. 20 of these switches are used. 2 other switches are used to change the MIDI channel of the messages to give my foot controller 4 different functions. This is the code I intend to use:
//**************************************************************//
// Name : MIDI Foot Controller //
// Author : Matthew Hubble //
// Date : 11 May, 2008 //
// Version : 0.1 //
// Notes : Code for using a CD4021B Shift Register and //
// : sending MIDI //
//**************************************************************//
//define pins
#define MIDIPin 1
#define ledPin 2
#define clockPin 3
#define dataPin 4
#define latchPin 5
#define modePin1 6
#define modePin2 7
//define bits
#define BIT1 1
#define BIT2 2
#define BIT3 3
#define BIT4 4
#define BIT5 5
#define BIT6 6
#define BIT7 7
#define BIT8 8
//define MIDI stuff
#define MIDICHANNEL1 1
#define MIDICHANNEL2 2
#define MIDICHANNEL3 3
#define MIDICHANNEL4 4
#define VELOCITY 127
#define ROOTNOTE1 1
#define ROOTNOTE2 9
#define ROOTNOTE3 17
//declare 3 bytes to hold the binary from 3 CD4021BE IC's
byte switchVar1 = 0;
byte switchVar2 = 0;
byte switchVar3 = 0;
int modePin1State;
int modePin2State;
int if_flag = 0;
void setup()
{
//set MIDI baud rate
Serial.begin(31250);
//define pin modes
pinMode(ledPin,OUTPUT);
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, INPUT);
pinMode(modePin1,INPUT);
pinMode(modePin2,INPUT);
//turn on internal pullup
digitalWrite(modePin1, HIGH);
digitalWrite(modePin2, HIGH);
}
void loop()
{
//Pulse the latch pin:
//set it to 1 to collect parallel data
digitalWrite(latchPin,1);
//set it to 1 to collect parallel data, wait
delayMicroseconds(20);
//set it to 0 to transmit data serially
digitalWrite(latchPin,0);
//while the shift register is in serial mode
//collect each shift register into a byte
//the register attached to the chip comes in first
switchVar1 = shiftIn(dataPin, clockPin);
switchVar2 = shiftIn(dataPin, clockPin);
switchVar3 = shiftIn(dataPin, clockPin);
//get the state of the mode switches
modePin1State = digitalRead(modePin1);
modePin2State = digitalRead(modePin2);
//send appropriate MIDI messages based on input
switchtoMIDI(switchVar1, ROOTNOTE1);
switchtoMIDI(switchVar2, ROOTNOTE2);
switchtoMIDI(switchVar3, ROOTNOTE3);
}
//shiftIn function gets 8 bit binary string
byte shiftIn(int myDataPin, int myClockPin) {
int i;
int temp = 0;
int pinState;
byte myDataIn = 0;
pinMode(myClockPin, OUTPUT);
pinMode(myDataPin, INPUT);
for (i=7; i>=0; i--)
{
//Set clockPin to LOW to recieve serial bit
digitalWrite(myClockPin, 0);
//wait to recieve bit
delayMicroseconds(2);
//read 1 or 0
temp = digitalRead(myDataPin);
if (temp)
{
pinState = 1;
myDataIn = myDataIn | (1 << i);
}
else
{
pinState = 0;
}
//set clockPin to HIGH ready for the next bit
digitalWrite(myClockPin, 1);
}
return myDataIn;
}
// send a MIDI note-on message
void noteOn(byte channel, byte note, byte velocity)
{
midiMsg( (0x90 | (channel << 4)), note, velocity);
}
// send a MIDI note-off message
void noteOff(byte channel, byte note, byte velocity)
{
midiMsg( (0x80 | (channel<<4)), note, velocity);
}
// send a general MIDI message
void midiMsg(byte cmd, byte data1, byte data2)
{
digitalWrite(ledPin,HIGH); // indicate we're sending MIDI data
Serial.print(cmd, BYTE);
Serial.print(data1, BYTE);
Serial.print(data2, BYTE);
digitalWrite(ledPin,LOW);
}
//send MIDI messages based on the mode switches and the MIDI switches
void switchtoMIDI(byte switchVar, int rootnote)
{
if(modePin1State == HIGH && modePin2State == HIGH && if_flag == 0)
{
if(switchVar & BIT1 == 1)
{
noteOn(MIDICHANNEL1,rootnote,VELOCITY);
delayMicroseconds(1);
noteOff(MIDICHANNEL1,rootnote,VELOCITY);
}
if(switchVar & BIT2 == 2)
{
noteOn(MIDICHANNEL1,(rootnote + 1),VELOCITY);
delayMicroseconds(1);
noteOff(MIDICHANNEL1,(rootnote + 1),VELOCITY);
}
if(switchVar & BIT3 == 3)
{
noteOn(MIDICHANNEL1,(rootnote + 2),VELOCITY);
delayMicroseconds(1);
noteOff(MIDICHANNEL1,(rootnote + 2),VELOCITY);
}
if(switchVar & BIT4 == 4)
{
noteOn(MIDICHANNEL1,(rootnote + 3),VELOCITY);
delayMicroseconds(1);
noteOff(MIDICHANNEL1,(rootnote + 3),VELOCITY);
}
if(switchVar & BIT5 == 5)
{
noteOn(MIDICHANNEL1,(rootnote + 4),VELOCITY);
delayMicroseconds(1);
noteOff(MIDICHANNEL1,(rootnote + 4),VELOCITY);
}
if(switchVar & BIT6 == 6)
{
noteOn(MIDICHANNEL1,(rootnote + 5),VELOCITY);
delayMicroseconds(1);
noteOff(MIDICHANNEL1,(rootnote + 5),VELOCITY);
}
if(switchVar & BIT7 == 7)
{
noteOn(MIDICHANNEL1,(rootnote + 6),VELOCITY);
delayMicroseconds(1);
noteOff(MIDICHANNEL1,(rootnote + 6),VELOCITY);
}
if(switchVar & 8 == 8)
{
noteOn(MIDICHANNEL1,(rootnote + 7),VE