External lighting controller
On at dusk, off at a fixed time

see copyright notice. Page created 27-Apr-2005 updated 4-Nov-2019. Use the button groups above to navigate quickly around the site.


The problem

From 1984 to 1995 I struggled to make my outdoor security and porch lights turn on and off automatically each day. I'd bought a neat unit that fitted in place of a wall switch and was supposed to detect the failing daylight. But in practice the "on period" needed constant adjustment throughout the year, the lights turned on and off at all hours of the day during dull weather, and every few years something went "phut" and the thing had to be replaced. What I really wanted didn't seem to exist; a device that could:

So in 1995 I embarked on a DIY solution. Perhaps even then it belonged in a museum, but however old-fashioned the technology, I hope someone somewhere will pick up on the principle and market it in place of that dreadful light-sensitive switch!

The solution

[Unit in operation]

It's basically a metal box, fixed to the garage wall, containing the inevitable (for me) Z80 microprocessor system, a bank of 4 membrane buttons, various switches and LEDs and a good old-fashioned relay to drive the lights. The firmware knows the time of sunset for every day of the year, which forms the basis for switching on the lights.

I'm always reluctant to put non-essential hardware into a project, so in this case I designed-in the challenge of setting up the date and time without any form of alphanumeric display. The result will do one or more of: impress, mystify, amuse, horrify you. It's set up by three user actions during the first evening after the unit is installed; at each action, one of the three PROGRAM LEDs changes from flashing to steadily on.

At sunset, the buttons marked S-S and either spr[ing] or aut[umn], as appropriate, are simultaneously pressed; this makes the lights switch on. At 9pm local time, the buttons marked 9PM and either GMT or BST, as appropriate, are simultaneously pressed; this calibrates the device's timekeeping. Finally, at the desired switch-off time, the buttons marked sw and off are simultaneously pressed; this makes the lights switch off. From then onwards operation is fully automatic. Twice a year, at the start and end of British Summer Time (Daylight Saving Time), it's just necessary to press the 9PM-GMT/BST combination at 9pm under the new regime, to move the switch-off to the same clock time as before.

The red button disables the automatic switch-off for one night only, and the 3-way toggle switch immediately switches the lights ON or OFF and can be either left in those positions or returned to AUTO to revert at the next scheduled switching time. There's another feature that will turn the lights on at a fixed time in the morning, and off at sunrise, but since I gave up full-time work at about the time of installation, I've never actually tested it!

Hardware notes

[Chassis] [Power board] [CPU and logic board]

The main chassis carries a connection block, 250mA mains fuse, transformer, and relay to drive the lights. The remaining circuitry occupies two boards, one each side of the wrap-round front panel with the controls. The power board rectifies the transformer output to produce a 12V raw DC supply, which feeds the light control relay and a 5V regulator for the logic.

The logic board is designed for low power consumption, since I decided it would be neat to use a backup capacitor rather than a battery to keep it going during short outages (see below). The CMOS Z80CPU is clocked at 32.768kHz, its reset pin driven at 4Hz, both courtesy of a 74HC4060 oscillator/divider with a "watch" crystal. Firmware is in a 27C64 EPROM and I/O go through a 74HC541 and 74HC574 respectively. Pull-ups for the momentary switch inputs are 10k, but the toggle switch has 100k to minimise drain when it's in an "active" position.

[Power circuit detail]

The circuit arrangements shown here make sure all loading is removed from the logic outputs during mains outages. Originally, logic power was maintained by a 1.0F capacitor connected across the 5V supply, with a 220R series resistor to limit inrush current. It kept the timekeeping alive for 2-4 hours during a power outage. However, the original capacitor "went dry" after about 5 years, and its replacement rapidly went the same way. Much against my better judgement, I admitted defeat and fixed a tray containing three AA cells to the outside of the box, connected to where the capacitor had been via a couple of rectifiers. I now have to keep an eye on these cells, and replace them every few years - but there have been no further problems during outages.

Software notes

The EPROM contains a little under 1kB of code, plus look-up tables to convert sunset time to day-of-year (separate tables for spring and autumn), and day-of-year to sunrise and sunset times. The 4Hz reset drive constrains the processing for each reset "tick" to complete within 4096 clock cycles, and the lack of external RAM means there's no stack, so Call/Return instructions are not available.

Building the sunset/sunrise tables was fun. An internet search threw up an all-singing all-dancing solar prediction program, acres and acres of 'C', but I lacked the patience to fathom how it worked and adapt it to my needs. A pathological hatred of the Unix/C mindset didn't help. Instead, I opted for the simple expedient of copying the sunrise and sunset times for each saturday from my diary into a text file, then writing just a few square inches of PASCAL to interpolate them for each day of the year. The tables were output as 4 blocks of DEFW lines for inclusion in the assembler source.

The hard resets and use of checksums to validate volatile data make the system fairly bombproof. It did hang a couple of times in the first few months, but that turned out to be an oscillator problem, cured by replacing the crystal and tweaking the circuit slightly. Since then, apart from the aforementioned capacitor issues, it has run for 24 years without a hitch (and through temperature variations from nearly zero to over 30°C!)


top ▲