Heating Count-Down Timer
MAPJ April 2001 -Jan 2003
Introduction
The count-down timer was originally dreamed up to allow the heating boiler to be forced on for a definite period without re-adjustment of the regular 24 hour time clock. Normally the heating is programmed to be on in the morning and evening, but when no-one is around during the week, the heating is off. However, it is sometimes useful to be able put the heating on during the "off" times. Typically this is for a day off work or in very cold weather. The original system had a simple 'over-ride' switch, but it is all too easy to put the boiler on, for example on an unusually cold morning, but then forget to switch off the over-ride. This both wastes fuel, and makes the building uncomfortably hot.
Many commercial heating controllers partly address this problem by a "1 hour boost" facility. However, the count-down timer was made to be much more flexible and can be programmed from 10 minutes to 10hrs, and was designed to fit a standard (UK) double socket box. This means it may be mounted in a living room, while the main timer is in the boiler room. The output is a relay contact which is wired in parallel with the original over-ride switch, and keeps the heating on while the counter is running down.
However, by changing the software a number of alternative permutations are possible -the circuit is really presented to others not because I expect it to be copied directly, but as a starting point for other projects. Useful parts that may be re-used include the driving of a 7 segment display and a relay to switch the mains. The software makes use of interrupt programming to keep the time based on the 50Hz mains. Readers in other (non 50Hz) countries will be pleased to read that modification of the time keeping routine for other frequencies is a trivial change of source code.
Instructions For Use:-
The timer displays the time remaining extra time for the heating to be operational. Initially (and after the countdown has finished) the timer indicates zero, and the count-down timer has no effect. In this case the boiler operates as normal as set by the original controller.
To run the boiler for additional time, use the + & - buttons to dial up the desired running time.
By pressing the + (more) button the timer will increase by 10 minutes, and if the button is held for more than 0.5 second, then the display will increase by a further 10 minutes for every half second the button is held in. (So for example to set a 1-hr boost press the button for a count of 6, or two hours for a count of 12, etc)
The - (less) button will reduce the time remaining by 10 minutes for every second the button is held in, and pressing both button together will reset the timer to zero immediately.
Once the count-down timer is counting then the boiler will be on regardless of the time on the time switch, as the two sets of contacts are in parallel.
The maximum boost time is 9 hours 59 minutes, although more time can be added once the timer has begun to run down.
Once the timer is programmed the countdown will begin; the boiler should come on a few seconds after the last button-press. The display will begin reducing back to zero minutes by minute. You can still add or remove time while the timer is running.
Implementation:-
A PIC16F872 micro-controller, made by Arizona Microchip forms the heart of the timer. The chip is clocked by its own RC timer clock, but the 50Hz mains signal provides a counter clock, which is divided down to produce the interrupt period of 0.1 Sec. The interrupt routine scans the buttons, and updates the registers representing minutes, tens of minutes and hours when the appropriate counts are reached.
For the rest of the time, when the processor is not scanning buttons or updating registers, it is operating the display. The display is 3 seven-segment digits, nominal 20mm high, in high visibility red. Each digit is displayed in turn, but the clocking between them is rapid enough that the eye perceives the display as being permanently lit. This trick allows the wiring to be simplified considerably, as only 8 segment signals and 3 digit signals are needed to drive all three digits and decimal points.
A possible front panel layout is shown below.

