62 Light Stop Jamb
/*
Lighted Stop Jamb Buttons: HW Combination action: Arduino #1 or #2
=========================================
This sketch is designed to scan 31 lighted toggling buttons.
ON/OFF messages are sent to HW on channel 1 + number of intervening Arduinos.
(messages start on channel 1 but each of four subsequent Arduinos bumps this up by one)
These ON/OFF messages, echoed back from HW, are used to turn the LEDs on and off.
Two Arduinos,running identical code may be daisy chained.
Outputs: pins 2 - 32
Inputs: pins 34 - 64
HW note numbers: 36 - 66
For testing, LED on Pin 13 corresponds to Input pin 45.
I/O is through Port 0 to and from HW.
Equipment: Arduino Mega (with one MIDI shield for whole system)
created 2022 JAN 6
modified and tested 2022 JAN 9
by John Coenraads
*/
// Declarations==========================================
//Counters (old Fortran habit)
int i, j, k;
//Receive variables
byte noteStatusRx;
byte noteNumberRx;
byte noteVelocityRx;
int pin; //Arduino pin number
byte switchState;
byte numArd = 4; //number of intervening Arduinos (e.g., parallel scan Arduinos that bump up channel number
byte stopONArray [100]; //Tracks which stops are on and which LEDs are lit.
byte switchONArray [100]; //Tracks which of the latching switches is in the ON position
//Initialize =========================================================
void setup()
{
// Set MIDI baud rate:
Serial.begin(31250);
//Initialize input. Normally high (via internal pullups)
for (i = 34; i < 65; i++)
{
pinMode (i, INPUT_PULLUP);
}
//Initialize output (normally low)
for (i = 2; i < 33; i++)
{
pinMode (i, OUTPUT);
digitalWrite (i, LOW);
}
//Initialize Arrays
for (i= 0; i < 100; i++){
stopONArray[i] = 0; //all stops and LEDs are off
}
for (pin = 34; pin < 65; pin++){
switchONArray[pin] = digitalRead(pin); //read initial state of latching switch
}
}
//Main Loop ===========================================================
void loop()
{
scanGroup();
processSerial ();
}
//Scan thirty-one Buttons
void scanGroup ()
{
for (pin = 34; pin < 65; pin++)
{
switchState = digitalRead(pin);
if (switchState != switchONArray [pin])
{
switchONArray [pin] = switchState;
toggleStop ();}
}
}
void toggleStop ()
{
if (stopONArray[pin] == 0)
{
Serial.write (0x90); //note ON, channel 1
Serial.write (pin + 2);
Serial.write (0x7f); //medium velocity
}
else
{
Serial.write (0x90); //note OFF,
Serial.write (pin + 2);
Serial.write (0); //zero velocity
}
delay (10); //debounce delay
}
//Process data received for serial port 0 (from preceding Arduino): status, note number, velocity
//Note: this bare bones version does not handle running status.
void processSerial ()
{
if (Serial.available())
{
noteStatusRx = Serial.read ();
if (noteStatusRx > 0x7F) //is status byte
{
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 (((noteStatusRx - numArd ) == 0x91) || ((noteStatusRx - numArd ) == 0x81)) //I.e., channel 2
{processDataIn ();}
else
{transmitDataIn ();}
}
}
void processDataIn ()
{
pin = noteNumberRx - 2;
if ((noteStatusRx - numArd ) == 0x91)
{
stopONArray[pin] = 1;
digitalWrite (pin - 32, HIGH); //turn ON light
}
else
{
stopONArray[pin] = 0;
digitalWrite (pin - 32, LOW); //turn OFF light
}
}
void transmitDataIn ()
{
Serial.write (noteStatusRx + 1); //output on port 0. Bump up one channel
Serial.write (noteNumberRx);
Serial.write (noteVelocityRx);
}