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);

}