4021's X4 for 32note midi pedals

Hi, I am trying to infterface 4 - 4021 shift registers that are connected to switches I am using for a 32 note pedalboard. I am not a programmer but I do understand some stuff. I found this code that used 7 - 4021's and I am trying to get it to work for me. can anyone help?

#include <MIDI.h>

// ******************************************
// Variables definitions
// ******************************************

// *********************
// Buttons Multiplexing Variables
// Definition of pins
int buttonsMuxClockPin = 7;
int buttonsMuxLatchPin = 8;
int buttonsMuxDataPin = 9;

// Define variables to hold the data
// for each shift register.
byte muxButtons1 = 0;
byte muxButtons2 = 0;
byte muxButtons3 = 0;
byte muxButtons4 = 0;

// General midi notes
char buttonsMuxNotes1[] = {36, 37, 38, 39, 40, 41, 42, 43};
char buttonsMuxNotes2[] = {44, 45, 46, 47, 48, 49, 50, 51};
char buttonsMuxNotes3[] = {52, 53, 54, 55, 56, 57, 58, 59};
char buttonsMuxNotes4[] = {60, 61, 62, 63, 64, 65, 66, 67};

// Status of each button of the mux
boolean buttonsMuxStatus1[] = {0,0,0,0,0,0,0,0};
boolean buttonsMuxStatus2[] = {0,0,0,0,0,0,0,0};
boolean buttonsMuxStatus3[] = {0,0,0,0,0,0,0,0};
boolean buttonsMuxStatus4[] = {0,0,0,0,0,0,0,0};

// Midi channel where to send notes for each mux
int buttonsMuxMidiChannel1 = 3;
int buttonsMuxMidiChannel2 = 3;
int buttonsMuxMidiChannel3 = 3;
int buttonsMuxMidiChannel4 = 3;

// Debounce settings
long muxButtonsTime = 0; // the last time the output pin was toggled
long muxButtonsDebounce = 100; // the debounce time, increase if the output flickers

// *********************
// Set up application
// *********************
void setup() {
// Standard serial begin
// Serial.begin(9600);
// Midi serial begin
Serial.begin(31250);

// Buttons Mux
// Define pin modes
pinMode(buttonsMuxLatchPin, OUTPUT);
pinMode(buttonsMuxClockPin, OUTPUT);
pinMode(buttonsMuxDataPin, INPUT);
}

// ******************************************
// Main Loop
// ******************************************
void loop() {
// Butons Mux
// Function that handles digital mux for buttons
startReadingButtonMux();
}

// ******************************************
// Buttons Mux
// ******************************************
// Activate Digital Mux for Buttons
void startReadingButtonMux() {
// Pulse the latch pin:
// Set it to 1 to collect parallel data
digitalWrite(buttonsMuxLatchPin, HIGH);
// .... collecting data from digital inputs of MUX ... wait ...
delayMicroseconds(20);
// Set it to 0 to transmit data serially
digitalWrite(buttonsMuxLatchPin, LOW);

// While the shift register is in serial mode
//collect each shift register into a byte
//the register attached to the chip comes in first
muxButtons1 = shiftIn(buttonsMuxDataPin, buttonsMuxClockPin);
muxButtons2 = shiftIn(buttonsMuxDataPin, buttonsMuxClockPin);
muxButtons3 = shiftIn(buttonsMuxDataPin, buttonsMuxClockPin);
muxButtons4 = shiftIn(buttonsMuxDataPin, buttonsMuxClockPin);

analyzeButtonsMux(muxButtons1, buttonsMuxNotes1, buttonsMuxStatus1, buttonsMuxMidiChannel1);
analyzeButtonsMux(muxButtons2, buttonsMuxNotes2, buttonsMuxStatus2, buttonsMuxMidiChannel2);
analyzeButtonsMux(muxButtons3, buttonsMuxNotes3, buttonsMuxStatus3, buttonsMuxMidiChannel3);
analyzeButtonsMux(muxButtons4, buttonsMuxNotes4, buttonsMuxStatus4, buttonsMuxMidiChannel4);

}

