unstable code with shift register

Hi,
I’m currently building a small extension for my Grand Orgue vpo system, which will be a small set of real organ pipes. I’m planning to control the pipe’s valve magnets using an Arduino Nano with midiIn and 4 shift registers with 25 transistors on their outputs to control solenoids.
The circuit is working fine, but the programming is the problem for me. I only use 25 pipes, so two octaves. I want to start at the G right under middle C (so Midinote 55) , so thats what has to be the shift register’s first pin. At the moment it’s working, but very unstable. The LED that I attached between the base and emitter of the transistor for testing purposes often stays on or off until I reset the board. What am I doing wrong or what can I improve to solve the problem? Btw: It’s a code I copied from another thread that I modified a bit. And yes, my way may be completely wrong, I’m not a pro at all.)
Here’s my code:

/* /* Controlling up to 88 LEDs independently with Midi notes from a Midi in.
//

// This code has been cobbled together from existing material found on the internet and help from the Arduino forums.

// The midi stuff in particular was gleaned from this thread: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1187962258/

// The shift register stuff is pulled straight from the arduino tutorials.

// I have not fine tuned it yet and there are still probably fragments of code in here that are either unnecessary or
// perhaps even detrimental to the performance.
// However, it DOES work, so if you happen to need to be able to control LEDS via midi notes, then this will be
// a useful place to start.
*/

// A midi signal comes in 3 bits. The first is Midi On (144), or Midi off(128). It can be a bunch of other things too,
// but for this situation I'm not interested in them.
// The second bit is the note number (e.g 36 = C1, 37 = C#1, 38 = D1, etc.)
// The third bit is velocity (0-127).

// Finally - at the moment this code only deals with 5 shift registers, giving control over 40 leds,
// although the array caters for all 88 notes.
//

//variables setup

byte byteCount;
byte incomingByte = 255; // midi signal #1
byte note = 255; // midi signal #2
byte velocity = 255; // midi signal #3
byte incomingBytea;

byte bytenumb; // 
byte bitnumb; //
byte chromatic[4];   // declare chromatic scale, 8 x 11 = 88 notes


//Shift Out Pins to 74HC595s
int latchPin = 11;
int clockPin = 12;
int dataPin = 8;
int statusLed = 13;   // select the pin for the LED
int startupBeep =  6; // connect to a piezo buzzer. not strictly necessary, but use to know arduino is on & good to receive midi   
int action=2; // MIDI rules: 0 =note off ; 1=note on ; 2= nada

//setup: declaring iputs and outputs and begin serial 
void setup() {

pinMode(statusLed,OUTPUT);   // declare the LED's pin as output
pinMode(latchPin, OUTPUT);  // declare latch pin as output

//start serial with midi baudrate 31250 or 38400 for debugging
Serial.begin(31250);        



//function that blinks all the LEDs and then switches them off
 //gets passed the number of blinks and the pause time
 blinkAll_2Bytes(1,100);
 killAll_2Bytes(1,100);
 delay(200);
 blinkAll_2Bytes(1,100);
 killAll_2Bytes(1,100);

 
 for (int i = 0; i < 4; i++){ //  (i.e. for i = 0 to 10)
chromatic[i] = 0; // resets the array.
}

 
}

