I have been working on a cheap and fairly basic Q light system for our school venue. Im far from an expert in either programming or device electronics, but the design principle works in simulation, and im hoping to have a working demo in the coming months. Its not particularly high end, but it could be beneficial for others in need of such a system with the same financial constraints. I've taken an Arduino Mega 2560 as the "heart" and used components easily found from cpc.farnell for the hardware. Outputs are Rj45 to suit our venue patching, but XLR could also be used depending on voltage drop tests and distance from source. We have tested voltage drop over 50m of cat5 and the amounts were negligible in relation to this application. The code is functional but a little rudimentary and could be improved upon, especially in terms of de-bouncing the button actions. however I have found it to be reliable in simulation. 6 channels (can be expanded or reduced within limitations of the Arduino)Standby and Go button for each channel on "Master" unitStandby and Go LED for each channel on "Master" unitSingle Standby and Go on "remote" units. Pressing the standby button once will illuminate (and hold) the standby LED of that channel on both the "Master" and "Remote" unit. Pressing the standby button when already illuminated will turn off the LED Holding the standby button will intermittently flash the standby LED until released. The Go Button when held will illuminate the Go LED on both the "Master" and "Remote" until released, regardless of standby state Releasing the Go button will turn off the Go LED and the Standby LED if illuminated of that channel A Master GO has also been included. When this is held, any channel that is already in standby will have its Go LED illuminated. All others will remain dark When released, all GO and Standby LED's will turn off. Model images and Arduino Uno pinout shown below. Code for 2ch (as imaged) and 6ch also included. Master Unit Remote Unit Master and Remote size comparison Outputs Graphic of wiring option - Arduino has internal pull-up resistors on each pin, so resistor between button and GND is not needed - resistors for LEDs in this case are 220, but this is dependent on LEDs used. - cpc project boxes used for hardware mounting 2ch Tinkercad example /*
Q Light control Box
*/
/*
variables
*/
//Array Variables
int BtnArray [] {1, 2, 3, 4, 5};
int GoBtnArray [] {3, 4};
int SbyBtnArray [] {1, 2,};
int LEDArray [] {6, 7, 8, 9, 10, 11, 12, 13};
int SbyLEDArray [] {6, 7, 8, 9};
int GoLEDArray [] {10, 11, 12, 13};
//Delay time
int DLY = 200;
//Standby button variables
int Sby_Btn_1;
int Sby_Btn_2;
//Go button variables
int Go_Btn_1;
int Go_Btn_2;
//Standby LED variables
int Sby_LED_1;
int Sby_LED_2;
//Standby remote LED variables
int Sby_LED_1a;
int Sby_LED_2a;
//Go LED variables
int Go_LED_1;
int Go_LED_2;
//Go remote LED variables
int Go_LED_1a;
int Go_LED_2a;
//Master variable
int Master_Go;
void setup()
{
pinMode(BtnArray[0], INPUT_PULLUP);
pinMode(BtnArray[1], INPUT_PULLUP);
pinMode(BtnArray[2], INPUT_PULLUP);
pinMode(BtnArray[3], INPUT_PULLUP);
pinMode(BtnArray[4], INPUT_PULLUP);
pinMode(LEDArray[0], OUTPUT);
pinMode(LEDArray[1], OUTPUT);
pinMode(LEDArray[2], OUTPUT);
pinMode(LEDArray[3], OUTPUT);
pinMode(LEDArray[4], OUTPUT);
pinMode(LEDArray[5], OUTPUT);
pinMode(LEDArray[6], OUTPUT);
pinMode(LEDArray[7], OUTPUT);
}
void loop()
{
// Set Button 1 and LED 1 Status
Sby_LED_1 = digitalRead(6);
Sby_LED_1a = digitalRead(8);
Sby_Btn_1 = digitalRead(1);
// Set Button 2 Status and LED 2 Status
Sby_LED_2 = digitalRead(7);
Sby_LED_2a = digitalRead(9);
Sby_Btn_2 = digitalRead(2);
// Set Button 3 Status and LED 3 Status
Go_LED_1 = digitalRead(10);
Go_LED_1a = digitalRead(12);
Go_Btn_1 = digitalRead(3);
// Set Button 4 Status and LED 4 Status
Go_LED_2 = digitalRead(11);
Go_LED_2a = digitalRead(13);
Go_Btn_2 = digitalRead(4);
// helpful single-line comment here
Master_Go = digitalRead(5);
// Standby Button 1 Behaviour
if (Sby_Btn_1 == LOW) {
delay(DLY);
digitalWrite(6, HIGH);
digitalWrite(8, HIGH);
}
if (SbyBtnArray == LOW) {
if (Sby_LED_1 == HIGH) {
delay(DLY);
digitalWrite(6, LOW);
digitalWrite(8, LOW);
}
}
// Go Button 1 Behaviour
if (Go_Btn_1 == LOW) {
digitalWrite(10, HIGH);
digitalWrite(12, HIGH);
} else {
digitalWrite(10, LOW);
digitalWrite(12, LOW);
}
// Standby Button 2 Behaviour
if (Sby_Btn_2 == LOW) {
delay(DLY);
digitalWrite(7, HIGH);
digitalWrite(9, HIGH);
}
if (Sby_Btn_2 == LOW) {
if (Sby_LED_2 == HIGH) {
delay(DLY);
digitalWrite(7, LOW);
digitalWrite(9, LOW);
}
}
// Go Button 2 Behaviour
if (Go_Btn_2 == LOW) {
digitalWrite(11, HIGH);
digitalWrite(13, HIGH);
} else {
digitalWrite(11, LOW);
digitalWrite(13, LOW);
}
// Master_Go Behaviour
if (Master_Go == LOW) {
if (Sby_LED_1 == HIGH) {
digitalWrite(10, HIGH);
digitalWrite(12, HIGH);
}
}
if (Master_Go == LOW) {
if (Sby_LED_2 == HIGH) {
digitalWrite(11, HIGH);
digitalWrite(13, HIGH);
}
}
// Master_Go Release
if (Master_Go == HIGH) {
if (Go_LED_1 == HIGH) {
if (Go_Btn_1 == HIGH) {
digitalWrite(6, LOW);
digitalWrite(8, LOW);
digitalWrite(10, LOW);
digitalWrite(12, LOW);
}
}
}
if (Master_Go == HIGH) {
if (Go_LED_2 == HIGH) {
if (Go_Btn_2 == HIGH) {
digitalWrite(7, LOW);
digitalWrite(9, LOW);
digitalWrite(11, LOW);
digitalWrite(13, LOW);
}
}
}
} Full 6ch Code /*
Q Light control Box
*/
/*
variables
*/
//Standby Button variables
int SBY_1;
int SBY_2;
int SBY_3;
int SBY_4;
int SBY_5;
int SBY_6;
//Go Button variables
int GO_1;
int GO_2;
int GO_3;
int GO_4;
int GO_5;
int GO_6;
//LED variables
int RED_1;
int RED_2;
int RED_3;
int RED_4;
int RED_5;
int RED_6;
int GREEN_1;
int GREEN_2;
int GREEN_3;
int GREEN_4;
int GREEN_5;
int GREEN_6;
//Master Button variable
int Master_Go;
//Remote Variables
int RED_1b;
int RED_2b;
int RED_3b;
int RED_4b;
int RED_5b;
int RED_6b;
int GREEN_1b;
int GREEN_2b;
int GREEN_3b;
int GREEN_4b;
int GREEN_5b;
int GREEN_6b;
/*
Main code
*/
void setup()
{
//Button Inputs
pinMode(1, INPUT_PULLUP);
pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);
pinMode(4, INPUT_PULLUP);
pinMode(5, INPUT_PULLUP);
pinMode(6, INPUT_PULLUP);
pinMode(7, INPUT_PULLUP);
pinMode(8, INPUT_PULLUP);
pinMode(9, INPUT_PULLUP);
pinMode(10, INPUT_PULLUP);
pinMode(11, INPUT_PULLUP);
pinMode(12, INPUT_PULLUP);
pinMode(13, INPUT_PULLUP);
//LED Outputs
pinMode(14, OUTPUT);
pinMode(15, OUTPUT);
pinMode(16, OUTPUT);
pinMode(17, OUTPUT);
pinMode(18, OUTPUT);
pinMode(19, OUTPUT);
pinMode(20, OUTPUT);
pinMode(21, OUTPUT);
pinMode(22, OUTPUT);
pinMode(23, OUTPUT);
pinMode(24, OUTPUT);
pinMode(25, OUTPUT);
pinMode(26, OUTPUT);
pinMode(27, OUTPUT);
pinMode(28, OUTPUT);
pinMode(29, OUTPUT);
pinMode(30, OUTPUT);
pinMode(31, OUTPUT);
pinMode(32, OUTPUT);
pinMode(33, OUTPUT);
pinMode(34, OUTPUT);
pinMode(35, OUTPUT);
pinMode(36, OUTPUT);
pinMode(37, OUTPUT);
}
void loop()
{
// Set Standby 1 and RED 1 / 1b Status
RED_1 = digitalRead(14);
RED_1b = digitalRead(26);
SBY_1 = digitalRead(1);
// Set Standby 2 and RED 2 / 2b Status
RED_2 = digitalRead(15);
RED_2b = digitalRead(27);
SBY_2 = digitalRead(2);
// Set Standby 3 and RED 3 / 3b Status
RED_3 = digitalRead(16);
RED_3b = digitalRead(28);
SBY_3 = digitalRead(3);
// Set Standby 4 and RED 4 / 4b Status
RED_4 = digitalRead(17);
RED_4b = digitalRead(29);
SBY_4 = digitalRead(4);
// Set Standby 5 and RED 5 / 5b Status
RED_5 = digitalRead(18);
RED_5b = digitalRead(30);
SBY_5 = digitalRead(5);
// Set Standby 6 and RED 6 / 6b Status
RED_6 = digitalRead(19);
RED_6b = digitalRead(31);
SBY_6 = digitalRead(6);
// Set GO 1 and Green 1 / 1b Status
GREEN_1 = digitalRead(20);
GREEN_1b = digitalRead(32);
GO_1 = digitalRead(7);
// Set GO 2 and Green 2 / 2b Status
GREEN_2 = digitalRead(21);
GREEN_2b = digitalRead(33);
GO_2 = digitalRead(8);
// Set GO 3 and Green 3 / 3b Status
GREEN_3 = digitalRead(22);
GREEN_3b = digitalRead(34);
GO_3 = digitalRead(9);
// Set GO 4 and Green 4 / 4b Status
GREEN_4 = digitalRead(23);
GREEN_4b = digitalRead(35);
GO_4 = digitalRead(10);
// Set GO 5 and Green 5 / 5b Status
GREEN_5 = digitalRead(24);
GREEN_5b = digitalRead(36);
GO_5 = digitalRead(11);
// Set GO 6 and Green 6 / 6b Status
GREEN_6 = digitalRead(25);
GREEN_6b = digitalRead(37);
GO_6 = digitalRead(12);
// Master GO
Master_Go = digitalRead(13);
// SBY_1 Behaviour
if (SBY_1 == LOW) {
delay(200);
digitalWrite(14, HIGH);
digitalWrite(26, HIGH);
}
if (SBY_1 == LOW) {
if (RED_1 == HIGH) {
delay(200);
digitalWrite(14, LOW);
digitalWrite(26, LOW);
}
}
// SBY_2 Behaviour
if (SBY_2 == LOW) {
delay(200);
digitalWrite(15, HIGH);
digitalWrite(27, HIGH);
}
if (SBY_2 == LOW) {
if (RED_2 == HIGH) {
delay(200);
digitalWrite(15, LOW);
digitalWrite(27, LOW);
}
}
// SBY_3 Behaviour
if (SBY_3 == LOW) {
delay(200);
digitalWrite(16, HIGH);
digitalWrite(28, HIGH);
}
if (SBY_3 == LOW) {
if (RED_3 == HIGH) {
delay(200);
digitalWrite(16, LOW);
digitalWrite(28, LOW);
}
}
// SBY_4 Behaviour
if (SBY_4 == LOW) {
delay(200);
digitalWrite(17, HIGH);
digitalWrite(29, HIGH);
}
if (SBY_4 == LOW) {
if (RED_4 == HIGH) {
delay(200);
digitalWrite(17, LOW);
digitalWrite(29, LOW);
}
}
// SBY_5 Behaviour
if (SBY_5 == LOW) {
delay(200);
digitalWrite(18, HIGH);
digitalWrite(30, HIGH);
}
if (SBY_5 == LOW) {
if (RED_5 == HIGH) {
delay(200);
digitalWrite(18, LOW);
digitalWrite(30, LOW);
}
}
// SBY_6 Behaviour
if (SBY_6 == LOW) {
delay(200);
digitalWrite(19, HIGH);
digitalWrite(31, HIGH);
}
if (SBY_6 == LOW) {
if (RED_6 == HIGH) {
delay(200);
digitalWrite(19, LOW);
digitalWrite(31, LOW);
}
}
// GO_1 Behaviour
if (GO_1 == LOW) {
delay(200);
digitalWrite(20, HIGH);
digitalWrite(32, HIGH);
}
if (GO_1 == LOW) {
if (GREEN_1 == HIGH) {
delay(200);
digitalWrite(20, LOW);
digitalWrite(32, LOW);
}
}
// GO_2 Behaviour
if (GO_2 == LOW) {
delay(200);
digitalWrite(21, HIGH);
digitalWrite(33, HIGH);
}
if (GO_2 == LOW) {
if (GREEN_2 == HIGH) {
delay(200);
digitalWrite(21, LOW);
digitalWrite(33, LOW);
}
}
// GO_3 Behaviour
if (GO_3 == LOW) {
delay(200);
digitalWrite(22, HIGH);
digitalWrite(34, HIGH);
}
if (GO_3 == LOW) {
if (GREEN_3 == HIGH) {
delay(200);
digitalWrite(22, LOW);
digitalWrite(34, LOW);
}
}
// GO_4 Behaviour
if (GO_4 == LOW) {
delay(200);
digitalWrite(23, HIGH);
digitalWrite(35, HIGH);
}
if (GO_4 == LOW) {
if (GREEN_4 == HIGH) {
delay(200);
digitalWrite(23, LOW);
digitalWrite(35, LOW);
}
}
// GO_5 Behaviour
if (GO_5 == LOW) {
delay(200);
digitalWrite(24, HIGH);
digitalWrite(36, HIGH);
}
if (GO_5 == LOW) {
if (GREEN_5 == HIGH) {
delay(200);
digitalWrite(24, LOW);
digitalWrite(36, LOW);
}
}
// GO_6 Behaviour
if (GO_6 == LOW) {
delay(200);
digitalWrite(25, HIGH);
digitalWrite(37, HIGH);
}
if (GO_6 == LOW) {
if (GREEN_6 == HIGH) {
delay(200);
digitalWrite(25, LOW);
digitalWrite(37, LOW);
}
}
//Master GO Hold Behaviour
if (Master_Go == LOW) {
if (RED_1 == HIGH) {
digitalWrite(1, HIGH);
digitalWrite(7, HIGH);
}
}
if (Master_Go == LOW) {
if (RED_2 == HIGH) {
digitalWrite(2, HIGH);
digitalWrite(8, HIGH);
}
}
if (Master_Go == LOW) {
if (RED_3 == HIGH) {
digitalWrite(3, HIGH);
digitalWrite(9, HIGH);
}
}
if (Master_Go == LOW) {
if (RED_4 == HIGH) {
digitalWrite(4, HIGH);
digitalWrite(10, HIGH);
}
}
if (Master_Go == LOW) {
if (RED_5 == HIGH) {
digitalWrite(5, HIGH);
digitalWrite(11, HIGH);
}
}
if (Master_Go == LOW) {
if (RED_6 == HIGH) {
digitalWrite(6, HIGH);
digitalWrite(12, HIGH);
}
}
// Master_Go Release Behaviour
if (Master_Go == HIGH) {
if (GREEN_1 == LOW) {
if (GO_1 == LOW) {
digitalWrite(14, LOW);
digitalWrite(20, LOW);
digitalWrite(26, LOW);
digitalWrite(32, LOW);
}
}
}
if (Master_Go == HIGH) {
if (GREEN_2 == LOW) {
if (GO_2 == LOW) {
digitalWrite(15, LOW);
digitalWrite(21, LOW);
digitalWrite(27, LOW);
digitalWrite(33, LOW);
}
}
}
if (Master_Go == HIGH) {
if (GREEN_3 == LOW) {
if (GO_3 == LOW) {
digitalWrite(16, LOW);
digitalWrite(22, LOW);
digitalWrite(28, LOW);
digitalWrite(34, LOW);
}
}
}
if (Master_Go == HIGH) {
if (GREEN_4 == LOW) {
if (GO_4 == LOW) {
digitalWrite(17, LOW);
digitalWrite(23, LOW);
digitalWrite(29, LOW);
digitalWrite(35, LOW);
}
}
}
if (Master_Go == HIGH) {
if (GREEN_5 == LOW) {
if (GO_5 == LOW) {
digitalWrite(18, LOW);
digitalWrite(24, LOW);
digitalWrite(30, LOW);
digitalWrite(36, LOW);
}
}
}
if (Master_Go == HIGH) {
if (GREEN_6 == LOW) {
if (GO_6 == LOW) {
digitalWrite(19, LOW);
digitalWrite(25, LOW);
digitalWrite(31, LOW);
digitalWrite(37, LOW);
}
}
}
} Pin allocation can be changed to your own preference... Hope this is useful to someone. Please feel free to comment or message me if you need anything explaining further, I'm sure I will have forgotten vital info ...