Jump to content

DIY Q Light system


tomo2607

Recommended Posts

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" unit
  • Standby and Go LED for each channel on "Master" unit
  • Single 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

Top.jpg

 

 

Remote Unit

Remote.jpg

 

Master and Remote size comparison

Single-Ch-System.jpg

 

Outputs

Ports.jpg

 

 

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

 

Q-light-Control-Beta-2-CH-1-Remote.png

 

 

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 ...

Edited by tomo2607
Link to comment
Share on other sites

  • Replies 38
  • Created
  • Last Reply

Top Posters In This Topic

It looks like you are interconnecting the units directly from the IO pins of the arduino? I'd really recommend you don't do that as the pins are easy to damage with static or stray voltages - e.g when someone patches the wrong lead into a POE switch or something.

 

I would advise putting a series resistor of about 100R on any pin you connect to the "outside world", with a 5V transil or zener on the "inside" of the resistor safe.

A more elegant way to do this (but harder in software) would be to have a single serial comms bus which goes round each outstation using RS485. This would be a lot easier to connect up (do you really have 6 RJ45 patch points where you are putting the master?) and more fault tolerant.

 

 

 

 

 

Link to comment
Share on other sites

That's an interesting alternative, Tim. Many years ago I worked for a company who manufactured calculators and it had an RS-232 port. We fashioned an adapter that allowed us to do a simple local area network over 3 core cable (single ened, not differential). Of course youd need processing in each out station too but arduino nano or similar are dirt cheap.

 

I'd suggest having feedback from the outstation could be useful- when the talent is in place and waiting they signal to the DSM with their pushbutton.

Edited by alistermorton
Link to comment
Share on other sites

Thanks for the advice, As I said im no expert in this area. Just trying to fill a need...

 

In our set up, we have multiple RJ45 patch points in the control booth and locations around the stage. So yes, we have enough ports.

 

As for pin protection, its not something I considered, so thanks for that.

Link to comment
Share on other sites

Sorry I misunderstood your drawing and thought there were pushbuttons to acknowledge on the remote stations.

If it's just LEDs on the remote end put 100R in the master and 120R in the remote. I would still have slight concerns about people mis-patching if you have a patch bay for your RJ45's.

 

Also I'd put your own pullup resistors (1K - 4K7) on the buttons as the built in arduino ones are really weak, e.g. if someone keys a radio nearby this can register as a switch press

 

Link to comment
Share on other sites

For live performance work, equipment used must be totally reliable and if it fails, fail gracefully to a safe state. For this reason, simpler systems are usually preferred. Are you making this too complicated with a microcontroller in the middle of it? From experience, making something like this work installed in a real building is a least an order of magnitude harder than making it work on a nice cosy benchtop.

 

For a local community theatre, I made a very simple cue light system. Each indicator circuit consists of parallel connected (local, remote) pushbuttons operating series (local, remote) connected LED lamps. Either pushbutton when pushed lights the connected LEDs. The LEDs are series connected to provide confimation that the other one is also lit when a button is pressed. This circuit is duplicated for Red and Green channels and repeated as many times as required for all the outstations. CAT5 wiring can be used for the system hardwired, or via RJ45 connectors. Becaue the power demand is so low (power is only drawn when a button is pressed), two PP3 batteries happily power the system for a long time until they fail due to old age. Faults are instantly self-evident and can be qiuckly fixed with little more than a screwdriver and a meter. If budget can be persuaded, use 22mm industrial pushbuttons and lamps (or illuminated pushbuttons) - they are very reliable and good size to see and use in dimly lit backstage areas.

 

Link to comment
Share on other sites

For clarification... the design brief for the system I mentioned above included a requirement for a very long installed service life (10yrs+) with minimal maintenance. It was also assumed that the original designer and installer would not be available if anything did go wrong. These are the main reasons why a non-microcontroler system was chosen, the loss of some clever functions was an acceptable compromise to meet this and other design goals.

 

A 'master go' function is useful - the installation has only 4 outstations, so it is assumed that the person at the master station has sufficient fingers to push 4 big chunky buttons nearly simultaneously. It required, it is easy enough to add a 'master go' function with an extra pushbutton and some diodes.

 

To keep the system simple a latching standby function was omitted. The user workaround (bear in mind this is a community theatre which will happily evolve its own way of doing things!) is that the master station flashes the red standby at the outstation, which will respond with a green flash back to the main station, acknowledging the standby signal.

 

We generally don't use a headphone system (history, paracticalities and personalities!) so being able to signal in both directions with this cue light system is very useful. For example, if a scene change is going to take longer than rehearsed, the crew can signal back to the master station with a red light alerting the SM, then signal with a green light when ready. Needless to say there are other possible combinations (similar to inter-signal box communications using bells in old railway systems) which are generally not wanted or needed in our application.

 

