I have a an Arduino Uno doing PWM on an RGB analog LED strip ala the Adafruit guide: https://learn.adafruit.com/rgb-led-strips?view=all. I've written a sketch that accepts MIDI data over USB and uses it to control the LEDs.
#include <MIDI.h>
#include <midi_Defs.h>
#include <midi_Message.h>
#include <midi_Namespace.h>
#include <midi_Settings.h>
#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
#define REDPIN 5
#define GREENPIN 6
#define BLUEPIN 3
byte commandByte;
byte noteByte;
byte velocityByte;
byte noteOn = 144;
byte noteOff = 128;
int colorGroup;
int pColor;
int sColor;
void setup()
{
pinMode(REDPIN, OUTPUT);
pinMode(GREENPIN, OUTPUT);
pinMode(BLUEPIN, OUTPUT);
MIDI.begin(1);
Serial.begin(115200);
}
void checkMIDI(){
do{
if (Serial.available()){
commandByte = Serial.read();//read first byte
noteByte = Serial.read();//read next byte
velocityByte = Serial.read();//read final byte
}
}
while (Serial.available() > 2);//when at least three bytes available
}
void updateLights(){
colorGroup = noteByte/42;
pColor = noteByte%41*127/41;
sColor = 127 - pColor;
pColor = pColor*velocityByte/127;
sColor = sColor*velocityByte/127;
if (commandByte == noteOn && velocityByte > 0){
if (colorGroup == 1){
analogWrite(REDPIN, pColor);
analogWrite(GREENPIN, sColor);
analogWrite(BLUEPIN, 0);
}
else if(colorGroup == 1){
analogWrite(GREENPIN, pColor);
analogWrite(BLUEPIN, sColor);
analogWrite(REDPIN, 0);
}
else{
analogWrite(BLUEPIN, pColor);
analogWrite(REDPIN, sColor);
analogWrite(GREENPIN, 0);
}
}
else if(commandByte == noteOff || velocityByte == 0){
analogWrite(REDPIN, 0);
analogWrite(GREENPIN, 0);
analogWrite(BLUEPIN, 0);
}
}
void loop()
{
checkMIDI();
updateLights();
}
Currently this code will turn the lights on and off in accordance with noteOn and noteOff messages. However, the color doesn't seem responsive to the note value and the brightness doesn't seem responsive to the velocity value. I suspect that the problem has to do with my arithmetic combined with the data type (maybe a problem with the order of operations), but I haven't been successful in debugging this.
The idea behind the RGB control is that I take the possible note values (0–127) and map it onto three different combinations of colors: R+G, G+B, and B+R. That's three groups of 42 values: 0-41, 42-84, and 85-127. Then I rescale the 42 values onto 0-127 for the intensity values of the LEDs. Finally I scale the intensity of all the colors by the velocity value over its possible max value.