Not sure why my LED won't light up?

Hi there,

I'm currently at the very very early stages of making my own LED MIDI reactive strip so that when a key is pressed on the piano then an LED (will eventually be 2 LEDs) will light up.

So far I've managed to get a simple MIDI read document working with my DAW and I'm getting the notes going from my piano into the DAW and then sent out to my Arduino board (using an Arduino Pro Micro Leonardo).

Next I've been trying to get just one LED to light up whenever a key is pressed on the piano by placing some code (using the FastLEDS library) into the noteOn function and was hoping that whenever (at this point) any key is pressed that the first LED would light up.

That's unfortunately not happening though. If I take this code from the noteOn function :

  leds[0] = CRGB::Red;
  FastLED.show();

and place it into say just for now the setup function then the first LED does indeed light up however that code never fires when it's placed inside the noteOn function :frowning:

I'm very new to Arduino and coding so not really too sure what I'm missing. It's probably going to be something very easy somewhere but I've been moving code back and forth for hours now and seem to be able to get LEDs to light up every which way except for when I want them to light up! :frowning:

If anyone could possibly point me in the right direction as to why the LED code isn't firing when placed in the noteOn function then I'd be very greatful.

My full code currently is below :

/*
   MIDIUSB_test.ino

   Created: 4/6/2015 10:47:08 AM
   Author: gurbrinder grewal
   Modified by Arduino LLC (2015)
*/

#include "MIDIUSB.h"
#include "FastLED.h"
#define NUM_LEDS 2  // # of LEDS in the strip
CRGB leds[NUM_LEDS];
#define PIN 3 // Output Pin to Data Line on Strip
#define COLOR_ORDER GRB  // I had to change this for my strip if your color is off then you know.
int fadeAmount = 5;  // Set the amount to fade I usually do 5, 10, 15, 20, 25 etc even up to 255.
int brightness = 0;


void setup() {
  // sanity check delay - allows reprogramming if accidently blowing power w/leds
  delay(2000);
  FastLED.addLeds<WS2812, PIN, GRB>(leds, NUM_LEDS);  // GRB ordering is typical
  Serial.begin(115200);
}

// First parameter is the event type (0x0B = control change).
// Second parameter is the event type, combined with the channel.
// Third parameter is the control number number (0-119).
// Fourth parameter is the control value (0-127).

void controlChange(byte channel, byte control, byte value) {
  midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
  MidiUSB.sendMIDI(event);
}

void loop() {
  
  midiEventPacket_t rx;
  do {
    rx = MidiUSB.read();
    if (rx.header != 0) {
      Serial.print("Received: ");
      Serial.print(rx.header, HEX);
      Serial.print("-");
      Serial.print(rx.byte1, HEX);
      Serial.print("-");
      Serial.print(rx.byte2, HEX);
      Serial.print("-");
      Serial.println(rx.byte3, HEX);
    }
  } while (rx.header != 0);
}

// First parameter is the event type (0x09 = note on, 0x08 = note off).
// Second parameter is note-on/note-off, combined with the channel.
// Channel can be anything between 0-15. Typically reported to the user as 1-16.
// Third parameter is the note number (48 = middle C).
// Fourth parameter is the velocity (64 = normal, 127 = fastest).

void noteOn(byte channel, byte pitch, byte velocity) {
  // Turn the first LED on the strip on
  leds[0] = CRGB::Red;
  FastLED.show();

  midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOff);
  // Now turn the LED off
  leds[0] = CRGB::Black;
  FastLED.show();
}

Many thanks for any help anyone can throw my way on this.

Best wishes,

Mark

Where in the code is the noteOn() function called ?

UKHeliBob:
Where in the code is the noteOn() function called ?

That's a very good question!
I've actually taken most of that code from the MIDIUSB example called MIDIUSB_read and then added a tiny bit of FASTLED code to it.
As the MIDIUSB_read code was working fine before I added the LED code I was thinking that it must all be needed code and working but I see what you're saying now. Looking at the MIDIUSB docs it says to place those noteOn and noteOff functions in there but admittedly they are never being called are they?!
I'm not too sure of what to do in that case unless I perhaps call them constantly from within the main loop?

Thanks,
Mark

UKHeliBob:
Where in the code is the noteOn() function called ?

What I don't understand though is that if I change the main loop to this instead :

void loop() {
  midiEventPacket_t rx;
  do {
    rx = MidiUSB.read();
    if (rx.header != 0) {

  leds[0] = CRGB::Red;
  FastLED.show();
  delay(500);
  leds[0] = CRGB::Black;
  FastLED.show();

      
      Serial.print("Received: ");
      Serial.print(rx.header, HEX);
      Serial.print("-");
      Serial.print(rx.byte1, HEX);
      Serial.print("-");
      Serial.print(rx.byte2, HEX);
      Serial.print("-");
      Serial.println(rx.byte3, HEX);
    }
  } while (rx.header != 0);
}