Oddball temporary relocations and extra stations can be quickly added with one 3 pin xlr microphone cable per pushbutton and indication (no RJ45 infrastructure in our building).

Edited by pmiller056
Link to comment
Share on other sites

I'm totally with pmiller056 on this one. When my local theatre moved from a home-brew SM desk to a commercially-made one, losing the ability to send reverse cues was initially quite a culture-shock. In community / amateur theatre everything electronic needs to be either industry-standard, so it can be sent away for repair, or so simple that anyone even slightly technically-minded can sort out how it works, & mend it, long after its designer / builder has moved / passed away.

 

I've made the odd LEDs-in-series cue-light boxes for cueing MDs, via a spare way on the multicore (using AAs rather than PP3s), but I also possess a multi-station intercom system designed by a very clever, but now deceased, electronics engineer that, if it goes wrong & I can't fix it myself, will inevitably end up at the Council tip.

Link to comment
Share on other sites

P Miller, why would a micro controller be any less reliable than any other engineered system? As well as additional features outlined by Tim, the system is still very simple to build and operate...

 

Sandall, I’m also curious as to why you think this system may not be a simple system to maintain? The coding used is entry level, (I’m not expert) and we even have students who could possibly write the code in a more elegant way than I have... the hardware is also very basic electronics... so I’m sure any competent tech could maintain it easily...

 

Further to this, on my last costing, the components for the complete build are under £60 including the “Arduino”. So it’s almost a disposable system in terms of financial outlay.

Link to comment
Share on other sites

For clarification... the design brief ............ included a requirement for a very long installed service life (10yrs+) with minimal maintenance. It was also assumed that the original designer and installer would not be available if anything did go wrong. These are the main reasons why a non-microcontroler system was chosen, the loss of some clever functions was an acceptable compromise to meet this and other design goals.

Put it down to being of a generation for whom anything with a micro inside means "if it dies, I'm going to have to throw it away". I'm not knocking your system, Tomo2607 - it looks neat & well-designed, but I spent 25 years working in a theatre where all the sound & comms equipment was built in Eddystone boxes as hobby projects by BBC engineers with too much time on their hands. EVERYTHING was a prototype, & paperwork was minimal at best - basically they were the guardians of "The Knowledge", so when they went "the knowledge" went with them. Hence, when we had the chance to start again, everything that went in was industry-standard, off-the-shelf &, most importantly, fully documented (& the documentation kept up-to-date)..

 

Back to cue-lights - on my first home-made system pushing the button flashed the LED in the other box, so you had to rely on a return flash for confirmation that the cue had been given, but putting the LEDs in series would have been a better solution.

Link to comment
Share on other sites

Having a system that you consider to be disposable does not help when it suddenly fails in a strange way 1 hour before curtain-up in 2 years time. The cost of a lost show is many, many times the cost of the failed system.

 

Your coding IS entry level coding, however coming back to and understanding your own code many months after completion is hard. It is even harder and more time consuming when you have to understand someone else's code on an unfamiliar platform and development system. Been there and done both. It becomes nearly impossible when you are trying to do it with a very expensive clock ticking loudly (the cost of a lost show).

 

I'd much prefer to fault find and maintain any system where the ONLY required documentation is one A4 sheet of a circuit diagram tucked inside the box for the master station. A USB stick helpfully left inside is not instantly useful and needs other equipment to make it work. Please also remember that microcontrollers along with the required software infrastructure to make them work evolves VERY rapidly. A system that is readily available today probably will be obsolete and only maintainable with difficulty in as little as two years time.

Edited by pmiller056
Link to comment
Share on other sites

Oliver, Don't be put off by Peter's comments. Sure the coding is a bit clunky (at least go and look up the reference examples of a "for( )" loop) but everyone starts somewhere.

 

Also it sounds as though Peter is to some extent applying the standards of a pro system to what you have created as an amateur project. For example, if you decide that a system is disposable then you simply ensure you have a tested spare on the shelf so if one fails you just replace it. Peter, I think you are conflating maintenance/fault-finding and debugging - sure, to DEBUG a system you need access to either the original development environment or a modern equivalent but to maintain and fault-find you only need basic tools and a description of what it's supposed to do. (Also we're talking about an Arduino here and that environment isn't going to disappear any time soon!)

 

Regarding revisiting and understanding ancient code you're absolutely right - it is very easy to forget how code works once you've stopped working on it, but once Oliver has learned how to make his code a bit more compact no doubt he'll also start putting in copious comments so that years later he, or someone else, can understand what's going on.

 

One additional tip Oliver, any time you find yourself typing in almost the same bit of code more than once you probably need to be using a 'for' or while loop or a function.

 

Edit to get Oliver's name right - doh!

Edited by DrV
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.