USBMIDI "note" was not declared in this scope

Status
Not open for further replies.

sargentpilcher

Well-known member
So I'm trying to make my code more efficient by cutting down some of the lines required. I've gotten a lot of help from people on this forum that I appreciate so much. Just for an idea of what I'm doing, I'm posting a before and after.

This code works perfectly (Just incredibly slow)

Code:
void OnNoteOn(byte channel, byte note, byte velocity)
  {if (channel = 1 && note == 0)
    {red0 = velocity*2;}
    if (channel = 1 && note == 1)
    {green0 = velocity*2;}
    if (channel = 1 && note == 2)
    {blue0 = velocity*2;}
    strip1.setPixelColor(0, red0, green0, blue0);

So based on recomendations from fellow user "oddson" I'm using a math formula to assign the LED number instead of listing them all manually. So I've modified it to this

Code:
void OnNoteOn(byte channel, byte note, byte velocity);

uint8_t light = usbMIDI.getChannel()+note-1
red[light] = velocity*2
green[light] = velocity*2
blue[light] = velocity*2

    strip1.setPixelColor(light, red[light], green[light], blue[light]);}

However in this code, it is saying that "note" was not declared in this scope. Which to me is weird because "note" isn't declared any differently in the first/working example. I was having the same problem with "channel" until I changed the code to "usbMIDI.getChannel()" (Which may or may not even work), but there isn't an alternative for "note" that I've found. Isn't "note" declared during the "void OnoteOn" part? Aren't these part of the usbMIDI library? Thank you in advance for any help.
 
Last edited:
Switching to three 1D arrays instead of 2D might work but you would have to write ONLY to the relevant color... your code will set the colors all the same to whichever color your last message for that light was...

And you are not dividing the note value by three which is essential to the scheme from the other thread...

The compiler error might just be the unsigned integer declaration for light... (I know I said it might be that type but I also said I was terrible at this part!) ..try integer instead (or better your check the other post).

And paste your full code when looking for help here... especially with compiler problems as the issue is often in the initialization/setup portion you will get more and better assistance if you make it easy to replicate the problem.
 
Last edited:
Switching to three 1D arrays instead of 2D might work but you would have to write ONLY to the relevant color... your code will set the colors all the same to whichever color your last message for that light was...

And you are not dividing the note value by three which is essential to the scheme from the other thread...

The compiler error might just be the unsigned integer declaration for light... (I know I said it might be that type but I also said I was terrible at this part!) ..try integer instead (or better your check the other post).

And paste your full code when looking for help here... especially with compiler problems as the issue is often in the initialization/setup portion you will get more and better assistance if you make it easy to replicate the problem.

I see, yes I will paste the full code and try to explain the situation better. I see what you mean about having three 1d arrays, vs the 2d. I didn't realize I would be running into such problems. Also, I was not dividing by 3 because I did the math on a few example notes and found there would be several values I cannot achieve by doing that. For example, if channel is 1, and note is 3, with this formula "light = channel*42+note/3;" light will be equal to 15, when I want it to be equal to a smaller number. I was taking some liberties with the formula to a) get it working within the sketch at all, and b) make it work within a smaller example. What I am doing right now is I am taking a step back from my 2,500 lines of code sketch for my 144 LED dotstar strip, and using a 4 LED neopixel strip. I was trying to adapt your formula to work in a smaller example, and light 15 exceeded the available values for a 4 pixel strip. Once I get it working on the smaller sketch, I will adapt it to the larger.

Your example compiles just fine, but I'm not getting any output on the LED's. I tried to adapt it into my existing code, but for whatever reason I get similar errors when I try. "Light does not name a type" , "colormatrix does not name a type", "usbMIDI does not name a type".

Here is my entire sketch for the 4 LED sketch that works

Code:
 #include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif

#define PIN 35

Adafruit_NeoPixel strip1 = Adafruit_NeoPixel(4, PIN, NEO_RGB + NEO_KHZ800);

int ledPin =  13;
    uint8_t red0 = 0;
    uint8_t green0 = 0;
    uint8_t blue0 = 0;
    uint8_t red1 = 0;
    uint8_t green1 = 0;
    uint8_t blue1 = 0;
     uint8_t red2 = 0;
    uint8_t green2 = 0;
    uint8_t blue2 = 0;
    uint8_t red3 = 0;
    uint8_t green3 = 0;
    uint8_t blue3 = 0;

    

