A Digital Weekly Programmer is able to start and/or shutdown automatically any electrical or electronic devices via relays. The machine runs according to a programmable weekly schedule.
The weekly programmer was designed to support a vast variety of applications, such as automatic watering and garden irrigation systems, control of light sources, control of heating or air conditioning, etc.
The digital weekly programmer supports up to 99 independent actions running on a weekly basis. Each action takes place at an exact time on a specific day of the week, according to the weekly schedule. The programmer supports 3 independent channels (3 relays), so it can control up to 3 independent devices simultaneously.
Apart from the 99 time-depended actions, the programmer also supports 3 asynchronous “interrupts” from 3 digital inputs. Those inputs accept digital sensors to be used to cancel any actions due to external factors. For instance, we may wish to prevent water flow for plant watering when a moisture sensor detects sufficient soil moisture. The programmer has 3 digital inputs for sensors and each input acts on a specific channel. The use of sensors is optional; however it may be extremely valuable in many applications when we wish a scheduled action to be canceled due to any specific external factor.
The electronic circuit of the Digital Weekly Programmer
The Digital Weekly Programmer is based on a Microchip PIC microcontroller. It has a mini 6-key keyboard through which the user enters and modifies the weekly schedule, a liquid crystal display (LCD) for displaying a real-time clock and all the functions of the device, and three electromechanical relays. There are also three inputs for digital sensors. The block diagram of the device is shown here:
Figure 1. The block diagram of the Digital Weekly Timer
The programmer can be powered from 9 to 12V from a small power supply unit. The current consumption is at about 7mA on standby, and the peak power consumption is less than 2W and occurs during times when all relays are energized simultaneously.
In the event of a power failure, both the clock and the programs entered by the user will be reset (erased from the memory). Therefore, in applications where continuous operation is required on 24 hours a day - 365 days a year, the use of a backup power unit such us a backup battery, a small photo-voltaic system or a UPS is essential.
The PIC18F2520 microcontroller is the "heart" of the circuit (see electronic schematic on figure 2). The microcontroller is connected to the liquid crystal display through 7 I/O lines (D1 to D7) and via P1 connector. The LCD is not shown on the schematic diagram and it is assumed that it is attached on P1. We use a typical 2x16 (2 lines with 16 characters per line) alphanumeric display, compatible with HD44780 standard.
Figure 2. The electronic circuit of the Weekly Programmer (click to enlarge)
The 6 buttons of the keyboard are connected to the microcontroller through another 6 input / output lines (IO). The microcontroller senses any button-press when a logic transition from 0 to 1 occurs at any of those lines.
The three relays, K1, K2 and K3, are controlled from transistors Q1, Q2 and Q3, respectively through logic signals from I / O lines T1-T3. There are 3 more digital lines, SN1 to SN3, used as digital inputs for the sensors.
The microcontroller runs at 4MHz from crystal Y2. There is also a second crystal in the circuit, Y1, which is used as a time base for the real-time clock of the device. Y1 is a high quality clock-crystal at 32.768 KHz. The accuracy of the programmer's clock is absolutely depended on this crystal.
U2 is a standard 7805 linear regulator and it is used to step down the power supply voltage at 5V. D1, D2 and D3 are used as protection diodes, to protect Q1-Q3 transistors from any reverse current due to the inductance of the relays coils.
The D4, D5 and D6 are 5mm LEDs and are used as indicators for the status of the three relays. That is, the D4 LED lights up when the first channel (relay K1) is on, D5 when the second channel (relay K2) is on, and D6 is activated when the 3rd channel is on. The actual status of the three relays is also displayed on the LCD.
Any device that we wish to control may be connected to the relays via connectors P4, P3 and P2 for the 1st, 2nd and 3rd channel, respectively. P4, P3 and P2 are standard three-pin PCB terminals. In order to control any device, only 2 of the 3 pins are actually required. The reason that we provide three-pin PCB terminals is simply because the pair 1-2 represents a normally-on switch, while the pair 2-3 is a normally off switch. The user can choose to use any pair he wants for his own case. The difference between different pairs lies in the fact that the pins 2-3 in every PCB terminal provide a "positive logic" functionality (i.e. the current flows and the switch is closed when the corresponding channel is on) whereas the pair 1-2 provides a “negative logic” functionality (that is to say, the current is switched on when the corresponding channel is off).
The 32.768KHz clock crystal is used as a time base for the 16-bit internal timer-1 of the PIC18F2520 microcontroller, after the crystal frequency is divided by 2 by an internal prescaler. The timer-1 overflows when it counts 65536 (216) pulses. With the current settings, each overflow occurs every 4 seconds and triggers an interrupt event.
The computer code
The computer program is written in C and has been compiled into machine code by the Microchip’s XC8 compiler. We used version 1.37.
The computer code includes initialization commands, main program commands and commands that are executed on an interrupt service routine. During start up the controller executes initialization commands and then runs the main program on a closed loop. The program goes as follow:
- Start - screen initialization
- Initiate relays off
- Initialize program variables and start the real-time clock
- Start of an endless loop
- Check if a key has been pressed
- If there is a key press, perform any key operation. If not, continue to the next step
- Go back to step 5
In addition to the main program, code is also executed within an interrupt service routine. The interrupt takes place every 4 seconds at each overflow of timer-1. The interrupt code-flow goes as follow:
- Increase by 1 the global time-keeping variable (the time-keeping variable acts as a counter which counts quartets of elapsed seconds. A value of 0 corresponds to Sunday - 00:00).
- Convert the value of the time-keeping variable to time and day and display system’s clock on LCD.
- Check whether to perform any of the 99 programmed actions, based on system‘s clock, and sensors.
Below, there is the source – code of the main routine:
void main(void)
{
unsigned char k=0;
Delay1KTCYx(9);
ADCON1=15;
TRISC = 0b00011111; // RC5-7 as outputs
TRISA = 255; // PORTA as input
TRISB = 0; // PORTB as output
mode=0; // Starts with Clock-mode
// Switch off all relays
for (k=1; k<4; k++)
{
releoff(k);
}
// Initialize prclock[100] and prdo[100] matrices.
for (k=1; k<100; k++)
{
prclock[k]=20000; // 20000 means that current k program is Idle - no function
prdo[k]=20; // 20 means Idle - no function
}
//Starts Timer 1 - interrupt take place at timer's 1 overflow
OpenTimer1(TIMER_INT_ON & T1_16BIT_RW & T1_SOURCE_EXT & T1_PS_1_2 & T1_OSC1EN_ON & T1_SYNC_EXT_OFF);
PIE1bits.TMR1IE=1; // 1 = Enables the TMR1 overflow interrupt
IPR1bits.TMR1IP=1; // 1 = High priority
RCONbits.IPEN=1; // 1 = Enable priority levels on interrupts
INTCONbits.PEIE=0; // When IPEN = 1 - 0 = Disables all low priority peripheral interrupts
INTCONbits.GIE=1; // When IPEN = 1 - 1 = Enables all high priority interrupts
OpenXLCD(FOUR_BIT & LINES_5X7 ); // Initialize LCD
timer(clock,0); /* Find current day, hour and minutes (affects day, time, min global variables)*/
time(); // Display current time on LCD
disch(); // Display current Channel state at LCD's second line
//infinite loop starts here
label: while (button()==0); //check for any button press
function (button()); // Performs the appropriate function when a button is pressed
while (button()>0)Delay10KTCYx(5) ; //waits for button release - debounce
goto label; // infinite loop
}
The interrupt service routine runs periodically, every 4 seconds exactly, regardless of the main routine and regardless of the keyboard state. The code of the interrupt service routine is presented here:
void interrupt timer_isr ()
{
PIR1bits.TMR1IF = 0; // Set interrupt flag to 0
sec4=sec4+1; // sec4 increment by 1 for the 4sec have elapsed
if (sec4> 14) // if sec4>14 then 1 minute has elapsed and: {
sec4=0; // sec4 settled back to 0
clock=clock+1; // clock increment by 1
if (clock>10079) clock=0; // if clock>1079 means it is Sunday 00:00, so the clock is settled back to 0
if (mode==0) // mode=0 means that the LCD must refreshed with the current time (time mode)
{
timer(clock,0); /* Find current day, hour and minutes (affects day, time, min global variables)*/
time(); // Displays current clock-time on LCD
}
}
action(); // check for action according to program
}
How to build the Digital Weekly Programmer
If you just want to experiment, you may build the unit on a breadboard. However, if you wish to build a practical and a well-looking device, then you‘ll definitely need a printed circuit board (PCB). You may make your own printed circuit board or you may use the one we provide below.
The printed circuit we have made for the programmer is a single-sided board (copper is at one side only). All components, including the LCD, can be mounted on the printed circuit board as you can see in the photo:
Photo 1. All components, including the LCD, are assembled on the same board
All resistors used in this project are of 1/4 watt type, and of 5% tolerance or better. We use low voltage capacitors of vertical-mount type and all of them have a 5mm footprint (the horizontal distance between pins of the same capacitor is about 5mm). We do not use electrolytic capacitors apart from C6 and C8. Those 2 capacitors must be mounted carefully according to their correct polarity.
There is no need for any heat sink for the 7805 regulator. However, if you wish to be sure that the regulator will always be "cool" under the most extreme conditions; you may use a standard TO-220 heatsink. Alternatively, you may mount the regulator onto the interior metallic surface of a metallic box which will be also used to house the whole device.
The most essential detail regarding the construction is that you will need to program the microcontroller with the firmware that we provide below. Programming can be done with any programmer that supports PIC18F2520. Originally, we used Microchip’s PICKIT 3. With PICKIT-3 or any other similar programmer, burning the code into microcontroller’s memory can be done on board. There are also many programmers for off-board programming.
Once you’ll burn the code into the microcontroller and the circuit board will be assembled, the device should work immediately upon powering-up. You will only need to adjust the contrast of the LCD from the R1 trim pot. We wish that you’ll be completely satisfied with the accuracy and the reliability of the Digital Weekly Programmer.
Normally, access to the source code is not required for the purposes of construction of the device. The only code you’ll need is the machine code which is provided freely below. However, if you are familiar with C programming and you wish to make any modifications or improvements to the functionality of the weekly programmer, you may look for access to the source code.
How to use the weekly programmer
The programmer can control up to 3 different loads (devices) through its 3 relays. You simply have to use the relays as switches for the devices you want to control. You can use either the normally-on contacts or the normally-off contacts of the relays. Relay contacts are accessed via P4, P3, P2 for channel 1, 2 and 3, respectively. P4, P3 and P2 are classic 3-pin wire-terminals. At each "terminal", the contact pair 1-2 is normally-on while 2-3 pair is normally-off. You can choose to use any pair of contacts you want for your own case.
Photo 2. P4, P3 and P2 are classic 3-pin wire-terminals
Once the loads are connected, you’ll have to program a weekly schedule for activating or deactivating them during a week. You may program up to 99 actions regarding activating or deactivating. Simply select the day and time that a channel will have to be turned on or off, and the program will be written to the microcontroller's memory and will run faithfully during every week.
For special applications, such as when you’ll use the programmer for automatic watering systems, it may also be helpful to connect sensors to P5, P6 and P7 terminals for channels 1, 2 and 3, respectively. Thus, for instance you may connect a soil moisture sensor to P5 to prevent watering in channel 1 if there is sufficient ground moisture. The sensor you will connect to P5 will only prevent activation on channel 1 (prevents from switching on) and will have no effect in any other channel. For the other two channels, you may use sensors on P6 and P7 terminals, respectively.
Here, we do not refer to any sensor circuits e.g. for humidity, light, temperature etc. But you may take a look at the automation projects section for making different types of sensors. Any digital sensor that has a TTL output can be connected to the weekly programmer. Just keep in mind that a sensor prevents activation of the corresponding channel (relay) when its output happens to be at logic 1.
Photo 3. P5, P6 and P7 are 2-pin terminal blocks for the 3 digital inputs
We must also refer to the fact that the relays used in the prototype are low-power small 5V-coil relays. This selection was mainly for space saving on the circuit board. Those relays cannot support large loads. If your load is over 100W (or more than 0.5A at 220V) it will “burn” the relays. Therefore, if you wish to drive large loads you’ll need to use higher power relays than those of the programmer. In this case, simply use the low power relays of the programmer to control larger relays that may be connected externally or mounted on an electrical panel.
Lastly, we should remind again that in the unexpected event of a power failure both the clock and the programs will be erased from the programmer’s memory. That is why we recommend the use of a backup battery, or of a small photo-voltaic system or a UPS in applications where continuous operation 24 hours a day - 365 days a year is essential.
Mini User Manual
The Digital Weekly Programmer has 6 keys, as shown in the photo. These buttons are named as "mode", "position", "set", "ch1", "ch2" and "ch3" (from left to right).
Photo 4. The Digital Weekly Programmer has a 6-keys keyboard
As soon as you power-up the device, the clock will appear on the first line of the LCD as:
"Clock: Sun 00:00"
(That is, Sunday 00:00)
And the second line of the screen will show:
"1OFF 2OFF 3OFF"
(That is, the 1st channel is off, the 2nd channel is off and the 3rd channel is off)
How to set the clock
- On clock’s screen, press the "position" button to move the cursor to various positions on the screen. Each time you press the "position", the cursor appears and blinks in a different position
- In any position of the blinking cursor, press the "set" key as many times as needed to change the day, hour or minutes of the clock in that specific position.
- Repeat the above steps as many times as needed to set the programmer's clock.
By finishing the settings, the programmer's clock will be set and the clock will "run" normally. If you do not press any other button, the cursor will disappear from the screen in a little while (about one minute after the last press of a button). Alternatively, if you wish to move the blinking cursor away from the screen immediately, just press the "position" button a few times until the cursor "exits" from the screen.
Photo 5. A snapshot of the clock's screen
How to program a weekly schedule of actions:
- On clock’s screen, press the "mode" button to enter into programming mode.
By entering in the programming mode, you will see at the first line of the LCD:
PR DA TIME DO
(These are abbreviations of the "program", "day", "hour" and “what to do”)
The second line of the screen will show:
01 XX XX: XX XXX
(That is, “1st program”, “blank day”, “empty time”, blank action)
- Press the "position" button to move the cursor to various positions on the screen. Each time you press the "position", the cursor will flash in a different position on the 2nd line of the screen.
- In any position of the blinking cursor, press the "set" key as many times as needed to change the serial number of the program, day, hour, minutes, and action.
- Repeat the above steps as many times as needed to set up to 99 different programs. Of course, you do not have to set up all 99 programs but just those you need - leave the rest blank.
- After finishing "programming", press the "mode" button to return to the clock display.
Possible actions ("DO") are "1-ON", "1-OFF", "2-ON", "2-OFF" and “XXXX "that corresponds to commands: "activate channel 1 ","deactivate channel 1 ", "activate channel 2 "," deactivate channel 2 "," activate channel 3 "," deactivate channel 3" and “nothing to do", respectively.
Photo 6. A snapshot of the programming screen
How to modify an existing program
- Press the "mode" button to enter the programming screen.
- Press the "position" button to move the cursor to any digit of the serial number of the program.
- When cursor blinks on a digit of a serial number of any program, set the program number you wish to modify with the "set" button.
- Then, modify the day, hours, minutes and the “action” in this program according to the programming procedure mentioned in the previous section.
How to clear - reset an existing program
- Press the "position" button to move the cursor to any digit of the serial number of the program.
- When cursor blinks on a digit of a serial number of any program, set the program number you wish to modify with the "set" button.
- Once you have selected the program number you wish to reset, press the "position" button as many times as needed so that the cursor "goes out" from the screen.
- While the cursor is out of the screen, press the "set" button and this will reset the corresponding program. All variables for this program will be replaced with XXX ... XXX.
- When finished, press the "mode" button to return to the clock screen.
How to turn-on or off a channel manually
- To manually activate or deactivate channel 1, press the "ch1" key. Each time you press the “ch1” button, channel 1 changes state, from off to on and vice versa.
- To manually activate or deactivate channel 2, press the "ch2" key. Each time you press the “ch2” button, channel 2 changes state, from off to on and vice versa.
- To manually activate or deactivate channel 3, press the "ch3" key. Each time you press the “ch3” button, channel 3 changes state, from off to on and vice versa.
Watch out for safety!
- Observe to meet all the required safety rules for electrical insulations on all electrical connections you will make.
- Use fuses in all loads.
- Remote-controlled devices can be started at any time! Do not rest in predictions and speculations. Therefore, if you are handling with devices with moving parts, or with devices which produce heat or electric power stay always at a safe distance from them. Be careful that during making changes to the programmer, and due to improper handling or malfunction, any remote controlled device can be started unexpectedly.
- Potentially dangerous remote-controlled devices should be installed in non-accessible areas and all safety rules must be respected.
- Never use the programmer to handle explosives - flammable materials or fuels!
Attachments
In order to program the micro-controller you'll need the machine code. Click here to download the machine code in a standard .hex file for free.
You may also download the PCB-Artwork for the Digital Weekly Programmer and PCB assembly details for a small fee.
Download the source code in C (paid download).