Go Down

Topic: Problem using Arduino Micro and MIDIUSB library (Read 478 times) previous topic - next topic

Edwin1557

I will try to explain it in a few phrases... I am playing the launchpad, an electronic music instrument, and I want to make what is called a  "launchpad underlights". The goal of this project is to light up the led strip in a way that sort of "react" to a music I want to play. So, im not making this project for visualizing some piano notes, but really to have full control of a light strip and to create light patterns that fits to the music... I hope I'm clear ahahah

Also, I'm using the midi library because my launchpad works with ableton live, and because I can also program some light patterns on my launchpad. Because of that, it is easy to interact between the launchpad and the led strip so that they can "fit" together by having the same pattern, color, etc...

Here's an example of a launchpad underlight : https://youtu.be/hwPdrJmZ-so

Grumpy_Mike

Ok with the launch pad, I have a launch pad mini. Never seen the back lighting however, so thanks.

I think trying to alter 100 LEDs on every note on / off message is too much. Too many LEDs, too many updates. I think you should cut down on both. I am sure you don't need so many LEDs to achieve that result.

Edwin1557

Yeah you are right ahahah!

I will reduce the numbers of leds and updates and everything should be alright.

Again, thank you so much for your help, it is really apprecieted!

Grumpy_Mike

OK how about this for a solution?

Your code is using the MIDI note number to determine the position and the velocity to determine the colour through a look up table. Fine, but the problem is that for 100 LEDs your minimum note number is 36 and you do not have enough note numbers to cover all 100 positions as the biggest note number you can have is 127 so you are 8 short. So your _PStart needs to be set at 28.

Next you are updating the display on every note on and note off message, this is what is killing you. How about if you do refresh the display only when you tell it to. One way of doing this could be to send a note on message with a note number below 28. Then use that velocity to determine if you clear out the buffer after writing to it or you hold it the same for more LEDs to be lit. Any velocity above 64 would wipe the buffer, otherwise the buffer remains preserved. This would give you flexibility and control as to how you update your display.

If you think this is a good idea then the following code might do it. MIDI note off messages are simply ignored.

Code: [Select]

#include "MIDIUSB.h"

const byte _NLED = 100;
const byte _DPIN = 6;

#include <Adafruit_NeoPixel.h>
Adafruit_NeoPixel _LED = Adafruit_NeoPixel(_NLED, _DPIN, NEO_GRB + NEO_KHZ800);

const byte _R[128] = {0, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 45, 93, 142, 223, 190, 28, 61, 93, 190, 125, 12, 28, 45, 158, 61, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 12, 28, 45, 158, 61, 28, 61, 93, 190, 125, 45, 93, 142, 223, 190, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 36, 73, 109, 146, 182, 219, 255};
const byte _G[128] = {0, 0, 0, 0, 125, 0, 12, 28, 45, 158, 61, 28, 61, 93, 190, 125, 45, 93, 142, 223, 190, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 45, 93, 142, 223, 190, 28, 61, 93, 190, 125, 12, 28, 45, 158, 61, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 36, 73, 109, 146, 182, 219, 255};
const byte _B[128] = {0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 0, 0, 0, 125, 0, 12, 28, 45, 158, 61, 28, 61, 93, 190, 125, 45, 93, 142, 223, 190, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 61, 125, 190, 255, 255, 45, 93, 142, 223, 190, 28, 61, 93, 190, 125, 12, 28, 45, 158, 61, 36, 73, 109, 146, 182, 219, 255};
const byte _PStart = 28;  // First note in array

void setup() {
_LED.begin();
_LED.show();
}

void loop() {
  midiEventPacket_t rx;
  do {
    rx = MidiUSB.read();
    if(rx.header == 0x9) setLED(rx.byte2,rx.byte3);
  }
  while (rx.header == 0); // hold until a MIDI message is received
}

void setLED(byte pitch, byte velocity) {
  if (pitch >= 28) {
  _LED.setPixelColor(pitch - _PStart, _R[velocity], _G[velocity], _B[velocity]);
  }
  else {
  _LED.show();
  if(velocity>64){
    wipe();
  }
 }
}

void noteOff(byte channel, byte pitch, byte velocity) {
  _LED.setPixelColor(pitch - _PStart, 0, 0, 0);
  _LED.show();
}

void wipe(){
  for(int i = 0; i< _NLED; i++){
    _LED.setPixelColor(i, 0, 0, 0);
  }
}

   

Edwin1557

Yes it works perfectly!!!  :D

There's now no lag when I play the light effects !

Thank you very much!! Without your help, I would never have finished this project...

Grumpy_Mike

#20
May 19, 2019, 07:40 pm Last Edit: May 19, 2019, 07:40 pm by Grumpy_Mike
Glad that it works, that code while it compiled was not tested.
 
It also occurs to me that you could use the note off message in a combination of not clearing the buffers on write to make some notes / lights stay on for the duration of the MIDI note you program. I am sure you could add that option if you wanted.

Edwin1557

Yeah this is a pretty good idea!

I'll will try to code it...

Go Up