OK, we played around with several numbers/formulars and now the logarithmic output is not perfect, but acceptable.
Using four 8-Pixel-Stick to display the velocity-output of four different decks:
// 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.
}
It is working, but now there is a new challenge: due to contruction-layout I have to mount 2 of the 4 Sticks in reverse order.
So I wonder if there is a way to change the direction of the two sticks pixelsB and pixelsD.
As all sticks use the same function updateVUStrip() I first thought about duplicating that function and make some changes to the > and + in the „for“ part like described here:
https://forums.adafruit.com/viewtopic.php?f=47&t=49649
Tried it, worked in a way, but would need much more modification to the duplicated function.
It might be easier, if I could just reverse the pixel-adressing of the sticks pixelsB and pixelsD (1=8, 2=7, 3=6 etc.).
Does anybody know to do do this?