Hello everyone, I've been trying to solve an issue with this project for over a week now, so I have finally decided to ask the community for help. I've attached the sketch and will subsequently post the wiring diagrams in separate posts (new users can only embed one media item per post).
Some of the pin numbers for the buttons/joystick in the sketch might differ slightly from what is in the diagrams, as I am using an Arduino MEGA 2560 instead of Pro Micro. Please let me know if any additional info is needed - Thanks!
I've combined two sketches: This one is the primary sketch. It is a MIDI instrument with 3 softpots that are triggered with 3 piezos or by just holding down a button for legato. The value of each softpot is sent to a different MIDI channel, channels 1,2, and 3. There's a joystick and two pots for additional MIDI CC messages. The 4 buttons are used for Legato, Calibration, Octave +, and Octave -
I copied small pieces of this other sketch to add neopixels that light up where the softpots are touched. This sketch was originally for just 2 softpots, and I suspect that's why only 2 out of the 3 softpots are triggering the neopixels.
In the below sketch - the 3rd softpot works exactly as expected with triggering MIDI notes, but it does not trigger the neopixels when playing the instrument. It does trigger the neopixels during the calibration process (blinks red when touching for calibration like the other 2 softpots).
/*
Arduino Ribbon Synth MIDI controller
------------------------------------
©2014 Dean Miller
*/
#include <EEPROM.h>
#include <Wire.h>
#include <Adafruit_NeoPixel.h>
#include <QuickStats.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
//------- Constants -------//
#define PIEZO_THRESHOLD_ON 12
#define PIN_LED 13
#define NEO_PIN 21
#define N_PIXELS 16 //# of LEDS
#define PIN_SOFTPOT_1 A0
#define PIN_SOFTPOT_2 A1
#define PIN_SOFTPOT_3 A2
#define PIN_PIEZO_1 A3
#define PIN_PIEZO_2 A4
#define PIN_PIEZO_3 A5
#define PIN_POT_1 8
#define PIN_POT_2 6
#define PIN_BUTTON_STICK 3
#define PIN_BUTTON_RIGHT 11
#define PIN_BUTTON_UP 5
#define PIN_BUTTON_DOWN 2
#define PIN_BUTTON_LEFT 7
//Joystick
#define PIN_JOYSTICK_X 9
#define PIN_JOYSTICK_Y 10
//Joystick
#define UP 0
#define RIGHT 1
#define DOWN 2
#define LEFT 3
#define STICK 4
#define PIEZO_SAMPLES 400
#define PADDING 2
#define THRESH 200
#define N_STR 3
#define N_FRET 21
//#define MOD_THRESHOLD 30 //Modulation is not send under this value
long noteDebounceTime = 0;
int noteDebounceDelay = 25;
long lastDebounceTime = 0;
int debounceDelay = 200;
long ledDebounceTime = 0;
int ledDebounceDelay = 20;
int mod_final;
//bool isPitchBend = false;
unsigned int pitchBendLight = 0;
//bool dim = false;
//------Note Class---------//
/*
A note class that stores some info about each note played is necessary
to ensure that open strings are held for the specified amount of time.
That is a problem with using the piezos as triggers instead of FSRs, they
only register momentary impact or vibration, creating a problem for open strings.
*/
class Note {
int _number;
int _velocity;
int _startTime;
int _fretted;
public:
void init(int number, int velocity, int startTime, int fretted) {
_number = number;
_velocity = velocity;
_startTime = startTime;
_fretted = fretted;
}
int number() {
return _number;
}
int velocity() {
return _velocity;
}
int fretted() {
return _fretted;
}
int timeActive() {
return millis() - _startTime;
}
};
//------ Global Variables ---------//
/*
fret defs stored in EEPROM for calibration purposes.
Lower output voltages from USB ports result in different values read from
SoftPots and wonky fret definitions.*/
int F0 = 248; // all bigger softpot values will be treated as open string
int F21 = 0;
int fretDefs[N_STR][N_FRET];
//short fretDefs[N_STR][N_FRET];
int piezoVals[] = {
0, 0, 0
};
int piezoPins[] = {
PIN_PIEZO_1, PIN_PIEZO_2, PIN_PIEZO_3
};
int softPotVals[] = {
0, 0, 0
};
int softPotPins[] = {
PIN_SOFTPOT_1, PIN_SOFTPOT_2, PIN_SOFTPOT_3
};
int potVal1Old = -1;
int potVal2Old = -1;
int softPotValsOld[] = {
0, 0, 0
};
int fretTouched[N_STR];
int noteFretted[N_STR];
int stringActive[] = {
false, false, false
};
int stringPlucked[] = {
false, false, false
};
Note *activeNotes[N_STR];
int calibrationMax[] = {
0, 0, 0
};
int calibrationMin[N_STR];
//true for low strings, false for high strings
int stringSetLow = true;
int octave = 3;
//E A D
int offsets_low[] = {16, 21, 26};
//G B E
int offsets_high[] = {19, 23, 28};
//default offsets
int offsets[] = {52, 57, 62};
//states of control buttons
int buttonStates[] = {
false, false, false, false, false
};
int stickActive = false;
int stickZeroX = 0;
int stickZeroY = 0;
int stickState = false;
int altControlSet = false;
int stickXY = false;
int fullLegatoMode = false;
int minDurationOpen = 75;
int minVelocity = 75;
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(N_PIXELS, NEO_PIN, NEO_GRB + NEO_KHZ800);
int led_number[2] = {0, 0};
int led_color;
int led;
int prev_led;
unsigned long last_read;
QuickStats stats;
//--------- Setup ----------------//
void setup() {
//read fret definitions from EEPROM
for (int i = 0; i < N_STR; i++) {
fretDefs[i][0] = F0;
for (int j = 1; j < 21; j++) {
fretDefs[i][j] = EEPROM.read(j + (21 * i));
}
fretDefs[i][N_FRET] = 0;
calibrationMin[i] = EEPROM.read(21 + (21 * i));
}
//begin at MIDI spec baud rate
//Serial.begin(9600);
//Serial.println("START");
Serial.begin(31250);
pinMode(PIN_SOFTPOT_1, INPUT);
pinMode(PIN_SOFTPOT_2, INPUT);
pinMode(PIN_SOFTPOT_3, INPUT);
pinMode(PIN_PIEZO_1, INPUT);
pinMode(PIN_PIEZO_2, INPUT);
pinMode(PIN_PIEZO_3, INPUT);
digitalWrite(PIN_SOFTPOT_1, HIGH);
digitalWrite(PIN_SOFTPOT_2, HIGH);
digitalWrite(PIN_SOFTPOT_3, HIGH);
pinMode(PIN_BUTTON_RIGHT, INPUT);
digitalWrite(PIN_BUTTON_RIGHT, HIGH);
pinMode(PIN_BUTTON_LEFT, INPUT);
digitalWrite(PIN_BUTTON_LEFT, HIGH);
pinMode(PIN_BUTTON_UP, INPUT);
digitalWrite(PIN_BUTTON_UP, HIGH);
pinMode(PIN_BUTTON_DOWN, INPUT);
digitalWrite(PIN_BUTTON_DOWN, HIGH);
pinMode(PIN_BUTTON_STICK, INPUT);
digitalWrite(PIN_BUTTON_STICK, HIGH);
pinMode(PIN_LED, OUTPUT);
pixels.begin();
pixels.setBrightness(50);
pixels.show();
while (millis() < 500) {
for (int i = 0; i < N_STR; i++) {
int val = analogRead(softPotPins[i]);
if (val > calibrationMax[i]) calibrationMax[i] = val;
}
//calibrate joystick
stickZeroX = analogRead(PIN_JOYSTICK_X);
stickZeroY = analogRead(PIN_JOYSTICK_Y);
}
}
//----------Main Loop---------------//
void loop() {
//reset
for (int i = 0; i < N_STR; i++) {
stringPlucked[i] = false;
piezoVals[i] = false;
}
//read values of all sensors
readSensors();
determineFrets();
//if we are in full legato mode, run the function
if (fullLegatoMode) {
fullLegato();
}
//otherwise just do the regular thing
else {
//test for legato action
legatoTest();
// onLED(N_PIXELS, 0, 0, 0);
//use this info to determine which notes to pluck
pickNotes();
onLED(N_PIXELS, 0, 0, 0);
}
//send not off messages and reset necessary things
cleanUp();
//check for control changes
readControls();
}
void readSensors() {
for (int i = 0; i < N_STR; i++) {
//read piezo vals
int piezoVal = analogRead(piezoPins[i]);
//if the value breaks the threshold read for max amplitude
/* TODO: this is less than ideal. Have it determine which piezos were triggered and
then sample them all at once for better support for polyphonic stuff.
*/
if (piezoVal > PIEZO_THRESHOLD_ON) {
int v_new = piezoVal;
for (int sample = 0; sample < PIEZO_SAMPLES; sample++) {
piezoVal = analogRead(piezoPins[i]);
if (piezoVal > v_new) {
v_new = piezoVal;
}
}
piezoVals[i] = v_new;
piezoVals[i] = map(piezoVals[i], 0, 500, 0, 127);
piezoVals[i] = constrain(piezoVals[i], minVelocity, 127);
}
//read the value of all the softPots
softPotVals[i] = analogRead(softPotPins[i]);
softPotVals[i] = map(softPotVals[i], calibrationMin[i], calibrationMax[i], 0, 255);
softPotVals[i] = constrain(softPotVals[i], 0, 255);
}
}
void determineFrets () {
static int count = 0;
//---------Get Fret Numbers------
for (int i = 0; i < N_STR; i++) {
int softPotVal = softPotVals[i];
//check for open strings
if (softPotVal >= F0) {
softPotValsOld[i] = softPotVal;
fretTouched[i] = 0;
led_number[i] = fretTouched[i];
}
//loop through the array of fret definitions
for (int j = 1; j < N_FRET; j++) {
int k = j - 1;
if (softPotVal <= fretDefs[i][k] &&
softPotVal > fretDefs[i][j] &&
abs(softPotVal - softPotValsOld[i]) > PADDING) {
softPotValsOld[i] = softPotVal;
fretTouched[i] = j-2;
led_number[i] = fretTouched[i];
// Serial.print("string= "); Serial.print(i); Serial.print(" FretTouched= "); Serial.print(j); Serial.print(" softpotval = "); Serial.println(softPotVal); //count=0;}
}
}
if (softPotVal <= fretDefs[i][20]) {
softPotValsOld[i] = softPotVal;
fretTouched[i] = N_FRET;
led_number[i] = fretTouched[i];
}
}
}
void pickNotes() {
for (int i = 0; i < N_STR; i++) {
//if the piezo was hit, play the fretted note
if (piezoVals[i]) {
switch (i) {
case 0:
noteFretted[i] = fretTouched[i] + offsets[i];
break;
case 1:
noteFretted[i] = fretTouched[i] + offsets[i];
break;
case 2:
noteFretted[i] = fretTouched[i] + offsets[i];
break;
}
if (stringActive[i]) {
//turn off the currently active note on that string
noteOff(0x80 + i, activeNotes[i]->number(), 0);
free(activeNotes[i]);
}
if (!stringActive[i]) {
//mark string as active
stringActive[i] = true;
}
//register with active notes
activeNotes[i] = (Note *) malloc(sizeof(Note));
if (fretTouched[i] > 0) activeNotes[i]->init(noteFretted[i], piezoVals[i], millis(), true);
else activeNotes[i]->init(noteFretted[i], piezoVals[i], millis(), false);
//turn on fretted note
noteOn(0x90 + i, activeNotes[i]->number(), activeNotes[i]->velocity());
//mark that the string was plucked
stringPlucked[i] = true;
}
}
}
void legatoTest() {
for (int i = 0; i < N_STR; i++) {
if (stringActive[i]) {
switch (i) {
case 0:
noteFretted[i] = fretTouched[i] + offsets[i];
break;
case 1:
noteFretted[i] = fretTouched[i] + offsets[i];
break;
case 2:
noteFretted[i] = fretTouched[i] + offsets[i];
break;
}
if (noteFretted[i] != activeNotes[i]->number() && fretTouched[i]) {
//turn on new note
int vel = activeNotes[i]->velocity();
noteOn(0x90 + i, noteFretted[i], vel);
//turn off old note
noteOff(0x80 + i, activeNotes[i]->number(), 0);
free(activeNotes[i]);
//register new note as the active one
activeNotes[i] = (Note *) malloc(sizeof(Note));
activeNotes[i]->init(noteFretted[i], vel, millis(), true);
}
}
}
}
/*
*/
void fullLegato() {
for (int i = 0; i < N_STR; i++) {
if (fretTouched[i]) {
switch (i) {
case 0:
noteFretted[i] = fretTouched[i] + offsets[i];
break;
case 1:
noteFretted[i] = fretTouched[i] + offsets[i];
break;
case 2:
noteFretted[i] = fretTouched[i] + offsets[i];
break;
}
int vel = 127;
if (!stringActive[i]) {
noteOn(0x90 + i, noteFretted[i], vel);
//register new note as the active one
activeNotes[i] = (Note *) malloc(sizeof(Note));
activeNotes[i]->init(noteFretted[i], vel, millis(), true);
stringActive[i] = true;
}
else {
if (noteFretted[i] != activeNotes[i]->number()) {
int vel = 80;
noteOn(0x90 + i, noteFretted[i], vel);
//turn off old note
noteOff(0x80 + i, activeNotes[i]->number(), 0);
free(activeNotes[i]);
//register new note as the active one
activeNotes[i] = (Note *) malloc(sizeof(Note));
activeNotes[i]->init(noteFretted[i], vel, millis(), true);
}
}
}
}
}
void cleanUp() {
for (int i = 0; i < N_STR; i++) {
//no fret is touched and the string is marked active
if (!fretTouched[i] && stringActive[i]) {
//if open string
if (!activeNotes[i]->fretted()) {
if (activeNotes[i]->timeActive() > minDurationOpen) {
//turn off the active note
noteOff(0x80 + i, activeNotes[i]->number(), 0);
//mark as inactive
stringActive[i] = false;
free(activeNotes[i]);
}
}
else {
//turn off the active note
noteOff(0x80 + i, activeNotes[i]->number(), 0);
//mark as inactive
stringActive[i] = false;
free(activeNotes[i]);
}
}
}
}
void readControls() {
if (altControlSet) {
minDurationOpen = analogRead(PIN_POT_1);
minDurationOpen = map(minDurationOpen, 0, 1023, 0, 255 );
minVelocity = analogRead(PIN_POT_2);
minVelocity = map(minVelocity, 0, 1023, 0, 127);
}
//Potentiometers set the values for controllers 69 and 7
else {
int potVal1New = analogRead(PIN_POT_1);
int potVal2New = analogRead(PIN_POT_2);
if (abs(potVal1New - potVal1Old) > 30 || potVal1New == 0 || potVal1New == 1023 ) {
if ((potVal1New - potVal1Old) != 0) {
//Send MIDI control change message
int val = map(potVal1New, 0, 1023, 0, 127);
val = constrain(val, 0, 127);
controllerChange(69, val);
potVal1Old = potVal1New;
}
}
if (abs(potVal2New - potVal2Old) > 30 || potVal2New == 0 || potVal2New == 1023) {
if ((potVal2New - potVal2Old) != 0) {
//Send MIDI control change message
int val = map(potVal2New, 0, 1023, 0, 127);
val = constrain(val, 0, 127);
controllerChange(7, val);
potVal2Old = potVal2New;
}
}
}
//-----ENGAGE FULL LEGATO MODE-----
//removes the need for triggering with piezo for fretted notes
if (digitalRead(PIN_BUTTON_LEFT) == LOW && !buttonStates[LEFT]) {
fullLegatoMode = true;
buttonStates[LEFT] = true;
}
if (digitalRead(PIN_BUTTON_LEFT) == HIGH && buttonStates[LEFT]) {
fullLegatoMode = false;
buttonStates[LEFT] = false;
}
led = max(led_number[0],led_number[1]);
Serial.println(led_number[0]);
//Serial.println(led_number[1]);
if (led == -1){
led = 0;
onLED(N_PIXELS,0,0,0);
}
else{
led = led + 1;
led = map(led,0,N_FRET - 1,0,N_PIXELS);
led_color = map(led,0,30,0,255);
//Serial.println(led_number);
if((millis() - ledDebounceTime ) > ledDebounceDelay){
for(int i=0;i<led;i++){
//pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
pixels.setPixelColor(i, Wheel(led_color));
}
if(prev_led > led)
for(int i=led;i<N_PIXELS;i++){
//pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
pixels.setPixelColor(i, (pixels.Color(0, 0, 0)));
}
pixels.show();
ledDebounceTime = millis();
prev_led = led ;
}
}
/*
//switch to alt control set
if (digitalRead(PIN_BUTTON_LEFT) == LOW && !buttonStates[LEFT]) {
altControlSet = !altControlSet;
buttonStates[LEFT] = true;
}
if (digitalRead(PIN_BUTTON_LEFT) == HIGH && buttonStates[LEFT]) buttonStates[LEFT] = false;
//Right button triggers calibration
if (digitalRead(PIN_BUTTON_RIGHT) == LOW && !buttonStates[RIGHT]) {
buttonStates[RIGHT] = true;
calibrate();
}
*/
//---- CHANGING THE OCTAVE -------//
//UP and down buttons used to change offset/octave. Cycles through EAD and GBE like an infinite guitar neck.
//---- UP BUTTON ----
if (digitalRead(PIN_BUTTON_UP) == LOW) {
//change the set of strings
if (!buttonStates[UP]) {
octave = octave - 1;
stringSetLow = !stringSetLow;
for (int i = 0; i < N_STR; i++) {
//if low
if (stringSetLow) {
offsets[i] = offsets_low[i] + (12 * octave);
}
//if high
if (!stringSetLow) {
offsets[i] = offsets_high[i] + (12 * octave);
}
}
}
buttonStates[UP] = true;
}
//reset state once button is no longer being pressed
if (digitalRead(PIN_BUTTON_UP) == HIGH && buttonStates[UP]) buttonStates[UP] = false;
//----DOWN BUTTON----
if (digitalRead(PIN_BUTTON_DOWN) == LOW) {
//change the set of strings
if (!buttonStates[DOWN]) {
octave = octave + 1;
stringSetLow = !stringSetLow;
for (int i = 0; i < N_STR; i++) {
//if low
if (stringSetLow) {
offsets[i] = offsets_low[i] + (12 * octave);
}
//if high
if (!stringSetLow) {
offsets[i] = offsets_high[i] + (12 * octave);
}
}
}
buttonStates[DOWN] = true;
}
//reset state once button is no longer being pressed
if (digitalRead(PIN_BUTTON_DOWN) == HIGH && buttonStates[DOWN]) buttonStates[DOWN] = false;
//switch stick to xy mode
if (digitalRead(PIN_BUTTON_RIGHT) == LOW && !buttonStates[RIGHT]) {
stickXY = !stickXY;
buttonStates[RIGHT] = true;
}
if (digitalRead(PIN_BUTTON_RIGHT) == HIGH && buttonStates[RIGHT]) buttonStates[RIGHT] = false;
//--------JOYSTICK-------//
/* Click down the joystick to activate it. In regular mode it will read absolute position from the
center in any direction (sends to modwheel, MIDI controller 1), and in XY mode the x axis
sends to controller 2 (breath) and the y axis sends to controller 4 (foot). */
if (digitalRead(PIN_BUTTON_STICK) == LOW) {
//activate joystick
if (!buttonStates[STICK]) {
//make sure modwheel value is set to 0 when stick is off
if (stickActive) controllerChange(1, 0);
stickActive = !stickActive;
}
buttonStates[STICK] = true;
}
//reset once stick is no longer being pressed
if (digitalRead(PIN_BUTTON_STICK) == HIGH && buttonStates[STICK]) buttonStates[STICK] = false;
if (stickActive) {
//read positions from center
float xPos = map(analogRead(PIN_JOYSTICK_X), stickZeroX, 1023, 0, 127);
float yPos = map(analogRead(PIN_JOYSTICK_Y), stickZeroY, 1023, 0, 127);
//get absolute position from center
float z = sqrt(sq(xPos) + sq(yPos));
int stickVal = (int)constrain(z, 0, 127);
if (stickVal > 0) {
stickState = true;
if (stickXY) {
controllerChange(2, abs(xPos));
controllerChange(4, abs(yPos));
}
else controllerChange(1, stickVal);
}
else if (stickState && stickVal == 0) {
stickState = false;
if (stickXY) {
controllerChange(2, 0);
controllerChange(4, 0);
}
else controllerChange(1, 0);
}
}
}
//----CALIBRATION----//
/* Likely will only have to calibrate once. This is done by activating calibration mode and
"plucking" each note on each string starting with the upper bound (after the 21st fret) and descending down
to just after the 1st fret. Starts with the low E string, then the A string and then the D string.
fret definitions are stored in EEPROM. Once it is calibrated for the voltage put out by the MIDI --> USB board
you can just have the calibration button do something else because you probably won't need it again.
*/
void unset(int i){
//this function doesn't even do anything!!
}
void calibrate() {
for (int i = 0; i < N_STR; i++) {
//Flash the LED too indicate calibration
/*
digitalWrite(PIN_LED, HIGH);
delay(100);
digitalWrite(PIN_LED, LOW);
delay(100);
digitalWrite(PIN_LED, HIGH);
delay(100);
digitalWrite(PIN_LED, LOW);
delay(100);
digitalWrite(PIN_LED, HIGH);
*/
//Flash the LED too indicate calibration
onLED(10, 250, 0, 0);
delay(100);
clrLED();
onLED(10, 250, 0, 0);
delay(100);
clrLED();
onLED(10, 250, 0, 0);
delay(100);
clrLED();
int sensorMax = 0;
int sensorMin = 1023;
int val;
//loop through the array of fret definitions
for (int j = N_FRET; j > 0; j--) {
int response = false;
//wait for response
while (!response) {
//read piezo val
int piezoVal = analogRead(piezoPins[i]);
//get the sensor min value (highest fret) on the first round
if (j == N_FRET) {
int fretVal = analogRead(softPotPins[i]);
if (fretVal > sensorMax) (sensorMax = fretVal);
clrLED();
//if the piezo is hit, register this as the definition for this fret
if (piezoVal > PIEZO_THRESHOLD_ON) {
int fretVal = analogRead(softPotPins[i]);
sensorMin = fretVal;
val = fretVal;
response = true;
clrLED();
}
}
else {
//get the rest of the fret definitions
//if the piezo is hit, register this as the definition for this fret
if (piezoVal > PIEZO_THRESHOLD_ON) {
int fretVal = analogRead(softPotPins[i]);
fretVal = map(fretVal, sensorMin, sensorMax, 0, 255);
fretVal = constrain(fretVal, 0, 255);
val = fretVal;
response = true;
clrLED();
}
}
}
//write to memory
digitalWrite(PIN_LED, LOW);
EEPROM.write(j + (N_FRET * i), val);
delay(100);
onLED(10, 250, 0, 0);
// delay(100);
digitalWrite(PIN_LED, HIGH);
}
//update global definitions
calibrationMin[i] = EEPROM.read(N_FRET + (N_FRET * i));
for (int j = 1; j < N_FRET; j++) {
fretDefs[i][j] = EEPROM.read(j + (i * N_FRET));
}
clrLED();
}
buttonStates[RIGHT] = false;
digitalWrite(PIN_LED, LOW);
}
void onLED(int led, int red, int green, int blue) {
for (int i = 0; i < N_STR; i++) {
//pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
pixels.setPixelColor(i, pixels.Color(red, green, blue));
}
pixels.show();
}
void clrLED() {
for (int i = 0; i < N_PIXELS; i++){
pixels.setPixelColor(i, pixels.Color(0, 0, 0)); // turn off
}
pixels.show();
}
//-------------MIDI functions-----------------
//note-on message
void noteOn(int cmd, int pitch, int velocity) {
Serial.write(byte(cmd));
Serial.write(byte(pitch));
Serial.write(byte(velocity));
digitalWrite(PIN_LED, HIGH);
}
//note-off message
void noteOff(int cmd, int pitch, int velocity) {
Serial.write(byte(cmd));
Serial.write(byte(pitch));
Serial.write(byte(0));
digitalWrite(PIN_LED, LOW);
}
//Sends controller change to the specified controller
void controllerChange(int controller, int value) {
Serial.write(byte(0xb0));
Serial.write(byte(controller));
Serial.write(byte(value));
Serial.write(byte(0xb1));
Serial.write(byte(controller));
Serial.write(byte(value));
Serial.write(byte(0xb2));
Serial.write(byte(controller));
Serial.write(byte(value));
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) {
return pixels.Color(255 - WheelPos * 3 + pitchBendLight, 0, WheelPos * 3 + pitchBendLight);
}
if(WheelPos < 170) {
WheelPos -= 85;
return pixels.Color(0, WheelPos * 3 + pitchBendLight , 255 - WheelPos * 3 + pitchBendLight);
}
else{
WheelPos -= 170;
return pixels.Color(WheelPos * 3 + pitchBendLight , 255 - WheelPos * 3 + pitchBendLight , 0 );
}
if(mod_final> 50){
}
}