//loop: wait for serial data, and interpret the message 
void loop () {
if (Serial.available() > 0) {
  // read the incoming byte:
  incomingByte = Serial.read();
  // wait for as status-byte, channel 1, note on or off
  if (incomingByte== 144){ // note on message starting starting
    action=1;
  }else if (incomingByte== 128){ // note off message starting
    action=0;
  }else if (incomingByte > 144){ // message is anything but note message
  action=2; //nothing happens
    
  //process second byte
 
  }else if ( (incomingByte<=127) && (action ==1) ){ // IF THE FIRST BYTE WAS A NOTE ON MESSAGE...
    
      if(byteCount == 1) {
         incomingBytea = incomingByte;
         incomingBytea += -55;
       }
    bytenumb = (incomingBytea / 8);  // calculate which array byte 0 ~ 10
    bitnumb  = (incomingBytea % 8);   // calculate which bit  (0 ~ 7)
    chromatic[bytenumb] = bitSet(chromatic[bytenumb], bitnumb);
   //ground latchPin and hold low for as long as you are transmitting
   digitalWrite(latchPin, 0);
   //move 'em out   
   shiftOut(dataPin, clockPin, chromatic[3]);   
   shiftOut(dataPin, clockPin, chromatic[2]);   
   shiftOut(dataPin, clockPin, chromatic[1]);   
   shiftOut(dataPin, clockPin, chromatic[0]);   
   //return the latch pin high to signal chip that it 
   //no longer needs to listen for information
   digitalWrite(latchPin, 1);
   digitalWrite(statusLed,HIGH); 
 }   
 
 else if ( (incomingByte<=127) && (action ==0) ){ //IF THE FIRST BYTE WAS A NOTE OFF MESSAGE...
    if(byteCount == 1) {
        incomingBytea = incomingByte;
        incomingBytea += -55;
    }
    bytenumb = (incomingBytea / 8);  // calculate which array byte 0 ~ 10
    bitnumb  = (incomingBytea % 8);   // calculate which bit  (0 ~ 7)
    chromatic[bytenumb] = bitClear(chromatic[bytenumb], bitnumb);
    //ground latchPin and hold low for as long as you are transmitting
    digitalWrite(latchPin, 0);
    //move 'em out
    shiftOut(dataPin, clockPin, chromatic[3]);
    shiftOut(dataPin, clockPin, chromatic[2]);
    shiftOut(dataPin, clockPin, chromatic[1]);
    shiftOut(dataPin, clockPin, chromatic[0]);  
   
    //return the latch pin high to signal chip that it 
    //no longer needs to listen for information
    digitalWrite(latchPin, 1);
    digitalWrite(statusLed,LOW); 
 } 
 
  
  
  //process Third byte - the velocity
  }else if ( (incomingByte<=127) && (action ==1) ){ // if we received note ON message load this byte in the velocity byte
   velocity=incomingByte;
   note=255;
  }else if ( (incomingByte<=127) && (action ==0) ){ // if we received note message load this byte in the velocity byte
   velocity=0;
   note=255;
  }
 }


// the shift out function
void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {
 // This shifts 8 bits out MSB first, 
 //on the rising edge of the clock,
 //clock idles low

 //internal function setup
 int i=0;
 int pinState;
 pinMode(myClockPin, OUTPUT);
 pinMode(myDataPin, OUTPUT);

 //clear everything out just in case to
 //prepare shift register for bit shifting
 digitalWrite(myDataPin, 0);
 digitalWrite(myClockPin, 0);

 //for each bit in the byte myDataOut?
 //NOTICE THAT WE ARE COUNTING DOWN in our for loop
 //This means that %00000001 or "1" will go through such
 //that it will be pin Q0 that lights. 
 for (i=7; i>=0; i--)  {
   digitalWrite(myClockPin, 0);

   //if the value passed to myDataOut and a bitmask result 
   // true then... so if we are at i=6 and our value is
   // %11010100 it would the code compares it to %01000000 
   // and proceeds to set pinState to 1.
   if ( myDataOut & (1<<i) ) {
     pinState= 1;
   }
   else {      
     pinState= 0;
   }

   //Sets the pin to HIGH or LOW depending on pinState
   digitalWrite(myDataPin, pinState);
   //register shifts bits on upstroke of clock pin  
   digitalWrite(myClockPin, 1);
   //zero the data pin after shift to prevent bleed through
   digitalWrite(myDataPin, 0);
 }

 //stop shifting
 digitalWrite(myClockPin, 0);
}


//blinks the whole register based on the number of times you want to 
//blink "n" and the pause between them "d"
//starts with a moment of darkness to make sure the first blink
//has its full visual effect.
void blinkAll_2Bytes(int n, int d) {
 digitalWrite(latchPin, 0);
 shiftOut(dataPin, clockPin, 0);
 shiftOut(dataPin, clockPin, 0);
 shiftOut(dataPin, clockPin, 0);
 shiftOut(dataPin, clockPin, 0);
 digitalWrite(startupBeep, 0);
 digitalWrite(latchPin, 1);
 delay(200);
 for (int x = 0; x < n; x++) {
   digitalWrite(latchPin, 0);
   shiftOut(dataPin, clockPin, 255);
   shiftOut(dataPin, clockPin, 255);
   shiftOut(dataPin, clockPin, 255);
   shiftOut(dataPin, clockPin, 255);
   digitalWrite(startupBeep, 1);
   digitalWrite(latchPin, 1);
   delay(d);
   digitalWrite(latchPin, 0);
   shiftOut(dataPin, clockPin, 0);
   shiftOut(dataPin, clockPin, 0);
   shiftOut(dataPin, clockPin, 0);
   shiftOut(dataPin, clockPin, 0);
   digitalWrite(startupBeep, 0);
   digitalWrite(latchPin, 1);
   delay(d);
 }
}