// ShiftIn function
// Just needs the location of the data pin and the clock pin
// it returns a byte with each bit in the byte corresponding
// to a pin on the shift register. leftBit 7 = Pin 7 / Bit 0= Pin 0
byte shiftIn(int myDataPin, int myClockPin) {
int i;
int temp = 0;
// int pinState;
byte myDataIn = 0;

pinMode(myClockPin, OUTPUT);
pinMode(myDataPin, INPUT);

// we will be holding the clock pin high 8 times (0,..,7) at the
// end of each time through the for loop

// at the begining of each loop when we set the clock low, it will
// be doing the necessary low to high drop to cause the shift
// register's DataPin to change state based on the value
// of the next bit in its serial information flow.
// The register transmits the information about the pins from pin 7 to pin 0
// so that is why our function counts down

// Loop for all the pins of the shift reg.
for (i=7; i>=0; i--)
{
digitalWrite(myClockPin, LOW);
delayMicroseconds(2);
temp = digitalRead(myDataPin);
if (temp) {
// pinState = 1;
// Set the bit to 1 no matter what
myDataIn = myDataIn | (1 << i);
}
else {
//turn it off -- only necessary for debuging
//print statement since myDataIn starts as 0
// pinState = 0;
}

//Debuging print statements
// Serial.print("Valore Pin: ");
// Serial.print(pinState);
// Serial.print(" - ");
//Serial.println (dataIn, BIN);
digitalWrite(myClockPin, HIGH);
}
//debuging print statements whitespace
//Serial.println();
//Serial.println(myDataIn, BIN);
return myDataIn;
}

// Function that analiyzes the data from the Mux
// Parameters:
// 1. Byte with the state of the 8 pins
// 2. Array of notes corresponfding to the 8 pins
// 3. Array off boolean values indicates the actual status of each not/pin
// 4. Midi channel to send the midi data for the 8 notes of the mux
void analyzeButtonsMux(byte incomingData, char* muxNotes, boolean* muxStatus, int midiChannel) {
// Loop thru the Byte
for (int n=0; n<=7; n++)
{
// if 'n' value equals 1
if (incomingData & (1 << n) ){
//print the value of the array location
// Pin "i" has value 1!
// If that note was not playing.....
if(muxStatus[n] == 0 && (millis() - muxButtonsTime > muxButtonsDebounce) ) { // Some debouncing here
// playMuxOnNotes(n, muxNotes, midiChannel);
sendMidi(NoteOn, muxNotes[n], 120, midiChannel);
muxStatus[n] = 1;
muxButtonsTime =

You don't say what is going wrong.

Do you get any output at all?

Have you tried looking at the output on the monitor?(need to set to 9600)

Have you tried un commenting the debug messages, if so what do you get?

How have you got your shift registers wired up? Can you post a schematic.

When posting code, paste it between the brackets that appere when you press the hash icon in the reply box.

The 4021's are wired the same as in the Parallel to serial shifting-in with a 4021 tutorial. Q8 ouput into the serial in of each cascaded 4021. the clock and latch are connected to each 4021.

I am using hall effect sensors as switches. they are normally pulledup hi(5V) and when pressed they drop to a low (0V)

When I hook it up, all of the notes starting at 36 sequentially start to play but when I activate the first switch(and only the first switch) it turns them all off. All other switches have no response.

I will change it to 9600. and I will uncomment all of the debug messages.
Sorry, I am going to have to look in to how to monitor the output. I am completely new to this. I am using the miduino.

This guy has done a similar project the schematic is there minus the 4051's and the switches are wired with a pullup resistor.
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1234810520/5#5

Sorry you are being a bit vague.

the same as in the Parallel to serial shifting-in with a 4021 tutorial

It would be good if you could post a link to this.

a similar project the schematic is there minus the 4051's

Sorry but that is a nonsense. It's like saying I am using that circuit but it is totally different. These is little similarity between the schematic you posted a link to and what you are trying to do.

Hint.
Don't try an do it all at once, take it step by step and work up to it. With a big circuit and big sketch it is easy to get lost. Just start with one shift register and get it to print out (on the monitor) the individual bits you get. Then when that works expand it to your four shift registers. Then when that works add your MIDI protocol over the top.

I got it to work. it was a lot of trial and error.

Thanks for the help.

Go on then, tell us what was wrong, it might help other in the future. :slight_smile:

Like I said before I am not a programmer, but I will do my best to explain the things I changed to get it to work.

  1. I read that when defining a byte to hold the values from the shift registers, it should not be "0" , so I changed them. I just picked some numbers 72, 73, 74 and 75.

  2. Each shift register was in the wrong order(playing the wrong note) so I reversed the order of the buttonsMuxNotes.

  3. I had to change the status of the buttonsMuxStatus from "0" to "1" Because my switches are normally High.

  4. Not necessary but I changed the muxbuttonsDebounce to 10. I dont believe I need the debounce at all but I left it at 10.

  5. finally I had to switch the sendMidi (NoteOn..... with sendMidi(NoteOff... and vice versa. this was because all of the notes would play then when I activated a switch the note would shut off. opposite from what I needed.

magically it works.
hopefully this will help.

Thanks that is helpful.

I read that when defining a byte to hold the values from the shift registers, it should not be "0"

I think that is rubbish, I always define the bytes as zero when I am doing this. In that way you only need set the least significant bit if you read a logic on and do nothing if you read a zero.