WS2812B LEDs (w/ WS2812FX library) triggered by Hairless Midi on UNO

Hi everyone!
I'm trying to "command" different FX_MODEs from the WS2812FX library using midi notes from Ableton Live through Hairless Midi.
I have 5 LED stripes of 60 (WS2812B) neopixels (300 in total), and a UNO powered by USB + 2 extra 5v 10A supplies for the LEDs.
I'm giving the signal to the LEDs through pin 8 with 470Ohm resistor across and 1000uf capacitor on the power.

I am able to light up single LEDs with single notes, and to run the WS2812FX library effect modes smoothly but am unable to write the code to trigger certain FX_MODE by a specific note.

The aim being that i attach all of the 128 notes to an FX mode of my choice to be recalled on the piano roll of Ableton live and thus be in sync with tracks being played...

Here is the code that i use for choosing & displaying FX_MODE

#include <WS2812FX.h>

#define LED_PIN    8  // digital pin used to drive the LED strip
#define LED_COUNT 300  // number of LEDs on the strip

WS2812FX ws2812fx = WS2812FX(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  Serial.begin(115200);

  ws2812fx.init();
  ws2812fx.setBrightness(128);

  // parameters: index, start, stop, mode, color, speed, reverse
  //ws2812fx.setSegment(0,  0,  9, FX_MODE_BLINK, 0xFF0000, 1000, false); // segment 0 is leds 0 - 9

       ws2812fx.setSegment(0, 0, 299, FX_MODE_MULTI_STROBE, 0xF65D94, 920, false);  // segment 2 is leds 20 - 29

  ws2812fx.start();
}

void loop() {
  ws2812fx.service();
}

and here the code that blinks LEDs as i press notes on Midi keyboard:

#include <MIDI.h>
#include "FastLED.h" //We are using the FastLED library instead of the Adafruit Neopixel library, to work better with Teensy


#define LED_PIN     8
#define NUM_LEDS    300
#define BRIGHTNESS  90
#define LED_TYPE    WS2812
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];


#define UPDATES_PER_SECOND 200
///////////////////////////////////////// 

struct HairlessMidiSettings : public midi::DefaultSettings
{
   static const bool UseRunningStatus = false;
   static const long BaudRate = 115200;
};
MIDI_CREATE_CUSTOM_INSTANCE(HardwareSerial, Serial, MIDI, HairlessMidiSettings);

///////////////////////////////////////// 

//Palette setup
CRGBPalette16 currentPalette;
TBlendType    currentBlending;
extern CRGBPalette16 RainbowColors;
extern const TProgmemPalette16 RainbowColors_p PROGMEM;


//Set variables for velocity (color) and note (LED position on ring)
uint8_t NewVelocity;
uint8_t NewNote;






void setup()
{
  //MIDI handles to set up actions on note on and note off
  MIDI.setHandleNoteOff(OnNoteOff);
  MIDI.setHandleNoteOn(OnNoteOn) ;
  
  //Setting up LED info for the FastLED library
  FastLED.addLeds<LED_TYPE, 8, GRB >(leds, 300).setCorrection( TypicalLEDStrip );
  FastLED.setBrightness( 200 );
  currentPalette = RainbowColors_p;
  currentBlending = LINEARBLEND;
  
  //Turn on one red LED to show sketch has started
  leds[0] = CRGB::Red;
  FastLED.show();
  delay(1000);
  leds[0] = CRGB::Black;
  FastLED.show();
  delay(1000);
  
  //Print OK for start
  Serial.begin(115200);
// Serial.print("---------------- START SUCCESSFUL ----------------");
}




//*** Running program loop ***
void loop()
{
  //This is all we need, since we have actions set when MIDI is read
MIDI.read();
}


//****************************************
//Functions defined below




//What to do if MIDI note on is read
void OnNoteOn(byte channel, byte note, byte velocity)
{
  NewNote = note;  ///note/8
  //this reduces notes to 16 LEDs - change to suit different setup
  //NewVelocity = 128 - velocity; // do this so palette goes from blue to red with higher velocity
  
  VelocityColorFromPalette( NewVelocity); //Go do the routine we have defined below, to set up color depending on velocity
  
  FastLED.show(); //Turn on that LED when you get back from the color routine
 
  //Uncomment lines below to print values to Serial Monitor if needed 
 Serial.println("Note On, ch=1");
  Serial.print(channel, DEC);
 Serial.println(", NewNote=");
    Serial.println(note, DEC);
 Serial.print(", velocity=");
  Serial.print(velocity, DEC);
  Serial.println();
}


//What to do if MIDI note off is read
void OnNoteOff(byte channel, byte note, byte velocity)
{
  ///////// if i put num_leds - 5 (minus 5) it'll crash, so DON'T!!!!
    /////   test to see if the bastard gets lower than 0 so it won't crash
  if((note <= NUM_LEDS )){ 
    leds[note] = CRGB::Black; //Set color to black instead of going to the color from velocity routine
  }
  FastLED.show(); //turn off that LED by making it black
}


void VelocityColorFromPalette( uint8_t colorIndex)
{
  uint8_t brightness = BRIGHTNESS; //This takes the brightness from the BRIGHTNESS variable we set at the top
  
   colorIndex = NewVelocity; //This makes the colorIndex in the FastLED ColorFromPalette command follow our velocity  
  
  /////   test to see if the bastard gets lower than 0 so it won't crash
  if((NewNote <= NUM_LEDS )){ 
  leds[NewNote] = ColorFromPalette( currentPalette, colorIndex, brightness, currentBlending); //Set those colors and brightness
  } 
    }

Any help is greatly appreciated!
:slight_smile:

I've seen by searching that to accomplish what i want to do without dropouts i would need a ATMega32U4 board like the Pro Micro (which i'm receiving today) and an APA102 Dot Star strip (which, being more expensive, i would like to be "ready" for before i order).

it would be amazing to have an example code line that i could transpose then for each note and effect, like:

void loop() {
  if (MIDI.read())  
     (!note_on)
  {
    note_on = 1;
   
 ws2812fx.setSegment(0, 0, 299, FX_MODE_HYPER_SPARKLE, 0xFF3000, 1000, true);
  }

  else
  {
    note_on = 0;
    ws2812fx.setSegment(0, 0, 0, FX_MODE_HYPER_SPARKLE, 0xFF3000, 1000, true);

(i know that code is gibberish sorry for that:( )

I'm giving the signal to the LEDs through pin 8 with 470Ohm resistor across and 1000uf capacitor on the power.

Do you mean the signal goes through the resistor?

As to the rest you are right, using the Dot Star strips gives you an interruptible data transfer so will work well with a serial input.

However, I am unsure if using USB HID interface alone will do anything to make a difference.

Grumpy_Mike:
Do you mean the signal goes through the resistor?

yes following the Adafruit neopixel überguide...

So follow the Adafruit addressable LED examples and set up the driver for an APA102 type of LED.
Get the MIDI note on number, subtract a constant that represents the difference between the note number and the first one you want to display and set that LED number to a colour.

Do the same for the MIDI note off number only turn the LED off.

Note that MIDI note off can also be indicated by a note on message with the velocity set to zero.