void killAll_2Bytes(int n, int d){
 digitalWrite(latchPin, 0);
 shiftOut(dataPin, clockPin, 0);
 shiftOut(dataPin, clockPin, 0);
 shiftOut(dataPin, clockPin, 0);
 shiftOut(dataPin, clockPin, 0);
 digitalWrite(latchPin, 1);
 delay(200);
 }

I can see a couple problems with the code.

First, the else clause for when there is no data available at the serial port inspects the incomingByte variable and sets velocity. I would have to trace out the logic to be certain but it looks like three bytes are read and both the note and velocity values get treated as notes, then if there is no more data the last read value also gets treated as velocity.

Second, two sections of code compare the variable byteCount to one, but it does not seem to be set anywhere.

Could you please tell me where which comand in particular would need to go? I only understand the whole code to a certain degree and most importantly don't know enough about c++ yet. Thanks for your help!

The LED that I attached between the base and emitter of the transistor for testing purposes often stays on or off until I reset the board.

Base and emitter --- that's a BJT where current through the gate meters flow from the emitter and you tape the gate to light a led? Do you keep the gate either full open or full closed? Because if your do, get FETs.

GoForSmoke:
Base and emitter --- that's a BJT where current through the gate meters flow from the emitter and you tape the gate to light a led? Do you keep the gate either full open or full closed? Because if your do, get FETs.

No, I'm not using it to light LEDs. The LED is just connected to the base of one of the transistors to test the shift registers and the code. The transistors (BD 139) are supposed to drive the solenoids. I've read about it on this page: http://www.pykett.org.uk/electric-action-schematics-diode-keying.htm#TransistorSwitch

If you full open a BJT then there's extra current on the base the led can tap. Sure enough, that site is about using transistor as a switch (full open or closed) so the led's not a problem. Servo control is through PWM. FETs would only be more efficient than BJT's.

I still have the problem with the code... Can you @GoForSmoke or anyone else help me with that? I would really appreciate it!

I don't want to try debugging that delay-ridden mess! You picked it, I didn't!

Or could anyone modify the following code to work with the previously explained parameters or at least explain what has to be done in particular? This one can’t have that much errors, it’s from here: forum.arduino.cc/index.php?topic=19427.15

/* /* Controlling up to 88 LEDs independently with Midi notes from a Midi in.
//

// This code has been cobbled together from existing material found on the internet and help from the Arduino forums.

// The midi stuff in particular was gleaned from this thread: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1187962258/

// The shift register stuff is pulled straight from the arduino tutorials.

// I have not fine tuned it yet and there are still probably fragments of code in here that are either unnecessary or
// perhaps even detrimental to the performance.
// However, it DOES work, so if you happen to need to be able to control LEDS via midi notes, then this will be
// a useful place to start.
*/

// A midi signal comes in 3 bits. The first is Midi On (144), or Midi off(128). It can be a bunch of other things too,
// but for this situation I'm not interested in them.
// The second bit is the note number (e.g 36 = C1, 37 = C#1, 38 = D1, etc.)
// The third bit is velocity (0-127).

// Finally - at the moment this code only deals with 5 shift registers, giving control over 40 leds,
// although the array caters for all 88 notes.
//

//variables setup

byte incomingByte = 255; // midi signal #1
byte note = 255; // midi signal #2
byte velocity = 255; // midi signal #3

byte bytenumb; // 
byte bitnumb; //
byte chromatic[10];   // declare chromatic scale, 8 x 11 = 88 notes

//Shift Out Pins to 74HC595s
int latchPin = 8;
int clockPin = 12;
int dataPin = 11;
int statusLed = 13;   // select the pin for the LED
int startupBeep =  6; // connect to a piezo buzzer. not strictly necessary, but use to know arduino is on & good to receive midi   
int action=2; // MIDI rules: 0 =note off ; 1=note on ; 2= nada


//setup: declaring iputs and outputs and begin serial 
void setup() {

pinMode(statusLed,OUTPUT);   // declare the LED's pin as output
pinMode(latchPin, OUTPUT);  // declare latch pin as output

//start serial with midi baudrate 31250 or 38400 for debugging
Serial.begin(31250);        
digitalWrite(statusLed,HIGH); 


//function that blinks all the LEDs and then switches them off
 //gets passed the number of blinks and the pause time
 blinkAll_2Bytes(1,750);
 killAll_2Bytes(1,500);
 
 for (int i = 0; i < 11; i++){ //  (i.e. for i = 0 to 10)
chromatic[i] = 0; // resets the array.
}

 
}

