I got a setup with 4 Neopixel-Sticks (8 pixels per stick) which are all aligned to the same complex function (Full topic here). Due to construction-layout I have to mount 2 of the sticks in reverse order, so I also need them to function into the opposite direction.
Most entrys I found about the subject „reverse neopixel order“ are about changing the function. But in my case I got the feeling it would be much easier to change the adressing-order of the 2 reverse-sticks BEFORE they are aligned to the function (pixel1 = pixel8, pixel2 = pixel7, pixel3 = pixel6 etc.).
Does anybody know a way to change the pixel-adressing right at the setup of each neopixel-stick?
My neopixel-setup looks like this:
#define NR_OF_LEDS 8 //Number of leds on each neopixel-strip
// NeoPixel Setup: Number of pixelsA, Pin, Neopixel-Parameter
Adafruit_NeoPixel pixelsA = Adafruit_NeoPixel(NR_OF_LEDS, 25, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel pixelsB = Adafruit_NeoPixel(NR_OF_LEDS, 24, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel pixelsC = Adafruit_NeoPixel(NR_OF_LEDS, 26, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel pixelsD = Adafruit_NeoPixel(NR_OF_LEDS, 27, NEO_GRB + NEO_KHZ800);
void setup() {
//Serial.begin(115200);
pixelsA.begin(); // This initializes the NeoPixel library.
pixelsA.setBrightness(10); // set pixel brightness
pixelsA.clear();//set all leds to off
pixelsB.begin();
pixelsB.setBrightness(10);
pixelsB.clear();
pixelsC.begin();
pixelsC.setBrightness(10);
pixelsC.clear();
pixelsD.begin();
pixelsD.setBrightness(10);
pixelsD.clear();
}
If you have 8 pixels in a strip numbered 0 to 7 and you turn on each one in sequence using a variable to hold the LED number you will address them as LED 0, 1, 2, 3 etc
Examine what happens if you address them as 7 - LED number
Thanks for the reply! Sounds interesting, but I got no idea how/where to start this. Can you give me a bit more advice, please?
What code have you got that writes to any of the LED strips and how do you determine which LED or LEDs to write to ?
Please post an example
Full code below, I use the sticks as VU-Meters showing MIDI-velocity values of 4 different channels. You can read the whole story in this post.
// AdaFruit NeoPixel library
#include <Adafruit_NeoPixel.h>
#ifdef AVR
#include <avr/power.h>
#endif
#define NR_OF_LEDS 8 //Number of leds on each neopixel-strip
// NeoPixel Setup: Number of pixelsA, Pin, 3rd Parameter might have to be changed for older neopixel-strips (see strandtest-example for more possible values)
Adafruit_NeoPixel pixelsA = Adafruit_NeoPixel(NR_OF_LEDS, 25, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel pixelsB = Adafruit_NeoPixel(NR_OF_LEDS, 24, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel pixelsC = Adafruit_NeoPixel(NR_OF_LEDS, 26, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel pixelsD = Adafruit_NeoPixel(NR_OF_LEDS, 27, NEO_GRB + NEO_KHZ800);
void setup() {
//Serial.begin(115200);
pixelsA.begin(); // This initializes the NeoPixel library.
pixelsA.setBrightness(10); // set pixel brightness
pixelsA.clear();//set all leds to off
pixelsB.begin();
pixelsB.setBrightness(10);
pixelsB.clear();
pixelsC.begin();
pixelsC.setBrightness(10);
pixelsC.clear();
pixelsD.begin();
pixelsD.setBrightness(10);
pixelsD.clear();
pinMode(4, OUTPUT);
usbMIDI.setHandleNoteOff(OnNoteOff);
usbMIDI.setHandleNoteOn(OnNoteOn) ;
}
void loop() {
usbMIDI.read(2); // Midi channel to read
}
//MIDI READ
void OnNoteOn(byte channel, byte note, byte velocity) {
if (velocity > 0) {
switch (note) {
case 61:
updateVUStrip( &pixelsA, velocity);
break;
case 62:
updateVUStrip( &pixelsB, velocity);
break;
case 60:
updateVUStrip( &pixelsC, velocity);
break;
case 63:
updateVUStrip( &pixelsD, velocity);
break;
}
}
else {
switch (note) {
case 61:
pixelsA.clear(); //set all leds to off
pixelsA.show(); // This sends the updated pixel to the hardware.
break;
case 62:
pixelsB.clear();
pixelsB.show();
break;
case 60:
pixelsC.clear();
pixelsC.show();
break;
case 63:
pixelsD.clear();
pixelsD.show();
break;
}
}
}
void OnNoteOff(byte channel, byte note, byte velocity) {
switch (note) {
case 61:
pixelsA.clear();
pixelsA.show();
break;
case 62:
pixelsB.clear();
pixelsB.show();
break;
case 60:
pixelsC.clear();
pixelsC.show();
break;
case 63:
pixelsD.clear();
pixelsD.show();
break;
}
}
void updateVUStrip(Adafruit_NeoPixel* neopixel_object, byte velocity){
//original log-value: 2.89, better 2.8
int active_pixel = (2.66 log(velocity)) / 15 NR_OF_LEDS + 1.5; //calculate the number of leds that should be on, 0.5 is to correct the integer rounding errors
neopixel_object->clear();//set all leds to off
for (int current_pixel = 0; current_pixel < active_pixel; current_pixel++) { //switch on the correct number of leds
if (current_pixel >= 7)
neopixel_object->setPixelColor(current_pixel, neopixel_object->Color(255, 0, 0)); // leds in red color
else if (current_pixel < 6)
neopixel_object->setPixelColor(current_pixel, neopixel_object->Color(0, 255, 0)); // leds in green color
else
neopixel_object->setPixelColor(current_pixel, neopixel_object->Color(255, 160, 0)); // leds in orange color
}
neopixel_object->show(); // This sends the updated pixel to the hardware.
}
I have had a quick look at the sketch
Anywhere that you use the current_pixel I assume that it causes something to be written to that pixel. Try using 7 - current_pixel instead and see what effect it has
Basically, if current_pixel equals say 6 then 7 - 6 equals 1 so you will be writing to pixel 1 instead of 6. Do you see how that inverts distance from the end of the strip ?
Well, current_pixel is already part of the function updateVUStrip() which is aligned to all the Neopixel-Sticks. But as I wrote above I am looking for a solution to reverse the adressing of only 2 Sticks right at the setup BEFORE the function - so I can still use the same function for all of the Sticks.
An other approach would be to duplicate the function, make the duplicate work in reverse direction and align it only to the 2 reverse-sticks.
But before I get into this I wanted to know if there is a more basic way to reverse the adressing of pixels right at the setup, maybe in the section „void setup()“ ?
I thought it might be a common request as LED-Strips usually got a specific input-pin on one end and the output-pin on the other end - so it is not possible to just mount them upside-down.
Add a boolean parameter, let's name it reversed, to the function that writes to the LED strip. When the boolean is true write to current_pixel, when it is false write to 7 - current_pixel.
Call the function with the boolean set to true or false as required
An alternative, but clumsy solution, would be to put the LED numbers in an array such that the reversed strips used an array with the LED numbers reversed, so instead of controlling the LED referred to by current_pixel you control the LED referred to by ledNumbers[stripNumber][ ledNumber] with stripNumber being the index to the strip to be controlled
I thought it might be a common request as LED-Strips usually got a specific input-pin on one end and the output-pin on the other end - so it is not possible to just mount them upside-down.
I do not believe that there is such a function, at least I have not found one.
You could, of course, modify the library to do you what want, presumably when the NeoPixel object is created