So I've set up an Arudino to receive MIDI input and use that to control an APA102 LED strip, but am having some trouble figuring out how to get the LEDs to display more synchronously. As a test, I have each MIDI note corresponding to a single LED on the strip - note value 0 turns on/off LED position 0, value 1 controls LED position 1, etc.
When I have the loop run FastLED.show() by itself, the strip displays all the LEDs correctly (i.e. no MIDI messages dropped), up to 25 notes - anything more than that, and MIDI messages get dropped (i.e. an LED not turning on). Problem is, there is a noticeable delay between each note, and so you can see each LED light up one by one in order.
As an experiment, I tried putting a conditional around the show function:
if (!MIDI.read()) { FastLED.show(); }
...which I know is not ideal, but it looks like I do get a more synchronous result. There's still a slight delay between LEDs lighting up, but it's definitely much better than before. The problem now is that random MIDI messages get missed regularly. Furthermore, the Arduino will crash occasionally, which I still have yet to figure out the reason why.
It seems like without the "if" statement, the Arduino is at least still reading all the MIDI correctly and queuing the data up, but is taking time to display everything. Having the "if" statement for some reason makes the output side faster, but in turn other problems get introduced.
#include "FastLED.h"
#include <MIDI.h>
FASTLED_USING_NAMESPACE
#if defined(FASTLED_VERSION) && (FASTLED_VERSION < 3001000)
#warning "Requires FastLED 3.1 or later; check github for latest code."
#endif
MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI);
#define DATA_PIN_C 3
#define CLK_PIN_C 4
#define COLOR_ORDER BGR
#define LED_TYPE APA102
#define NUM_LEDS_C 50
#define BRIGHTNESS 30
CRGB leds_C1[NUM_LEDS_C];
//MIDI variables
byte midi_on = 0x90;
byte midi_off = 0x80;
byte location_byte;
byte channel;
byte note;
byte velocity;
byte midiNote[2][128];
boolean newNote = false;
void setup() {
delay(3000);
MIDI.begin(MIDI_CHANNEL_OMNI);
// tell FastLED about the LED strip configuration
FastLED.addLeds<LED_TYPE,DATA_PIN_C,CLK_PIN_C,COLOR_ORDER>(leds_C1, NUM_LEDS_C).setCorrection(TypicalLEDStrip);
// set master brightness control
FastLED.setBrightness(BRIGHTNESS);
set_max_power_in_volts_and_milliamps(5, 10000);
}
void loop() {
if (MIDI.read()) {
location_byte = MIDI.getType();
channel = MIDI.getChannel();
note = MIDI.getData1();
velocity = MIDI.getData2();
if (location_byte == midi_on || location_byte == midi_off) newNote = true;
}
if (newNote) {
if (location_byte == midi_on) {
midiNote[channel][note] = 1;
}
if (location_byte == midi_off) {
midiNote[channel][note] = 0;
}
newNote = false;
}
channel = 1;
if (midiNote[1][60] == 1) { leds_C1[0] = CRGB::Blue;}
else if (midiNote[1][60] == 0) { leds_C1[0] = CRGB::Black;}
if (midiNote[1][61] == 1) { leds_C1[1] = CRGB::Red;}
else if (midiNote[1][61] == 0) { leds_C1[1] = CRGB::Black;}
if (midiNote[1][62] == 1) { leds_C1[2] = CRGB::Green;}
else if (midiNote[1][62] == 0) { leds_C1[2] = CRGB::Black;}
if (midiNote[1][63] == 1) { leds_C1[3] = CRGB::Blue;}
else if (midiNote[1][63] == 0) { leds_C1[3] = CRGB::Black;}
if (midiNote[1][64] == 1) { leds_C1[4] = CRGB::Red;}
else if (midiNote[1][64] == 0) { leds_C1[4] = CRGB::Black;}
if (midiNote[1][65] == 1) { leds_C1[5] = CRGB::Green;}
else if (midiNote[1][65] == 0) { leds_C1[5] = CRGB::Black;}
if (midiNote[1][66] == 1) { leds_C1[6] = CRGB::Blue;}
else if (midiNote[1][66] == 0) { leds_C1[6] = CRGB::Black;}
if (midiNote[1][67] == 1) { leds_C1[7] = CRGB::Red;}
else if (midiNote[1][67] == 0) { leds_C1[7] = CRGB::Black;}
if (midiNote[1][68] == 1) { leds_C1[8] = CRGB::Green;}
else if (midiNote[1][68] == 0) { leds_C1[8] = CRGB::Black;}
if (midiNote[1][69] == 1) { leds_C1[9] = CRGB::Blue;}
else if (midiNote[1][69] == 0) { leds_C1[9] = CRGB::Black;}
if (midiNote[1][70] == 1) { leds_C1[10] = CRGB::Red;}
else if (midiNote[1][70] == 0) { leds_C1[10] = CRGB::Black;}
if (midiNote[1][71] == 1) { leds_C1[11] = CRGB::Green;}
else if (midiNote[1][71] == 0) { leds_C1[11] = CRGB::Black;}
if (midiNote[1][72] == 1) { leds_C1[12] = CRGB::Blue;}
else if (midiNote[1][72] == 0) { leds_C1[12] = CRGB::Black;}
if (midiNote[1][73] == 1) { leds_C1[13] = CRGB::Red;}
else if (midiNote[1][73] == 0) { leds_C1[13] = CRGB::Black;}
if (midiNote[1][74] == 1) { leds_C1[14] = CRGB::Green;}
else if (midiNote[1][74] == 0) { leds_C1[14] = CRGB::Black;}
if (midiNote[1][75] == 1) { leds_C1[15] = CRGB::Blue;}
else if (midiNote[1][75] == 0) { leds_C1[15] = CRGB::Black;}
if (midiNote[1][76] == 1) { leds_C1[16] = CRGB::Red;}
else if (midiNote[1][76] == 0) { leds_C1[16] = CRGB::Black;}
if (midiNote[1][77] == 1) { leds_C1[17] = CRGB::Green;}
else if (midiNote[1][77] == 0) { leds_C1[17] = CRGB::Black;}
if (midiNote[1][78] == 1) { leds_C1[18] = CRGB::Blue;}
else if (midiNote[1][78] == 0) { leds_C1[18] = CRGB::Black;}
if (midiNote[1][79] == 1) { leds_C1[19] = CRGB::Red;}
else if (midiNote[1][79] == 0) { leds_C1[19] = CRGB::Black;}
if (midiNote[1][80] == 1) { leds_C1[20] = CRGB::Green;}
else if (midiNote[1][80] == 0) { leds_C1[20] = CRGB::Black;}
if (midiNote[1][81] == 1) { leds_C1[21] = CRGB::Blue;}
else if (midiNote[1][81] == 0) { leds_C1[21] = CRGB::Black;}
if (midiNote[1][82] == 1) { leds_C1[22] = CRGB::Red;}
else if (midiNote[1][82] == 0) { leds_C1[22] = CRGB::Black;}
if (midiNote[1][83] == 1) { leds_C1[23] = CRGB::Green;}
else if (midiNote[1][83] == 0) { leds_C1[23] = CRGB::Black;}
if (midiNote[1][84] == 1) { leds_C1[24] = CRGB::Blue;}
else if (midiNote[1][84] == 0) { leds_C1[24] = CRGB::Black;}
if (midiNote[1][85] == 1) { leds_C1[25] = CRGB::Red;}
else if (midiNote[1][85] == 0) { leds_C1[25] = CRGB::Black;}
if (midiNote[1][86] == 1) { leds_C1[26] = CRGB::Green;}
else if (midiNote[1][86] == 0) { leds_C1[26] = CRGB::Black;}
if (midiNote[1][87] == 1) { leds_C1[27] = CRGB::Blue;}
else if (midiNote[1][87] == 0) { leds_C1[27] = CRGB::Black;}
if (midiNote[1][88] == 1) { leds_C1[28] = CRGB::Red;}
else if (midiNote[1][88] == 0) { leds_C1[28] = CRGB::Black;}
if (midiNote[1][89] == 1) { leds_C1[29] = CRGB::Green;}
else if (midiNote[1][89] == 0) { leds_C1[29] = CRGB::Black;}
// if (!MIDI.read()) { FastLED.show(); }
FastLED.show();
}
Side note - I know having a million "if" statements is not ideal, but I've tried messing around with using "switch/case" statements instead and still seem to get the same issue, so it doesn't seem to be a huge factor here.
Any suggestions?