Lighted Stop Jamb
/*
Lighted Stop Jamb Buttons: Toggling
=========================================
This sketch is designed to scan 30 lighted tactile buttons and to indicate
whether a stop is on or off by toggling an LED. ON/OFF messages are sent to HW on channel 5
A general cancel turns off all lights and transmits OFF codes for any stops that are ON.
Version 2 makes provision for daisy chaining.
Outputs: pins 2 - 31
Inputs: pins 34 - 63
HW codes: 36 - 65
General Cancel: Pin 69
I/O is through Port 0
Output is to HW.
Equipment: Arduino Mega with one MIDI shield
created 2021 OCT 30
modified 2021 NOV 2 tested on four pins
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 noteStatus;
byte noteNumber;
byte noteVelocity;
byte setState; //flag to remember that set piston ON message has been sent
byte stopONArray [100]; //Tracks which stops are on and which LEDs are lit.
//Initialize =========================================================
void setup()
{
// Set MIDI baud rate:
Serial.begin(31250);
//Initialize input. Normally high (via internal pullups)
for (i = 34; i < 64; i++)
{
pinMode (i, INPUT_PULLUP);
}
//Initialize output (normally low)
for (i = 2; i < 32; i++)
{
pinMode (i, OUTPUT);
digitalWrite (i, LOW);
}
pinMode (69, INPUT_PULLUP); // General Cancel Piston
//Initialize Array to zero
for (i= 0; i < 100; i++){
stopONArray[i] = 0;
}
}
//Main Loop ===========================================================
void loop()
{
scanGroup();
scanCancel();
processSerial ();
}
//Scan thirty Buttons
void scanGroup ()
{
for (pin = 34; pin < 64; pin++)
{
if (digitalRead(pin) == LOW)
{
toggleStop ();}
}
}
void toggleStop ()
{
if (stopONArray[pin] == 0)
{
stopONArray[pin] = 1;
digitalWrite (pin - 32, HIGH); //turn ON light
Serial.write (0x94); //note ON, channel 5
Serial.write (pin + 2);
Serial.write (0x7f); //medium velocity
}
else
{
stopONArray[pin] = 0;
digitalWrite (pin - 32, LOW); //turn OFF light
Serial.write (0x94); //note OFF,
Serial.write (pin + 2);
Serial.write (0); //zero velocity
}
delay (1); //debounce delay
while (digitalRead(pin) == LOW) {
}; //wait for button to be released
delay (1);
}
void scanCancel()
{
if (digitalRead(69) == LOW) // general cancel
{
for (pin = 1; pin < 100; pin++)
{
if (stopONArray[pin] != 0)
{
stopONArray[pin] = 0;
digitalWrite (pin - 32, LOW); //turn OFF light
Serial.write (0x94); //note OFF,
Serial.write (pin + 2);
Serial.write (0); //zero velocity
}
}
}
delay (1); //debounce delay
while (digitalRead(69) == LOW) {
}; //wait for piston to be released
delay (1);
}
//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 ();
Serial.write (noteStatusRx); //output on port 0
Serial.write (noteNumberRx);
Serial.write (noteVelocityRx);
}
}
}