//loop: wait for serial data, and interpret the message 
void loop () {
if (Serial.available() > 0) {
  // read the incoming byte:
  incomingByte = Serial.read();

  // wait for as status-byte, channel 1, note on or off
  if (incomingByte== 144){ // note on message starting starting
    action=1;
  }else if (incomingByte== 128){ // note off message starting
    action=0;
  }else if (incomingByte > 144){ // message is anything but note message
  action=2; //nothing happens
    
     
  //process second byte 
  }else if ( (incomingByte<=127) && (action ==1) ){ // IF THE FIRST BYTE WAS A NOTE ON MESSAGE...
    bytenumb = (incomingByte / 8);  // calculate which array byte 0 ~ 10
    bitnumb  = (incomingByte % 8);   // calculate which bit  (0 ~ 7)
    chromatic[bytenumb] = bitSet(chromatic[bytenumb], bitnumb);
   //ground latchPin and hold low for as long as you are transmitting
   digitalWrite(latchPin, 0);
   //move 'em out
   shiftOut(dataPin, clockPin, chromatic[4]);   
   shiftOut(dataPin, clockPin, chromatic[3]);   
   shiftOut(dataPin, clockPin, chromatic[2]);   
   shiftOut(dataPin, clockPin, chromatic[1]);   
   shiftOut(dataPin, clockPin, chromatic[0]);   
   //return the latch pin high to signal chip that it 
   //no longer needs to listen for information
   digitalWrite(latchPin, 1);
   
 }   
 
 else if ( (incomingByte<=127) && (action ==0) ){ //IF THE FIRST BYTE WAS A NOTE OFF MESSAGE...
    bytenumb = (incomingByte / 8);  // calculate which array byte 0 ~ 10
    bitnumb  = (incomingByte % 8);   // calculate which bit  (0 ~ 7)
    chromatic[bytenumb] = bitClear(chromatic[bytenumb], bitnumb);
    //ground latchPin and hold low for as long as you are transmitting
    digitalWrite(latchPin, 0);
    //move 'em out
    shiftOut(dataPin, clockPin, chromatic[4]);
    shiftOut(dataPin, clockPin, chromatic[3]);
    shiftOut(dataPin, clockPin, chromatic[2]);
    shiftOut(dataPin, clockPin, chromatic[1]);
    shiftOut(dataPin, clockPin, chromatic[0]);  
   
    //return the latch pin high to signal chip that it 
    //no longer needs to listen for information
    digitalWrite(latchPin, 1);
    
 } 
 
  
  
  //process Third byte - the velocity
  }else if ( (incomingByte<=127) && (action ==1) ){ // if we received note ON message load this byte in the velocity byte
   velocity=incomingByte;
   note=255;
  }else if ( (incomingByte<=127) && (action ==0) ){ // if we received note message load this byte in the velocity byte
   velocity=0;
   note=255;
  }
 }


// the shift out function
void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {
 // This shifts 8 bits out MSB first, 
 //on the rising edge of the clock,
 //clock idles low

 //internal function setup
 int i=0;
 int pinState;
 pinMode(myClockPin, OUTPUT);
 pinMode(myDataPin, OUTPUT);

 //clear everything out just in case to
 //prepare shift register for bit shifting
 digitalWrite(myDataPin, 0);
 digitalWrite(myClockPin, 0);

 //for each bit in the byte myDataOut?
 //NOTICE THAT WE ARE COUNTING DOWN in our for loop
 //This means that %00000001 or "1" will go through such
 //that it will be pin Q0 that lights. 
 for (i=7; i>=0; i--)  {
   digitalWrite(myClockPin, 0);

   //if the value passed to myDataOut and a bitmask result 
   // true then... so if we are at i=6 and our value is
   // %11010100 it would the code compares it to %01000000 
   // and proceeds to set pinState to 1.
   if ( myDataOut & (1<<i) ) {
     pinState= 1;
   }
   else {      
     pinState= 0;
   }

   //Sets the pin to HIGH or LOW depending on pinState
   digitalWrite(myDataPin, pinState);
   //register shifts bits on upstroke of clock pin  
   digitalWrite(myClockPin, 1);
   //zero the data pin after shift to prevent bleed through
   digitalWrite(myDataPin, 0);
 }

 //stop shifting
 digitalWrite(myClockPin, 0);
}