where I've added in the LED light up code just above where it spits out the note information to the serial monitor then the LED does light up but it stays on and doesn't do what I would have expected it to do which is to light up and then wait a while and then turn off and rinse and repeat.
I'm obviously missing something very obvious here?
Thanks,
Mark

In that test code NoteOn() and NoteOff() are intended to SEND MIDI messages. They are only actually used in the MIDI_write example (and no I don't know why the library author left them in here).

In this MIDI_read example only the code in loop() is used and that is intended to READ MIDI messages and print the results. It doesn't do anything else with the input messages.

You were a lot nearer with the last code I saw from you at Arduino Pro Micro not running code - Project Guidance - Arduino Forum Why didn't you continue with that instead of starting a new thread.

Steve

Hi slipstick,

Apologies if starting a new thread was the wrong thing to do. As mentioned this is all very new to me and I thought I should start a new one as I was adding something different into the mix. I see now that perhaps that wasn't the best of ideas though so sorry for that.

I'm not sure though how my other code was any closer?

The other one was pretty much just the MIDIUSB MIDI_read example that I had going there. With this one I'm trying to get the LED to light up and it's got me completely stumped as to why the LED is lighting up when placed in the loop function (just for testing) but it doesn't flash as I would have thought it should do with the fact that I'm setting the LED to red then waiting a while then setting it to black and so on and so forth. Why it just stays on red is beyond me at the moment.

Well the other code was at least analysing the signal coming in and doing something with it!

But to answer your immediate question the reason the LED seems to stay on is because you set it to black and then almost instantly loop round again and set it back to red. So it is going off but for too short a time for your eyes to detect. For now try putting the set to black AFTER the serial prints and add a delay() after it.

You won't want to do that in a real project because those delays, when the Arduino does nothing at all, almost certainly means you will be missing incoming MIDI messages during those times when you've told the Arduino to ignore everything. I would have though that what you really want is the LED on when a NoteOn arrives and for it to switch off when the NoteOff turns up. No?

Steve

Oh crikey!!!

I swear I honestly had a delay() after that fade to black. Absolutely no idea where it went to!

I've now got the first LED lighting up finally!!

My code so far :

/*
   MIDIUSB_test.ino

   Created: 4/6/2015 10:47:08 AM
   Author: gurbrinder grewal
   Modified by Arduino LLC (2015)
*/

#include "MIDIUSB.h"
#include "FastLED.h"
#define NUM_LEDS 2  // # of LEDS in the strip
CRGB leds[NUM_LEDS];
#define PIN 3 // Output Pin to Data Line on Strip
#define COLOR_ORDER GRB  // I had to change this for my strip if your color is off then you know.
int fadeAmount = 5;  // Set the amount to fade I usually do 5, 10, 15, 20, 25 etc even up to 255.
int brightness = 0;

#define BRIGHTNESS 10
//#define PASSIVE_FPS 120

// First parameter is the event type (0x09 = note on, 0x08 = note off).
// Second parameter is note-on/note-off, combined with the channel.
// Channel can be anything between 0-15. Typically reported to the user as 1-16.
// Third parameter is the note number (48 = middle C).
// Fourth parameter is the velocity (64 = normal, 127 = fastest).



void setup() {
  // sanity check delay - allows reprogramming if accidently blowing power w/leds
  delay(2000);
  FastLED.addLeds<WS2812, PIN, GRB>(leds, NUM_LEDS);  // GRB ordering is typical
  FastLED.setBrightness(BRIGHTNESS);
  FastLED.clear();
  Serial.begin(115200);
}


// First parameter is the event type (0x0B = control change).
// Second parameter is the event type, combined with the channel.
// Third parameter is the control number number (0-119).
// Fourth parameter is the control value (0-127).

void controlChange(byte channel, byte control, byte value) {
  midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
  MidiUSB.sendMIDI(event);
}


// a lookup table to convert pitch to text
char lut[][4] =
{
  "A0", "B0b", "B0", "C1", "D1b", "D1", "E1b", "E1", "F1", "G1b",
  "G1", "A1b", "A1", "B1b", "B1", "C2", "D2b", "D2", "E2b", "E2",
  "F2", "G2b", "G2", "A2b", "A2", "B2b", "B2", "C3", "D3b", "D3",
  "E3b", "E3", "F3", "G3b", "G3", "A3b", "A3", "B3b", "B3", "C4",
  "D4b", "D4", "E4b", "E4", "F4", "G4b", "G4", "A4b", "A4", "B4b",
  "B4", "C5", "D5b", "D5", "E5b", "E5", "F5", "G5b", "G5", "A5b",
  "A5", "B5b", "B5", "C6", "D6b", "D6", "E6b", "E6", "F6", "G6b",
  "G6", "A6b", "A6", "B6b", "B6", "C7", "D7b", "D7", "E7b", "E7",
  "F7", "G7b", "G7", "A7b", "A7", "B7b", "B7", "C8",
};

/*
  convert a pitch to text
  In:
    pitch (21 .. 108)
  Returns:
    note as text; NULL if invalid pitch passed
*/
char* pitchToText(byte pitch)
{
  // check against lowest pitch
  if (pitch < 21)
  {
    Serial.println("Invalid pitch (1)");
    return NULL;
  }
  // check against highest pitch
  if (pitch > 108)
  {
    Serial.println("Invalid pitch (2)");
    return NULL;
  }

  // first 20 are not used
  byte index = pitch - 21;

  // check in case the LUT is not fully populated
  if (index > sizeof(lut) / sizeof(lut[0]))
  {
    Serial.println("Invalid pitch (lookup table too small)");
    return NULL;
  }
  //  Serial.println(index+21);
  //  return lut[index];
}

void noteNumber (byte pitch) {
  byte index = pitch;
  // index gives us the correct MIDI note number on the piano
  // so for instance C3 = 60 and A0 = 21
  //  String message = "MIDI note number = ";
  //  Serial.println(message + index);
  return index;
}



void loop() {

  midiEventPacket_t rx;
  do {
    rx = MidiUSB.read();
    if (rx.header != 0) {

      //      Serial.print("Received: ");
      //      Serial.print(rx.header, HEX);
      //      Serial.print("-");
      //      Serial.print(rx.byte1, HEX);
      //      Serial.print("-");
      //      Serial.print(rx.byte2, HEX);
      //      Serial.print("-");
      //      Serial.println(rx.byte3, HEX);

      if (rx.byte3 != 0) {
        noteNumber(rx.byte2);
        Serial.println("Note on received");
        // Turn the first LED on the strip on
        leds[0] = CRGB::Red;
        FastLED.show();
      }
      else {
        noteNumber(rx.byte2);
        Serial.println("Note off received");
        // Now turn the LED off
        leds[0] = CRGB::Black;
        FastLED.show();
      }

      // Get note as text from pitch
      char *note = pitchToText(rx.byte2);
      // if a valid pitch
      if (note != NULL)
      {
        Serial.println(note);
      }

      //    noteNumber(rx.byte2);




    }
  } while (rx.header != 0);
}

Probably very very messy in places but I'm only learning so please be gentle with me :smiley:

Now I need to figure out how to take the note numbers (will be from 21-108 [A0-C8]) and figure out how to get a strip with 176 LEDs on it so that the strip lights up 2 LEDs for every 'note' on the piano so A0 would light up the first 2 LEDs then Bb0 would light up the next two.

Small steps but it feels like I might be actually going on a journey now finally!

Thanks for all the help so far everyone, it really is very much appreciated.

Best wishes,

Mark

I know less than zero about MIDI but I looked at your code and tried this: Does it provide any value?

/*
   MIDIUSB_test.ino

   Created: 4/6/2015 10:47:08 AM
   Author: gurbrinder grewal
   Modified by Arduino LLC (2015)
*/

// a lookup table to convert pitch to text
const char pitchLUT[][4] =
{
  " A0", "B0b", " B0", " C1", "D1b", " D1", "E1b", " E1", " F1", "G1b",
  " G1", "A1b", " A1", "B1b", " B1", " C2", "D2b", " D2", "E2b", " E2",
  " F2", "G2b", " G2", "A2b", " A2", "B2b", " B2", " C3", "D3b", " D3",
  "E3b", " E3", " F3", "G3b", " G3", "A3b", " A3", "B3b", " B3", " C4",
  "D4b", " D4", " E4b", " E4", " F4", "G4b", " G4", "A4b", "A4", "B4b",
  " B4", " C5", "D5b", " D5", "E5b", " E5", " F5", "G5b", " G5", "A5b",
  " A5", "B5b", " B5", " C6", "D6b", " D6", "E6b", " E6", " F6", "G6b",
  " G6", "A6b", " A6", "B6b", " B6", " C7", "D7b", " D7", "E7b", " E7",
  " F7", "G7b", " G7", "A7b", " A7", "B7b", " B7", " C8",
};

#include "MIDIUSB.h"
#include "FastLED.h"

#define PIN             3       // Output Pin to Data Line on Strip
#define COLOR_ORDER     GRB     // I had to change this for my strip if your color is off then you know.
#define NUM_LEDS        176     // # of LEDS in the strip
#define BRIGHTNESS      10

CRGB leds[NUM_LEDS];
int fadeAmount = 5;  // Set the amount to fade I usually do 5, 10, 15, 20, 25 etc even up to 255.

uint8_t
    pitch;

void setup() 
{
    // sanity check delay - allows reprogramming if accidently blowing power w/leds
    delay(2000);
    FastLED.addLeds<WS2812, PIN, GRB>(leds, NUM_LEDS);  // GRB ordering is typical
    FastLED.setBrightness(BRIGHTNESS);
    FastLED.clear();
    Serial.begin(115200);
}

void loop() 
{ 
    midiEventPacket_t rx = MidiUSB.read();
    if( rx.header != 0 )
    {
        do
        {
            switch( rx.header )
            {
                case    0x08:
                case    0x09:                    
                    pitch = rx.byte2;
                    if( pitch >= 21 && pitch <= 108 )
                    {
                        pitch -= 21;                                          
                        leds[pitch++] = (rx.header == 0x09) ? CRGB::Red : CRGB::Black;
                        leds[pitch] = (rx.header == 0x09) ? CRGB::Red : CRGB::Black;                    
                        FastLED.show();
                        Serial.print( pitchLUT[rx.byte2-21] ); Serial.println( (rx.header == 0x09) ? " on" : " off" );
                        
                    }//if
                    else
                    {
                        //illegal note
                        Serial.println( "Unknown note" );
                         
                    }//else
                    
                break;

                default:
                break;
                
            }//switch
            
            rx = MidiUSB.read();
            
        }while( rx.header != 0 );
        
    }//if
    
}//loop

Hi Blackfin,

Thank you so much for that code. I have to admit that most nearly all of that goes over my head at the moment.

I did try uploading it to my board though (currently I only have 2 LEDs hooked up as waiting for the LED strip to arrive) and the very first LED lit up red but stays on even after I let go of the piano key. The serial monitor states A0 on both for when you press the key and when you let go too.

I'll take a look at the code you've provided though and see if I can somehow figure it all out though may be difficult for me as my coding chops are quite seriously limited at this stage.

Thanks again for the fantastic help though, it really is very much appreciated.

Best wishes,

Mark

OK. Added a serial print of the packet. See what the press and release packets look like:

/*
   MIDIUSB_test.ino

   Created: 4/6/2015 10:47:08 AM
   Author: gurbrinder grewal
   Modified by Arduino LLC (2015)
*/

// a lookup table to convert pitch to text
const char pitchLUT[][4] =
{
  " A0", "B0b", " B0", " C1", "D1b", " D1", "E1b", " E1", " F1", "G1b",
  " G1", "A1b", " A1", "B1b", " B1", " C2", "D2b", " D2", "E2b", " E2",
  " F2", "G2b", " G2", "A2b", " A2", "B2b", " B2", " C3", "D3b", " D3",
  "E3b", " E3", " F3", "G3b", " G3", "A3b", " A3", "B3b", " B3", " C4",
  "D4b", " D4", " E4b", " E4", " F4", "G4b", " G4", "A4b", "A4", "B4b",
  " B4", " C5", "D5b", " D5", "E5b", " E5", " F5", "G5b", " G5", "A5b",
  " A5", "B5b", " B5", " C6", "D6b", " D6", "E6b", " E6", " F6", "G6b",
  " G6", "A6b", " A6", "B6b", " B6", " C7", "D7b", " D7", "E7b", " E7",
  " F7", "G7b", " G7", "A7b", " A7", "B7b", " B7", " C8",
};

#include "MIDIUSB.h"
#include "FastLED.h"

#define PIN             3       // Output Pin to Data Line on Strip
#define COLOR_ORDER     GRB     // I had to change this for my strip if your color is off then you know.
#define NUM_LEDS        176     // # of LEDS in the strip
#define BRIGHTNESS      10

CRGB leds[NUM_LEDS];
int fadeAmount = 5;  // Set the amount to fade I usually do 5, 10, 15, 20, 25 etc even up to 255.

uint8_t
    pitch;
char
    szStr[40];

void setup() 
{
    // sanity check delay - allows reprogramming if accidently blowing power w/leds
    delay(2000);
    FastLED.addLeds<WS2812, PIN, GRB>(leds, NUM_LEDS);  // GRB ordering is typical
    FastLED.setBrightness(BRIGHTNESS);
    FastLED.clear();
    Serial.begin(115200);
}

void loop() 
{ 
    midiEventPacket_t rx = MidiUSB.read();
    if( rx.header != 0 )
    {
        do
        {
            sprintf( szStr, "Packet: %02X - %02X - %02X - %02X",
                rx.header,
                rx.byte1,
                rx.byte2,
                rx.byte3 );                
            Serial.println( szStr ); 
            
            switch( rx.header )
            {
                case    0x08:
                case    0x09:                                    
                    pitch = rx.byte2;
                    if( pitch >= 21 && pitch <= 108 )
                    {
                        pitch -= 21;                                          
                        leds[pitch++] = (rx.header == 0x09) ? CRGB::Red : CRGB::Black;
                        leds[pitch] = (rx.header == 0x09) ? CRGB::Red : CRGB::Black;                    
                        FastLED.show();
                        Serial.print( pitchLUT[rx.byte2-21] ); Serial.println( (rx.header == 0x09) ? " on" : " off" );
                        
                    }//if
                    else
                    {
                        //illegal note
                        Serial.println( "Unknown note" );
                         
                    }//else
                    
                break;

                default:
                break;
                
            }//switch
            
            rx = MidiUSB.read();
            
        }while( rx.header != 0 );
        
    }//if
    
}//loop

Hi again,

Okay with that code I get this happening. When I press the first piano key (A0) this shows in the serial monitor :

Packet: 09 - 90 - 15 - 30
 A0 on
Packet: 09 - 90 - 15 - 00
 A0 on

and the first two LEDs (0&1) light up and stay lit even when I let go of the piano key.

When I press the next piano key B0b I get :

Packet: 09 - 90 - 16 - 2C
B0b on
Packet: 09 - 90 - 16 - 00
B0b on

The first two LEDs are still on and the third LED (2) lights up and stays on.

Next when I press B0 I get :

Packet: 09 - 90 - 17 - 30
 B0 on
Packet: 09 - 90 - 17 - 00
 B0 on

and the fourth LED (3) lights up and stays on.

So none of the LEDs ever go off again when I let go of the piano key and also they're saying on both when pressing the key and when letting go of it.

markbowenpiano:
Hi again,

Okay with that code I get this happening. When I press the first piano key (A0) this shows in the serial monitor :

Packet: 09 - 90 - 15 - 30

A0 on
Packet: 09 - 90 - 15 - 00
A0 on

So perhaps I misinterpreted your first post where if rx.header == 0x09 then noteOn and if == 0x08 then noteOff.

I assume these two messages correspond to you pressing the key (09-90-15-30) and then releasing (09-90-15-00). Is that correct?

If so: Is the note off indication that rx.byte3 == 0x00?

Blackfin:
So perhaps I misinterpreted your first post where if rx.header == 0x09 then noteOn and if == 0x08 then noteOff.

I assume these two messages correspond to you pressing the key (09-90-15-30) and then releasing (09-90-15-00). Is that correct?

If so: Is the note off indication that rx.byte3 == 0x00?

Trust me, I'm sure you're understanding this a LOT more than me :slight_smile: :wink: :slight_smile:
It's all really starting to go over my head a little at this point. To be honest I wasn't even sure what those 3 bytes represented and I was guessing just from what I was seeing coming up when I was pressing different keys that byte 3 is the velocity of how hard the key is pressed as it's always 0 when you let go of the key and different numbers when you hit the keys harder or softer so I was using that in my if clause to see if a note had been pressed or not.
I believe the first byte is the MIDI channel that is being transmitted, the second byte is the note value and the third byte is the velocity. That's what I took from it all anyway.
I believe those values are HEX though and I'm not sure about HEX at all so really don't know what those numbers mean or how to understand them :frowning:

Just for giggles, try replacing the case 0x08/0x09 with this:

                case    0x09:                                    
                    pitch = rx.byte2;
                    if( pitch >= 21 && pitch <= 108 )
                    {
                        pitch -= 21;                                          
                        leds[pitch++] = (rx.byte3 == 0x00) ? CRGB::Black : CRGB::Red;
                        leds[pitch] = (rx.byte3 == 0x00) ? CRGB::Black : CRGB::Red;                    
                        FastLED.show();
                        Serial.print( pitchLUT[rx.byte2-21] ); Serial.println( (rx.byte3 == 0x00) ? " off" : " on" );
                        
                    }//if
                    else
                    {
                        //illegal note
                        Serial.println( "Unknown note" );
                         
                    }//else
                    
                break;

Here's a revised version. Everything I've found so far says that an event type '8' is a note "off".

/*
   MIDIUSB_test.ino

   Created: 4/6/2015 10:47:08 AM
   Author: gurbrinder grewal
   Modified by Arduino LLC (2015)
*/

// a lookup table to convert pitch to text
const char pitchLUT[][4] =
{
  " A0", "B0b", " B0", " C1", "D1b", " D1", "E1b", " E1", " F1", "G1b",
  " G1", "A1b", " A1", "B1b", " B1", " C2", "D2b", " D2", "E2b", " E2",
  " F2", "G2b", " G2", "A2b", " A2", "B2b", " B2", " C3", "D3b", " D3",
  "E3b", " E3", " F3", "G3b", " G3", "A3b", " A3", "B3b", " B3", " C4",
  "D4b", " D4", " E4b", " E4", " F4", "G4b", " G4", "A4b", "A4", "B4b",
  " B4", " C5", "D5b", " D5", "E5b", " E5", " F5", "G5b", " G5", "A5b",
  " A5", "B5b", " B5", " C6", "D6b", " D6", "E6b", " E6", " F6", "G6b",
  " G6", "A6b", " A6", "B6b", " B6", " C7", "D7b", " D7", "E7b", " E7",
  " F7", "G7b", " G7", "A7b", " A7", "B7b", " B7", " C8",
};

#include "MIDIUSB.h"
#include "FastLED.h"

#define PIN             3       // Output Pin to Data Line on Strip
#define COLOR_ORDER     GRB     // I had to change this for my strip if your color is off then you know.
#define NUM_LEDS        176     // # of LEDS in the strip
#define BRIGHTNESS      10

CRGB leds[NUM_LEDS];
int fadeAmount = 5;  // Set the amount to fade I usually do 5, 10, 15, 20, 25 etc even up to 255.

uint8_t
    evtType,
    evtChan,
    evtPitch,
    evtVel,
    pitch;
char
    szStr[40];

void setup() 
{
    // sanity check delay - allows reprogramming if accidently blowing power w/leds
    delay(2000);
    FastLED.addLeds<WS2812, PIN, GRB>(leds, NUM_LEDS);  // GRB ordering is typical
    FastLED.setBrightness(BRIGHTNESS);
    FastLED.clear();
    Serial.begin(115200);
}

void loop() 
{ 
    if( MidiUSB.available() > 0 )
    {
        while( MidiUSB.available() > 0 )
        {
            midiEventPacket_t rx = MidiUSB.read();
            if( rx.header != 0 )
            {
                sprintf( szStr, "Packet: %02X - %02X - %02X - %02X",
                    rx.header,
                    rx.byte1,
                    rx.byte2,
                    rx.byte3 );                
                Serial.println( szStr ); 

                evtType = (rx.byte1 >> 4) & 0xf;
                evtChan = rx.byte1 & 0xf;                        
                evtPitch = rx.byte2;
                evtVel = rx.byte3;
                switch( evtType )
                {
                    case    0x8:
                    case    0x9:
                        if( pitch >= 21 && pitch <= 108 )
                        {
                            pitch -= 21;                                          
                            leds[pitch] = (evtType == 0x8) ? CRGB::Black : CRGB::Red;
                            leds[pitch+1] = (evtType == 0x8) ? CRGB::Black : CRGB::Red;                    
                                                            
                        }//if
                        else
                        {
                            //illegal note
                            Serial.println( "Unknown note" );
                             
                        }//else
                        
                    break;
    
                    default:
                    break;
                    
                }//switch
            
            }//if
                        
        }//while

        FastLED.show();
        sprintf( szStr, "Type: %1X Chan: %d Note: %s Velocity: %d",
            evtType,
            evtChan,
            pitchLUT[pitch],
            evtVel );
        Serial.print( szStr );
        
        
    }//if
    
}//loop

Hiya,

Unfortunately with that code nothing at all happens now. Nothing lights up and nothing is spat out to the serial monitor.

I was wondering (taking things slightly away from your code for a moment if that's okay?) if it would be possible to let me know why the code below (code I was originally working on) doesn't work though.

The code is much much simpler than yours however I actually understand it all :smiley: and while I'm absolutely certain your code is very probably going to be way more efficient than mine and probably better on resources and all of that I'd love to be able to get something working that I understand each line of and then maybe look at simplifying and making better the code that I have working so that I can understand everything that's going on.

The code I have currently is :

/*
   MBPiano_Piano_Visualiser_Simple.ino   
*/

#include "MIDIUSB.h"
#include "FastLED.h"
#define NUM_LEDS 4  // # of LEDS in the strip
CRGB leds[NUM_LEDS];
#define PIN 3 // Output Pin to Data Line on Strip
#define COLOR_ORDER GRB  // I had to change this for my strip if your color is off then you know.
int fadeAmount = 5;  // Set the amount to fade I usually do 5, 10, 15, 20, 25 etc even up to 255.
int brightness = 0;

#define BRIGHTNESS 10
//#define PASSIVE_FPS 120


void setup() {
  // sanity check delay - allows reprogramming if accidently blowing power w/leds
  delay(2000);
  FastLED.addLeds<WS2812, PIN, GRB>(leds, NUM_LEDS);  // GRB ordering is typical
  FastLED.setBrightness(BRIGHTNESS);
  FastLED.clear();
  Serial.begin(115200);
}



void loop() {

  midiEventPacket_t rx;
  do {
    rx = MidiUSB.read();
    if (rx.header != 0) {

      int ledToLight = rx.byte2 - 21; // Gives a number from 0-88
      Serial.println(ledToLight);
      Serial.println("---------------------------");
      int startLED = ledToLight * 2; // LED to light up first for given key
      Serial.println(startLED);
      int endLED = startLED + 1; // LED + 1
      Serial.println(endLED);
      Serial.println("------------------------------------------------------");


      if (rx.byte3 != 0) {
        //        Serial.println("Note on received");
        // Turn the LEDs on
        //                leds[startLED] = CRGB::Red;
        //        leds[endLED] = CRGB::Red;
        FastLED.show();
      }
      else {
        //        Serial.println("Note off received");
        // Now turn the LEDs off
        //                leds[startLED] = CRGB::Black;
        //        leds[endLED] = CRGB::Black;
        FastLED.show();
      }



    }
  } while (rx.header != 0);
}

This is as you can see very very basic and is spitting out the actual key number from 0-88 and then using very simple maths I'm figuring out which LEDs to light up.

When that code is run everything spits out to the serial monitor perfectly telling me I have the correct numbers for the LEDs.

What doesn't however work is if you uncomment the lines dealing with turning the LEDs on and off :

        // Turn the LEDs on
        leds[startLED] = CRGB::Red;
        leds[endLED] = CRGB::Red;
        FastLED.show();

and

        // Now turn the LEDs off
        leds[startLED] = CRGB::Black;
        leds[endLED] = CRGB::Black;
        FastLED.show();

When I do that I have the first 2 LEDs on my strip lit up constantly and all sorts of serial monitor data sent out :

226
---------------------------
452
453
------------------------------------------------------
0
---------------------------
0
1
------------------------------------------------------
226
---------------------------
452
453
------------------------------------------------------
105
---------------------------
210
211
------------------------------------------------------
-20
---------------------------
-40
-39
------------------------------------------------------
-21
---------------------------
-42
-41
------------------------------------------------------

It actually goes on and on scrolling really fast spitting out tons of stuff and I'm not sure why? Also not sure why the LEDs are turning on by themselves. I really thought I had something very simple here with the fact that I had the correct LED numbers figured out and I'd just be able to light them up then.

If it would be possible to get any help with this then I'd be eternally greatful as this would be something I'd be able to fully understand the code structure of and then I could look at making the code better.

Many thanks,

Mark

With my code above I'm seriously confused because if I hard code the LEDs turning on to say :

leds[0] = CRGB::Red;

and the respective off code :

leds[0] = CRGB::Black;

then the first LED as expected turns on and off when a key is pressed but just can't get it working with the numbers I'm getting back from my cod above :frowning:

I don't think my brain is up to understanding code at all at this point!! :smiley:

Well, it appears that I misunderstand the available() method. This one reverts back to the "original" method:

/*
   MIDIUSB_test.ino

   Created: 4/6/2015 10:47:08 AM
   Author: gurbrinder grewal
   Modified by Arduino LLC (2015)
*/

// a lookup table to convert pitch to text
const char pitchLUT[][4] =
{
  " A0", "B0b", " B0", " C1", "D1b", " D1", "E1b", " E1", " F1", "G1b",
  " G1", "A1b", " A1", "B1b", " B1", " C2", "D2b", " D2", "E2b", " E2",
  " F2", "G2b", " G2", "A2b", " A2", "B2b", " B2", " C3", "D3b", " D3",
  "E3b", " E3", " F3", "G3b", " G3", "A3b", " A3", "B3b", " B3", " C4",
  "D4b", " D4", " E4b", " E4", " F4", "G4b", " G4", "A4b", "A4", "B4b",
  " B4", " C5", "D5b", " D5", "E5b", " E5", " F5", "G5b", " G5", "A5b",
  " A5", "B5b", " B5", " C6", "D6b", " D6", "E6b", " E6", " F6", "G6b",
  " G6", "A6b", " A6", "B6b", " B6", " C7", "D7b", " D7", "E7b", " E7",
  " F7", "G7b", " G7", "A7b", " A7", "B7b", " B7", " C8",
};

#include "MIDIUSB.h"
#include "FastLED.h"

#define PIN             3       // Output Pin to Data Line on Strip
#define COLOR_ORDER     GRB     // I had to change this for my strip if your color is off then you know.
#define NUM_LEDS        176     // # of LEDS in the strip
#define BRIGHTNESS      10

CRGB leds[NUM_LEDS];
int fadeAmount = 5;  // Set the amount to fade I usually do 5, 10, 15, 20, 25 etc even up to 255.

uint8_t
    evtType,
    evtChan,
    evtPitch,
    evtVel,
    pitch;
char
    szStr[40];

void setup() 
{
    // sanity check delay - allows reprogramming if accidently blowing power w/leds
    delay(2000);
    FastLED.addLeds<WS2812, PIN, GRB>(leds, NUM_LEDS);  // GRB ordering is typical
    FastLED.setBrightness(BRIGHTNESS);
    FastLED.clear();
    Serial.begin(115200);
}

void loop() 
{ 
    midiEventPacket_t rx = MidiUSB.read();
    if( rx.header != 0 )
    {
        do
        {
            sprintf( szStr, "Packet: %02X - %02X - %02X - %02X",
                rx.header,
                rx.byte1,
                rx.byte2,
                rx.byte3 );                
            Serial.println( szStr ); 

            evtType = (rx.byte1 >> 4) & 0xf;
            evtChan = rx.byte1 & 0xf;                        
            evtPitch = rx.byte2;
            evtVel = rx.byte3;
            switch( evtType )
            {
                case    0x8:
                case    0x9:
                    if( pitch >= 21 && pitch <= 108 )
                    {
                        pitch -= 21;                                          
                        leds[pitch << 1] = (evtType == 0x8) ? CRGB::Black : CRGB::Red;
                        leds[(pitch << 1)+1] = (evtType == 0x8) ? CRGB::Black : CRGB::Red;                    
                                                        
                    }//if
                    else
                    {
                        //illegal note
                        Serial.println( "Unknown note" );
                         
                    }//else
                    
                break;

                default:
                break;
                
            }//switch

            FastLED.show();
            sprintf( szStr, "Type: %1X Chan: %d Note: %s Velocity: %d",
                evtType,
                evtChan,
                pitchLUT[pitch],
                evtVel );
            Serial.print( szStr );
        
            rx = MidiUSB.read();
            
        }while(rx.header != 0);
        
    }//if
    
}//loop

re your code: Why do you do this (multiply (rx.byte2 - 21) by 2)?

int startLED = ledToLight * 2; // LED to light up first for given key

Blackfin:
Well, it appears that I misunderstand the available() method. This one reverts back to the "original" method:

/*

MIDIUSB_test.ino

Created: 4/6/2015 10:47:08 AM
  Author: gurbrinder grewal
  Modified by Arduino LLC (2015)
*/

// a lookup table to convert pitch to text
const char pitchLUT[][4] =
{
 " A0", "B0b", " B0", " C1", "D1b", " D1", "E1b", " E1", " F1", "G1b",
 " G1", "A1b", " A1", "B1b", " B1", " C2", "D2b", " D2", "E2b", " E2",
 " F2", "G2b", " G2", "A2b", " A2", "B2b", " B2", " C3", "D3b", " D3",
 "E3b", " E3", " F3", "G3b", " G3", "A3b", " A3", "B3b", " B3", " C4",
 "D4b", " D4", " E4b", " E4", " F4", "G4b", " G4", "A4b", "A4", "B4b",
 " B4", " C5", "D5b", " D5", "E5b", " E5", " F5", "G5b", " G5", "A5b",
 " A5", "B5b", " B5", " C6", "D6b", " D6", "E6b", " E6", " F6", "G6b",
 " G6", "A6b", " A6", "B6b", " B6", " C7", "D7b", " D7", "E7b", " E7",
 " F7", "G7b", " G7", "A7b", " A7", "B7b", " B7", " C8",
};

#include "MIDIUSB.h"
#include "FastLED.h"

#define PIN             3       // Output Pin to Data Line on Strip
#define COLOR_ORDER     GRB     // I had to change this for my strip if your color is off then you know.
#define NUM_LEDS        176     // # of LEDS in the strip
#define BRIGHTNESS      10

CRGB leds[NUM_LEDS];
int fadeAmount = 5;  // Set the amount to fade I usually do 5, 10, 15, 20, 25 etc even up to 255.

uint8_t
   evtType,
   evtChan,
   evtPitch,
   evtVel,
   pitch;
char
   szStr[40];

void setup()
{
   // sanity check delay - allows reprogramming if accidently blowing power w/leds
   delay(2000);
   FastLED.addLeds<WS2812, PIN, GRB>(leds, NUM_LEDS);  // GRB ordering is typical
   FastLED.setBrightness(BRIGHTNESS);
   FastLED.clear();
   Serial.begin(115200);
}

void loop()
{
   midiEventPacket_t rx = MidiUSB.read();
   if( rx.header != 0 )
   {
       do
       {
           sprintf( szStr, "Packet: %02X - %02X - %02X - %02X",
               rx.header,
               rx.byte1,
               rx.byte2,
               rx.byte3 );                
           Serial.println( szStr );

evtType = (rx.byte1 >> 4) & 0xf;
           evtChan = rx.byte1 & 0xf;                        
           evtPitch = rx.byte2;
           evtVel = rx.byte3;
           switch( evtType )
           {
               case    0x8:
               case    0x9:
                   if( pitch >= 21 && pitch <= 108 )
                   {
                       pitch -= 21;                                          
                       leds[pitch] = (evtType == 0x8) ? CRGB::Black : CRGB::Red;
                       leds[pitch+1] = (evtType == 0x8) ? CRGB::Black : CRGB::Red;                    
                                                       
                   }//if
                   else
                   {
                       //illegal note
                       Serial.println( "Unknown note" );
                       
                   }//else
                   
               break;

default:
               break;
               
           }//switch

FastLED.show();
           sprintf( szStr, "Type: %1X Chan: %d Note: %s Velocity: %d",
               evtType,
               evtChan,
               pitchLUT[pitch],
               evtVel );
           Serial.print( szStr );
       
           rx = MidiUSB.read();
           
       }while(rx.header != 0);
       
   }//if
   
}//loop




re your code: Why do you do this (multiply (rx.byte2 - 21) by 2)?



int startLED = ledToLight * 2; // LED to light up first for given key

Hi again,
Thanks so much for keeping going with me on this one, it's really very much appreciated.
I'd done that in my code because my coding isn't very good at all and what I was doing was taking the note number that's being played so lets say the second key on the piano which is 1 (as they start at 0) and then if I times the number by 2 then I get the first LED which needs to be lit as I ultimately want to have 2 LEDs lit up per key. So taking the note number I can find the first LED by timesing by 2. Then using that number + 1 gives me the second LED to light up for that key.
I'm really honestly seriously greatful for the code you keep throwing my way although I'd love to be able to understand why the code I posted before doesn't work in any way I'm expecting it to.
It seems to be that I can either get one thing or another working but never the two together :frowning:
So as above where I posted my code, if I hard-code one of the LEDs to turn on when a key is pressed then it works but as soon as I try to insert those variables which figure out which LEDs to light up then it goes completely haywire on the serial monitor!
I'm really at a bit of a loss as to what I'm doing wrong though?
Best wishes,
Mark