A possible front panel layout which suits a UK double socket back-box
Program Description:-
The program description is best read in conjunction with the two flowcharts. The first represents the main program flow, and the second the interrupt routine. The PIC is initialised with all the correct IO configuration, and the timer counter register is loaded.
The main program then enters an endless loop displaying each digit, minutes, tens of minutes and hours in turn. The execution of this loop is asynchronous, and is interrupted every time the counter (clocked by 50z AC on pin A4) reaches zero.
The main time keeping and calculation is performed inside the interrupt routine, which is called 10 times per second. Firstly, as we cannot be sure what stage the main routine had reached when it was interrupted, the working registers (accumulator and flags) are saved, for restoration at the end of the routine. To avoid the interrupt routine itself being interrupted, and causing a lock-out all further interrupts are disabled until the end of the routine. (Although there is plenty of time in 0.1 seconds for the routine to complete safely, this precaution is good practice, and such a fault is just about possible with noisy mains, although then the unit would keep very bad time!) On most calls to this routine the 'sectenths' counter is increased by one and the routine finishes. However when the count reaches 60 (corresponding to 1 minute) the minute count is reduced by one, and if necessary carry from tens of minutes, and hours takes place.
For rapid testing a 'speedup' of a factor of ~200 making one minute about half a second may be applied, by grounding bit 5 of port B. This is handy during development for testing all the digits, and correct carry operation without waiting for 9Hrs 59 minutes. Once normal operation is confirmed this pin can be lefy open circuit. The interrupt routine also monitors the push buttons, and the sectenths counter is used to give an auto-repeat action when the up or down button is held in for a long time.
Configuration used by the program:-
The PIC supports a maximum of 64 byte wide variables, called F registers. These are used by the C compiler tohold the variables. The exact mapping is saved in the assembler output files. Some of the registers re hardware specific, and as thee mut correspond to the circuit these are described here
Port A (Address 05) used bits 0,1,2 as common cathode drives for the seven segment display, bit 3 is used to switch the boiler via relay. The four outputs are buffered and inverted by a ULN2003 octal transistor buffer. Bit 4 is set to be the timer counter input.
|
Bit 7 |
Bit 6 |
Bit 5 |
Bit 4 |
Bit 3 |
Bit 2 |
Bit 1 |
Bit 0 |
|
N/A |
N/A |
N/A |
50Hz CLK IN |
D3=Relay |
D2 =Hrs |
D1=Tens |
D0=Mins |
TRIS A (Address $85) I/O bit mask for port A. loaded with 00001111 during start up to set the lower 4 bits to be outputs.
Port B (Address 06) bits 0-5 inputs with pull-up pins bits 4,5,6,7 used as outputs to select which digit is on display, or to select the relay driver.
|
Bit 7 |
Bit 6 |
Bit 5 |
Bit 4 |
Bit 3 |
Bit 2 |
Bit 1 |
Bit 0 |
|
PGM CLK |
PGM CLK |
Test-mode input |
SPARE |
SPARE |
SPARE |
-input |
+ input |
The inputs are configured with on-chip pull up, so low indicates button pressed, high = not pressed.
TRIS B (Address $86) I/O bit mask for port B. loaded with 00110011 during start up.
Port C (Address 07) bits 0-5 inputs with pull-up pins bits 4,5,6,7 used as outputs to select which digit is on display, or to select the relay driver.
|
Bit 7 |
Bit 6 |
Bit 5 |
Bit 4 |
Bit 3 |
Bit 2 |
Bit 1 |
Bit 0 |
|
DP |
E |
C |
D |
G |
B |
F |
A |
The outputs drive the segments via a series resistor (680ohms) with on-chip pull up, high lights the appropriate segment when the particular cathode is also selected by port A.
TRIS C (Address $87) I/O bit mask for port C loaded with 00000000 (all outputs)during start up.

Segment allocation as per convention above
Other useful registers
Option Register (Address 81)
|
Bit 7 |
Bit 6 |
Bit 5 |
Bit 4 |
Bit 3 |
Bit 2 |
Bit 1 |
Bit 0 |
|
Pull up 0 (on) |
Int +/- 1 (+) |
Timer 1 (ext) |
Timer +/- 1 (+) |
Prescale 0 (timer) |
Divisor 0 |
Divisor 0 |
Divisor 0 (divide by 1) |
Interrupt Control Register (Address 8B)
|
Bit 7 |
Bit 6 |
Bit 5 |
Bit 4 |
Bit 3 |
Bit 2 |
Bit 1 |
Bit 0 |
|
Global int 1(on) |
PEIE 0 |
T0IE 1 |
INT E |
RBIE 0 |
T0 Flag 0 |
Int F 0 |
RB F 0 flag |
Although we dont need it, in an application where different sources of interrupt may occur, the flags may be read to determine which source caused the interrupt. We are only interested in the Timer interrupt. In any case to re-enable the interrupt at the end of the interrupt routine we set the flags to zero before returning to the main program.
Status register (Address 03), used in conjunction with a bit test for the zero flag.
|
Bit 7 |
Bit 6 |
Bit 5 |
Bit 4 |
Bit 3 |
Bit 2 |
Bit 1 |
Bit 0 |
|
0 reserve |
0 reserve |
RP0 bank |
timeout |
PD |
Z (zero flag) |
DC nibble carry |
C Carry |
The upper bits are used on higher family processors to address more memory. Not a concern in this project.