Issue with MIDI Controlled LEDs for EDrums

Hello everyone, first time posting here!

I have a Roland TD-17 electric drum kit that has a MIDI out jack. I am sending the MIDI into an UNO to control 4 meters of an Adafruit Neopixel strip. I've managed to get the LEDs quite responsive however I am running into an issue where the LEDs get "stuck" lit up when hitting multiple drums at once. This does not always occur but if I really overload it with "overlapping" MIDI notes (not really because serial port) it happens more often. Here is a video I have uploaded to Youtube showing the issue:

I've attached the schematic I followed to receive MIDI as well as a photo of my breadboard to elaborate. Here is my code:

#include <MIDI.h>
#include <Adafruit_NeoPixel.h>
 
#define PIN 6  //Data pin out to LED strip
#define N_LEDS 240 //4 meters of 60LED per meter

MIDI_CREATE_DEFAULT_INSTANCE();
Adafruit_NeoPixel strip = Adafruit_NeoPixel(N_LEDS, PIN, NEO_GRB + NEO_KHZ800);

int LEDLoc[6] = {-1, 60, 109, 158, 207, 238}; //Used to create regions in strip for each drum

void setup() {
  strip.begin();
  MIDI.begin(MIDI_CHANNEL_OMNI);
  MIDI.setHandleNoteOn(nOn);
  MIDI.setHandleNoteOff(nOff);
}

void loop() {
  MIDI.read();
}

//Two midi notes are assigned to one section of strip to include head and rim shots
void nOn(byte channel, byte pitch, byte velocity) { 
  if(pitch == 38 || pitch == 40){
    att(strip.Color(204, 0, 204), 1); // Snare
  }
  if(pitch == 48 || pitch == 50){
    att(strip.Color(0, 0, 155), 2); // HTom
  }
  if(pitch == 45 || pitch == 47){
    att(strip.Color(0, 155, 0), 3); // LTom
  }
  if(pitch == 43 || pitch == 58){
    att(strip.Color(155, 0, 0), 4); // FTom
  }
  if(pitch == 36){
    att(strip.Color(155, 155, 155), 5); // Kick
  }
}

void nOff(byte channel, byte pitch, byte velocity) { 
  if(pitch == 38 || pitch == 40){
    rel(1); // Snare
  }
  if(pitch == 48 || pitch == 50){
    rel(2); // HTom
  }
  if(pitch == 45 || pitch == 47){
    rel(3); // LTom
  }
  if(pitch == 43 || pitch == 58){
    rel(4); // FTom
  }
  if(pitch == 36){
    rel(5); // Kick
  }
}

//Turns LEDs on when drum is attacked
static void att(uint32_t c, int d) {
  for(uint16_t i=LEDLoc[d-1]+1; i<=LEDLoc[d]; i++) {
      strip.setPixelColor(i, c);
  }
  strip.show();
}

//Turns LEDs off when drum is released
static void rel(int d) {
  for(uint16_t i=LEDLoc[d-1]+1; i<=LEDLoc[d]; i++) {
    strip.setPixelColor(i, 0);
  }
  strip.show();
}

I am sure there is something I am misunderstanding about either the wiring or the "setHandleNoteOff" command. Any help would be much appreciated! :slight_smile:

however I am running into an issue where the LEDs get "stuck" lit up when hitting multiple drums at once.

Yes this is well known.

When you send out the data to an addressable LED strip the timing of the encoded data has to be precise. In order to do that the interrupts need to be turned off. This means that any incoming MIDI data sent during this time will be missed or only partially received. This could cause the jamming up of the code depending on how it is written.

The simplest solution is to use the DotStar type of LED strip. This uses a two line protocol, clock and data and can stand being interrupted so there is no need to turn the interrupts off while refreshing the data. So no MIDI signals are missed.

If this fails to fix it chances are also that your code can't handle running status mode as well, which is sometimes what controllers send when they are busy.

Hey Grumpy Mike. Thank you for the feedback! I went ahead and picked up a DotStar strip to replace the NeoPixel since I can use the NeoPixels for a future project anyway. The LEDs are working great so this thread can be closed up since the problem is solved. However, there's another aspect to this project that is currently giving me trouble. I've made a new post here:

https://forum.arduino.cc/index.php?topic=635182.0