//blinks the whole register based on the number of times you want to 
//blink "n" and the pause between them "d"
//starts with a moment of darkness to make sure the first blink
//has its full visual effect.
void blinkAll_2Bytes(int n, int d) {
 digitalWrite(latchPin, 0);
 shiftOut(dataPin, clockPin, 0);
 shiftOut(dataPin, clockPin, 0);
 shiftOut(dataPin, clockPin, 0);
 shiftOut(dataPin, clockPin, 0);
 shiftOut(dataPin, clockPin, 0);
 digitalWrite(startupBeep, 0);
 digitalWrite(latchPin, 1);
 delay(200);
 for (int x = 0; x < n; x++) {
   digitalWrite(latchPin, 0);
   shiftOut(dataPin, clockPin, 255);
   shiftOut(dataPin, clockPin, 255);
   shiftOut(dataPin, clockPin, 255);
   shiftOut(dataPin, clockPin, 255);
   shiftOut(dataPin, clockPin, 255);
   digitalWrite(startupBeep, 1);
   digitalWrite(latchPin, 1);
   delay(d);
   digitalWrite(latchPin, 0);
   shiftOut(dataPin, clockPin, 0);
   shiftOut(dataPin, clockPin, 0);
   shiftOut(dataPin, clockPin, 0);
   shiftOut(dataPin, clockPin, 0);
   shiftOut(dataPin, clockPin, 0);
   digitalWrite(startupBeep, 0);
   digitalWrite(latchPin, 1);
   delay(d);
 }
}

void killAll_2Bytes(int n, int d){
 digitalWrite(latchPin, 0);
 shiftOut(dataPin, clockPin, 0);
 shiftOut(dataPin, clockPin, 0);
 shiftOut(dataPin, clockPin, 0);
 shiftOut(dataPin, clockPin, 0);
 shiftOut(dataPin, clockPin, 0);
 digitalWrite(latchPin, 1);
 delay(200);
 }

Those delays in setup() don’t bother me, but I agree that the code is a mess. I’ve tried to clean it up as best I could - look for comments with asterisks - but this is not anywhere near the way I would write it, I have no way of testing it and I’m not convinced that there is no hardware problem.

If you don’t understand the code the best thing to do is rewrite it piece-by-piece to end up with code you can maintain.

At least I can say this code compiles, probably my biggest contribution is adding print statements so you can see how the logic flows. (Blink and Shiftout functions left off to meet max length).

/* /* Controlling up to 88 LEDs independently with Midi notes from a Midi in.
  //

  // This code has been cobbled together from existing material found on the internet and help from the Arduino forums.

  // The midi stuff in particular was gleaned from this thread: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1187962258/

  // The shift register stuff is pulled straight from the arduino tutorials.

  // I have not fine tuned it yet and there are still probably fragments of code in here that are either unnecessary or
  // perhaps even detrimental to the performance.
  // However, it DOES work, so if you happen to need to be able to control LEDS via midi notes, then this will be
  // a useful place to start.
*/

// A midi signal comes in 3 bits. The first is Midi On (144), or Midi off(128). It can be a bunch of other things too,
// but for this situation I'm not interested in them.
// The second bit is the note number (e.g 36 = C1, 37 = C#1, 38 = D1, etc.)
// The third bit is velocity (0-127).

// Finally - at the moment this code only deals with 5 shift registers, giving control over 40 leds,
// although the array caters for all 88 notes.
//

//variables setup

byte byteCount = 0; // **** initialize byteCount
byte incomingByte = 255; // midi signal #1
byte note = 255; // midi signal #2
byte velocity = 255; // midi signal #3
byte incomingBytea;

byte bytenumb; //
byte bitnumb; //
byte chromatic[4];   // declare chromatic scale, 8 x 11 = 88 notes


//Shift Out Pins to 74HC595s
int latchPin = 11;
int clockPin = 12;
int dataPin = 8;
int statusLed = 13;   // select the pin for the LED
int startupBeep =  6; // connect to a piezo buzzer. not strictly necessary, but use to know arduino is on & good to receive midi
int action = 2; // MIDI rules: 0 =note off ; 1=note on ; 2= nada

//setup: declaring iputs and outputs and begin serial
void setup() {

  pinMode(statusLed, OUTPUT);  // declare the LED's pin as output
  pinMode(latchPin, OUTPUT);  // declare latch pin as output

  //start serial with midi baudrate 31250 or 38400 for debugging
  Serial.begin(31250);



  //function that blinks all the LEDs and then switches them off
  //gets passed the number of blinks and the pause time
  blinkAll_2Bytes(1, 100);
  killAll_2Bytes(1, 100);
  delay(200);
  blinkAll_2Bytes(1, 100);
  killAll_2Bytes(1, 100);


  for (int i = 0; i < 4; i++) { //  (i.e. for i = 0 to 10)
    chromatic[i] = 0; // resets the array.
  }


}

