Lighted Stops with a Twist
/*
Arduino Decoder with dimly lit enabled stops: by John Coenraads
=====================================
This sketch accepts MIDI commands on channel 1, decodes them and turns the appropriate IO pins on and off.
Bottom C (note 36) outputs on pin 2. Total outputs = 68 (pins 2 to 69).
If boards are daisy chained, each one can be "tuned" to a specific channel.
**This sketch handles Running Status,..**
If a stop is turned ON, it becomes enabled meaning it will continue to glow dimly even after being turned off.
For testing purposes only, when top C (note 96) is pressed, the array that keeps track of enabled stops is cleared.
Equipment: Arduino Mega + MIDI shield
created 2021 APR 08, modified 2021 AUG 25
*/
// Declarations==========================================
int i, j, k; //Counters (old Fortran habit)
byte noteStatusRx, noteNumberRx, noteVelocityRx, tempVar; //Receive variables
const byte status90 = 0x90, status80 = 0x80; //Define status bytes for channel 1
const int n = 100; // Number of scan cycles for which enabled LED is OFF. Larger number = dimmer
const int m = 20; // Number of scan cycles for which enabled LED is ON. Larger number = brighter
// If n = m, LED duty cycle = 50%. If n and m are too large, the LED will flicker
byte notesON [110]; //if note is on, value is 1, otherwise 0
byte notesEnabled [110]; //if note is enabled, value is 1, otherwise 0
//Initialize ============================================
void setup()
{
Serial.begin(31250); // Set MIDI baud rate:
while (Serial.available() > 0) {Serial.read();} //Clear serial input buffer
Serial1.end(); Serial2.end(); Serial3.end(); //Relieve ports 1,2,3 of serial IO duty
//Initialize 68 pins for output.
for (i = 2; i < 70; i++)
{
pinMode (i, OUTPUT);
digitalWrite (i, LOW);
}
//Initialize notesON array and notesEnabled array to 0
for (i = 0; i < 111; i++)
{
notesON [i] = 0;
notesEnabled [i] = 0;
}
}
//Main Loop =============================================
void loop()
{
for (i = 1; i < n; i++)
{
processSerial ();
}
enabledON();
for (j = 1; j < m; j++)
{
processSerial ();
}
enabledOFF();
}
void processSerial ()
{
if (Serial.available())
{
tempVar = Serial.read ();
if ((tempVar == status90) || (tempVar == status80))
{noteStatusRx = tempVar;
while (!Serial.available()) {} //wait for serial data, port 0
noteNumberRx = Serial.read ();
while (!Serial.available()) {} //wait for serial data, port 0
noteVelocityRx = Serial.read ();
if ((noteVelocityRx == 0) ||(noteStatusRx == status80))
{
digitalWrite (noteNumberRx - 34, LOW);
notesON [noteNumberRx] = 0;
}
else
{
digitalWrite (noteNumberRx - 34, HIGH);
notesEnabled [noteNumberRx] = 1;
notesON [noteNumberRx] = 1;
}
}
if (tempVar <= 0x7F) //is data byte (Running Status)
{noteNumberRx = tempVar;
while (!Serial.available()) {} //wait for serial data, port 0
noteVelocityRx = Serial.read ();
if ((noteVelocityRx == 0) ||(noteStatusRx == status80))
{
digitalWrite (noteNumberRx - 34, LOW);
notesON [noteNumberRx] = 0;
}
else
{
digitalWrite (noteNumberRx - 34, HIGH);
notesEnabled [noteNumberRx] = 1;
notesON [noteNumberRx] = 1;
}
}
if (noteNumberRx == 96)
{
for (i = 0; i < 111; i++)
{
notesEnabled [i] = 0;
}
}
}
}
void enabledON ()
{
for (i = 36; i < 96; i++)
{
if (notesEnabled [i] != 0)
{ digitalWrite (i - 34, HIGH);}
}
}
void enabledOFF ()
{
for (i = 36; i < 96; i++)
{
if (notesON [i] == 0)
{ digitalWrite (i - 34, LOW);}
}
}