Automatic LED Staircase Lighting



When I moved into a new house I was redecorating and wanted to provide more light to a rather dark staircase. The design of the staircase made it feasible to run an LED strip adjacent to the treads and since I had the opportunity to run some wires and install some equipment, I thought it might be worth making provision to have the lights come on automatically when they were required - though exactly how wasn't immediately clear.

A PIR sensor was an obvious candidate, but most of those easily available are hardly unobtrusive and few are intended to be built in to an enclosure with all components and trailing cables concealed. There is one type of sensor that fitted the bill and is available from many sources of which this is only one: the sensor "head" is quite compact and contains both a PIR sensor and a light sensor (LDR) and can be seated in a relatively small hole with only the dome of the sensor exposed. 


Unfortunately, the control unit supplied with the sensor did not really meet my needs and I couldn't get it to trigger reliably in the specific circumstances I required of it. However, I made provision to install the sensor in the staircase and also added pressure pads to the top and bottom step and resolved to solve the problem of making it work until after the decoration was completed. 

 As a stop-gap measure, I installed a simple timer circuit, triggered by the pressure pads, which would turn on the lights for a fixed period when the stairs were in use. This worked well enough, but there was clearly room for improvement. However, this would mean trying to work with the raw output of the motion and light sensors and ditching the supplied controller.

Sensors and Signal Conditioning

You can find out more about PIR sensors here. However, basically, they consist of an FET with a window in the case transparent to infrared light. They produce a tiny current which needs amplification and filtering. The light sensor is more straightforward - its resistance changes (dramatically) in the presence of light and simply connecting the sensor via a resistor to a power supply produces a voltage which swings between almost 0 and almost the rail potential depending on the level of illumination.

To experiment with the sensor, I put together a prototype based on the circuit shown in the PIR article referenced above:

The 100k resistor converts the current from the PIR sensor to a small voltage which is amplified in two stages, each with a bandpass filter to limit extraneous signals. As I wanted a single rail power supply, I made the first and second stage identical so that I could put a mid-rail potential on the non-inverting inputs of the op-amps. I didn't have exact matches for some of the components, but the values used are 'near enough'. I happened to have a couple of TLC271 op-amps available (they had been misordered) and they turned out to be reasonable candidates for the job. I omitted the diode in the negative feedback loop to charge the large capacitor - it only removes a few seconds from the time it takes for the circuit to stabilise.

So, at this point, both the light and motion sensors were producing output in the order of volts, depending on activity. 

Control Logic

The next step was to process the sensor signals and use them (somehow) to control the lighting. The obvious (and relatively cheap) solution was to use an Arduino (clone) - in this case a Nano - and control the LED strip with PWM. There are ubiquitous and cheap MOSFET PWM modules that will handle several amps at 12V, for example:

 The Arduino is quite capable of generating a PWM signal that will connect directly to the MOSFET and allow proportional control of the lights (not just on and off).

Using the Arduino analogue inputs it is possible to measure the output from both the light and motion sensors. This offers the opportunity to be somewhat more sophisticated in detecting motion and also only to enable the lighting when it is actually dark! 

The PIR signal conditioning circuit is AC-coupled up to the input of the second stage of amplification, so the quiescent DC output will be around mid-rail potential, although this will depend on resistor tolerance and may drift a little dependent on environmental conditions. The light sensor signal is a little erratic when the illumination level changes suddenly and we don't want to pay attention to sudden blips caused by clouds or lights being flipped on and off. 

The solution to this is to take a rolling average of the sensor inputs. For the motion sensor, we take this as the baseline and our motion detection is based on the difference between the instantaneous motion signal and the long-term average. For the light sensor, we use the average ambient light value rather than the instantaneous level to determine if the staircase lights may be required.

But how much must the motion signal deviate to cause the lights to activate? And at what ambient light level? This will depend on the circumstances of the individual location, so a couple of potentiometers connected to another two of the Arduino's analogue inputs allows these thresholds to be adjusted to suit.

Finally, we use a digital pin on the Arduino to detect if the pressure pads on the stairs have closed.


The Arduino sketch can be found on GitHub.

Basically, the main loop reads the motion and light sensors and calculates the rolling average and comparing the present levels with the average. The average is computed as an exponential weighted moving average. Given the Arduino can't divide and can barely multiply we simplify this further by making the weighting a binary fraction so a couple of shifts sort out the arithmetic. 

Once the main loop has determined if a sensor change is significant, a simple finite state machine determines what action is necessary. 

The software is currently arranged so that presence detected by the PIR sensor causes the staircase lighting to "glow" at a reduced intensity - this is useful when approaching the stairs at night (or coming through the front door!). If the pressure sensor is triggered, indicating the staircase is in use, the lights are set to full intensity. After a period of time, the lights are then turned off.

Using the Arduino's Timer 1, a series of interrupts is generated and when the lights need to change state, the interrupt service routine increases or decreases the light level as smoothly as possible given the relatively short transit time of the staircase. 

Practical Considerations

Even with amplification, the PIR output changes by about 50mV for movement at the top and bottom of the stairs, so noise and false triggering are an obvious risk. For this reason, the software requires that the PIR trigger be present for two consecutive passes through the main loop (0.5s) before accepting it as genuine. The value read from the potentiometer used to calibrate sensitivity (the difference between the instantaneous and average motion sensor readings) is scaled down by a factor of 8 or it would be almost impossible to adjust precisely.

Because the sensors are situated adjacent to the LED light strip there are some obvious consequences. The light sensor is dominated by the LED lights when they're on and consequently values read while the lights are on are not added to the rolling average. The lighting has some small effect on the PIR sensor too, particularly as the lights fade on and off. Consequently, motion detected in a short period (10s) after the lights have gone off is ignored.

I originally hoped that I could use the Arduino to derive the 5V rail from the 12V LED supply - the Arduino has a 5V output and can allegedly be powered from voltages in excess of 12V. In practice, the linear regulator on the Arduino clone is not really up to the job and soon fried when 12V was applied.

Using a lower voltage supply via the Arduino regulator and using a regulated 5V supply for both the digital and analogue circuits was unsuccessful - the Arduino simply produced too much power supply noise for the signal conditioning circuitry. The inelegant solution was to use a couple of cheap buck converters to provide two independent 5V supplies, one for the Arduino clone and one for the analogue circuitry.

Final Prototype

The final prototype was built on stripboard and the various modules - the Arduino, power regulators, signal board, potentiometers and MOSFET PWM module - were housed in a spare plastic box with multiple compartments: not pretty but it does the job. Time now to live with it for a while and see what further improvements may be possible.