void OnNoteOn(byte channel, byte note, byte velocity)
{if (note == 72)
  {digitalWrite(ledPin, HIGH);}else
  {if (channel = 1 && note == 0)
    {red0 = velocity*2;}
    if (channel = 1 && note == 1)
    {green0 = velocity*2;}
    if (channel = 1 && note == 2)
    {blue0 = velocity*2;}
    strip1.setPixelColor(0, red0, green0, blue0);
  {{if (channel = 1 && note == 3)
    {red1 = velocity*2;}
    if (channel = 1 && note == 4)
    {green1 = velocity*2;}
    if (channel = 1 && note == 5)
    {blue1 = velocity*2;}
    strip1.setPixelColor(1, red1, green1, blue1);
  {if (channel = 1 && note == 6)
    {red2 = velocity*2;}
    if (channel = 1 && note == 7)
    {green2 = velocity*2;}
    if (channel = 1 && note == 8)
    {blue2 = velocity*2;}
    strip1.setPixelColor(2, red2, green2, blue2);}
    {if (channel = 1 && note == 9)
    {red3 = velocity*2;}
    if (channel = 1 && note == 10)
    {green3 = velocity*2;}
    if (channel = 1 && note == 11)
    {blue3 = velocity*2;}
    strip1.setPixelColor(3, red3, green3, blue3);}
}}}}
  void OnNoteOff(byte channel, byte note, byte velocity)
  {if (note == 72)
    {digitalWrite(ledPin, LOW);}else
     {if (channel = 1 && note == 0)
    {red0 = 0;}
    if (channel = 1 && note == 1)
    {green0 = 0;}
    if (channel = 1 && note == 2)
    {blue0 = 0;}
    strip1.setPixelColor(0, red0, green0, blue0);
 {{if (channel = 1 && note == 3)
    {red1 = 0;}
    if (channel = 1 && note == 4)
    {green1 = 0;}
    if (channel = 1 && note == 5)
    {blue1 = 0;}
    strip1.setPixelColor(1, red1, green1, blue1);
  {if (channel = 1 && note == 6)
    {red2 = 0;}
    if (channel = 1 && note == 7)
    {green2 = 0;}
    if (channel = 1 && note == 8)
    {blue2 = 0;}
    strip1.setPixelColor(2, red2, green2, blue2);}
    {if (channel = 1 && note == 9)
    {red3 = 0;}
    if (channel = 1 && note == 10)
    {green3 = 0;}
    if (channel = 1 && note == 11)
    {blue3 = 0;}
    strip1.setPixelColor(3, red3, green3, blue3);}
}}}}
  void setup()
  {
    strip1.begin();
    strip1.show(); // Initialize all pixels to 'off'
    pinMode(ledPin, OUTPUT);
    usbMIDI.setHandleNoteOff(OnNoteOff);
    usbMIDI.setHandleNoteOn(OnNoteOn);
    digitalWrite(ledPin, HIGH);
    delay(1000);
    digitalWrite(ledPin, LOW);
    delay(1000);
  }

  void loop()
  {
    usbMIDI.read();
    strip1.show(); // Initialize all pixels to 'off'
  }

And this is my code trying to adapt in your formula where I get "light does not name a type" which makes no sense to me since I don't get that error in your code, but when I try to adapt it to mine I get the error. I don't understand what I'm doing differently from you to get the error.

Code:
 #include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif

#define PIN 35

byte channel ;
byte note;
byte velocity;
byte colorMatrix[252][3] ;
int rgb1 = 18;
int rgb2 = 17;
int LEDs = 4;
int light = 0;

Adafruit_NeoPixel strip1 = Adafruit_NeoPixel(4, PIN, NEO_RGB + NEO_KHZ800);

void OnNoteOn(byte channel, byte note, byte velocity);

  light = channel*42+note/3; 
  colorMatrix[light][note%3] = velocity;
  usbMIDI.setHandleNoteOn(OnNoteOn);
  strip1.setPixelColor(light,colorMatrix[light][0],colorMatrix[light][1],colorMatrix[light][2]);
}}}}
  void OnNoteOff(byte channel, byte note, byte velocity)

 light = channel*42+note/3; 
  colorMatrix[light][note%3] = 0;
  usbMIDI.setHandleNoteOff(OnNoteOff);

    strip1.setPixelColor(light, colorMatrix[light][0], colorMatrix[light][1], colorMatrix[light][2]);}


}}}}
  void setup()
  {
    strip1.begin();
    strip1.show(); // Initialize all pixels to 'off'
    pinMode(ledPin, OUTPUT);
    usbMIDI.setHandleNoteOff(OnNoteOff);
    usbMIDI.setHandleNoteOn(OnNoteOn);
    digitalWrite(ledPin, HIGH);
    delay(1000);
    digitalWrite(ledPin, LOW);
    delay(1000);
  }

  void loop()
  {
    usbMIDI.read();
    strip1.show(); // Initialize all pixels to 'off'
  }

I tried switching the order of the "void's" like I noticed you had in yours, but I got the same error.
 
Code:
void OnNoteOn(byte channel, byte note, byte velocity);

  light = channel*42+note/3; 
  colorMatrix[light][note%3] = velocity;
  usbMIDI.setHandleNoteOn(OnNoteOn);
  strip1.setPixelColor(light,colorMatrix[light][0],colorMatrix[light][1],colorMatrix[light][2]);
}}}}

You're missing the opening curly braces "{". For each "}", you need a "{".

Also, do not put a semicolon ";" after the function declaration rather than a definition. Background info here:

http://www.cprogramming.com/declare_vs_define.html

Edit - in this case, you probably meant to have just one pair of braces, perhaps like this?

Code:
void OnNoteOn(byte channel, byte note, byte velocity)
{
  light = channel*42+note/3; 
  colorMatrix[light][note%3] = velocity;
  usbMIDI.setHandleNoteOn(OnNoteOn);
  strip1.setPixelColor(light,colorMatrix[light][0],colorMatrix[light][1],colorMatrix[light][2]);
}
 
Last edited:
You should also consider using a more conventional indenting style. Try clicking Tools > Auto Format. When your code is properly indented, simple mistakes that would have been very difficult to understand become immediately obvious just by looking at the horizontal indenting.
 
Last edited:
Code:
#include <Adafruit_NeoPixel.h>
#define PIN 35 // pin number for data connection to stip 
#define LIGHTS 4 // number of lights in strip

byte colorMatrix[16*42][3] ; // 2D matrix to hold velocity readings - index is for light number 
unsigned int light; // light is cacluatated by multiplying zero-indexed channel ID * 42 lights per channel + integer trunc of note/3

Adafruit_NeoPixel strip1 = Adafruit_NeoPixel(LIGHTS, PIN, NEO_RGB + NEO_KHZ800); // initialize pixel object

void setup(){
  usbMIDI.setHandleNoteOn(OnNoteOn);
  strip1.begin();
  strip1.show(); // Initialize all pixels to 'off'
}

void loop(){
  usbMIDI.read();
  //strip1.show(); // Initialize all pixels to 'off' // really -- every cycle!!!!! I've commented out assuming this is not correct!!!
}

void OnNoteOn(byte channel, byte note, byte velocity){
  light = channel*42+note/3; // calculate which light the message is for
  // note%3 returns an index for the three RGB positions 0,1,2 based on the remainder when the note is divided by three!
  colorMatrix[light][note%3] = velocity*2; // read the velocity and scale to 8-bit from 7 and write to matrix
  // could make set pixel conditional to blue updates (if (note%3 = 2)...) if you make sure all three are sent in order when a light's values are changed
  // this wouild prevent updates before all values are available to avoid incorrect colors being displayed wiht R and G valeues being sent
  strip1.setPixelColor(light,colorMatrix[light][0],colorMatrix[light][1],colorMatrix[light][2]);
}
This is my code for this cleaned up a bit and with some bone-head stuff from the other thread fixed... (calling setHandle... in the function call and not in set up for example).

(For others reading that may be puzzled... OP want to control LED strips with individual MIDI note messages for each color value (RGB) so there are 3 MIDI messages required to set the color of a single pixel... my suggestion was to use a two-dimensional array to keep track of the current settings.)

As Paul said.. indenting consistently makes code much more readable...

The order of calls doesn't seem to matter; I believe setup is called and then loop and everything else must be called by one or the other of those.

Your code was limiting to 4 pixels - I've left that assuming it was a testing thing but I've moved it into a #define statement - increase that to the actual number of pixels...

When this doesn't work 100% (nothing ever does on the first go) you may want to use serialPrint() commands to write to the serial monitor with the values calculated to make sure the numbers are what you expect.

And make sure channel is returning 0-15 and not 1-16... if the latter you have to subtract 1 to get the zero-index math to work (so that it starts on light 0 and not light 15).

...and maybe you should go back and do some of Pauls tutorials on the basics to help sort out the inevitable problems that will remain.
 
Last edited:
...make sure channel is returning 0-15 and not 1-16... if the latter you have to subtract 1 to get the zero-index math to work (so that it starts on light 0 and not light 15)...
The usbmidi page indicates 1-16... so I think you do have to correct.

light = (channel -1)*42+note/3;

I think!
 
All statements like this are wrong:
Code:
  {if (channel = 1 && note == 0)

It should be:
Code:
  {if (channel == 1 && note == 0)

Pete
 
Well I got it working! Fully functional across the entire strip. The sketch went from 7% of storage space and 2% of RAM down to 2% of storage space and 2% of RAM. 2,500 lines of code condensed into about 45. Thank you so much Oddson and PaulStoffregen for helping a newb like me out. Using the 2D array and having channel*42 + note/3 was ingenius (I ended up doing (channel*42) -42 +note/3 to compensate for a lack of midi channel 0). I spent all week in between work researching how arrays worked and finally wrapped my head around it, and the code is running just as it should on my computer.

Unfortunately it didn't fix the problems I was having of updating the strip quite slowly. For example, if I try to light up the entire strip white by sending 432 MIDI on messages to it, it still gets overloaded and it gives the appearance of the dotstar strip "loading" as it's not very responsive once you have high nimbers of notes going at it. I realize it wasn't necessarily designed for this, and it's probably a limitation of the dotstars and not the Teensy.

Do you think the Octo adapter would help for my needs?

This is a wonderful community here and I thank you so much for all of your help!
 
Last edited:
Status
Not open for further replies.
Back
Top