//loop: wait for serial data, and interpret the message
void loop () {
  if (Serial.available() > 0) {
    // read the incoming byte:
    incomingByte = Serial.read();

    byteCount++; // ***** increment count of bytes read


    // wait for as status-byte, channel 1, note on or off
    // if first byte and note on *****
    if ( (byteCount == 1) && incomingByte == 144) { // note on message starting starting
      action = 1;

      Serial.print("note on  ");  // *****

      // if first byte and note off *****
    } else if ( (byteCount == 1) && incomingByte == 128) { // note off message starting
      action = 0;

      Serial.print("note off  ");  // *****

    } else if (incomingByte > 144) { // message is anything but note message
      action = 2; //nothing happens
      byteCount = 0; // ***** reset byte count?

      Serial.println("unknown message");  // *****
      //process second byte
      // ***** check byte count
    } else if ( (byteCount == 2) && (incomingByte <= 127) && (action == 1) ) { // IF THE FIRST BYTE WAS A NOTE ON MESSAGE...

      Serial.print("action 1, shifting out note  ");  // *****

      // ***** second byte is note
      /*
        if (byteCount == 1) {
        incomingBytea = incomingByte;
        incomingBytea += -55;
        }
      */
      bytenumb = (incomingBytea / 8);  // calculate which array byte 0 ~ 10
      bitnumb  = (incomingBytea % 8);   // calculate which bit  (0 ~ 7)
      chromatic[bytenumb] = bitSet(chromatic[bytenumb], bitnumb);
      //ground latchPin and hold low for as long as you are transmitting
      digitalWrite(latchPin, 0);
      //move 'em out
      shiftOut(dataPin, clockPin, chromatic[3]);
      shiftOut(dataPin, clockPin, chromatic[2]);
      shiftOut(dataPin, clockPin, chromatic[1]);
      shiftOut(dataPin, clockPin, chromatic[0]);
      //return the latch pin high to signal chip that it
      //no longer needs to listen for information
      digitalWrite(latchPin, 1);
      digitalWrite(statusLed, HIGH);
    }
    // ***** check byte count
    else if ( (byteCount == 2) && (incomingByte <= 127) && (action == 0) ) { //IF THE FIRST BYTE WAS A NOTE OFF MESSAGE...

      Serial.print("action 0, shifting out note  ");  // *****

      // ***** second byte is note
      /*     if (byteCount == 1) {
        incomingBytea = incomingByte;
        incomingBytea += -55;
        }
      */
      bytenumb = (incomingBytea / 8);  // calculate which array byte 0 ~ 10
      bitnumb  = (incomingBytea % 8);   // calculate which bit  (0 ~ 7)
      chromatic[bytenumb] = bitClear(chromatic[bytenumb], bitnumb);
      //ground latchPin and hold low for as long as you are transmitting
      digitalWrite(latchPin, 0);
      //move 'em out
      shiftOut(dataPin, clockPin, chromatic[3]);
      shiftOut(dataPin, clockPin, chromatic[2]);
      shiftOut(dataPin, clockPin, chromatic[1]);
      shiftOut(dataPin, clockPin, chromatic[0]);

      //return the latch pin high to signal chip that it
      //no longer needs to listen for information
      digitalWrite(latchPin, 1);
      digitalWrite(statusLed, LOW);

      //process Third byte - the velocity
      // check for third byte *****
    } else if ( (byteCount == 3) && (incomingByte <= 127) ) { // if we received note ON message load this byte in the velocity byte


      Serial.print("read velocity  ");  // *****
      Serial.println("");  // *****

      velocity = (action == 1) ? incomingByte : 0;  // ***** set velocity
      note = 255;

      byteCount = 0; // ***** got all three bytes, reset count

      /*****
        } else if ( (incomingByte <= 127) && (action == 0) ) { // if we received note message load this byte in the velocity byte
        velocity = 0;
        note = 255;

      ***/
    }

  }

}

Thanks!
I still had to “reactivate” the transpose part that you “deactivated”, but now it’s working like a charm! No delay or any kind of freeze like before.
Here’s my final working code as an .ino file, as it exceeds the maximum lenght, for anyone curious:

midi_pipe_organ.ino (8.09 KB)