Вы находитесь на странице: 1из 16

Circuit Description of programmable

timer for appliance


With the combination of two 14-bit binary ripple counter (IC 2 & IC4), three quad
two input NAND gate ICs (IC1, IC3 and IC5) and a relay driver transistor with some
passive component the project programmable timer for appliance is successfully
completed. The NAND gates (N3 with N1 and N2) here is used as first oscillator and
NAND gates (N4 and N5) is used as second oscillator and provide clock pulse to
binary ripple counter IC (IC2 and IC4) respectively at rate of one pulse per second
where timing control circuit formed by NAND gates (N 6, N10 and N11) is used to
inhibited the rate of pulse.
Lastly the transistor relay driver transistor T 1 with NAND gates N8 and N9 is used
to energize the relay. Here for heavy load, a higher current rating relay is used in
order to control the appliance.

PARTS LIST
Resistors (all -watt, 5% Carbon)
R1, R3 = 4.7 M
R2, R4 = 1 M

R5, R8, R9 = 1 K
R6, R7 = 2.2 K
VR1, VR2 = 1 M potentiometer

Capacitors
C1, C4 = o.33 F
C2, C3 = 0.01 F
C5 = 1000 F/35V

Semiconductors
IC1 (N1 N3), IC3 (N4 N7), IC5 (N8 N11) = CD4011 (quad two input NAND gate IC)
IC2, IC4 = CD4020 (14 bit binary ripple counter)
D1 = 1N4007
T1 = BC548

Miscellaneous
LED1 = RED
LED2 = GREEN

PROGRAMMABLE DIGITAL TIMER SWITCH USING


A PIC MICROCONTROLLER
Posted on January 5, 2011 by R-B 309 comments

Digital timer switches are used to control the operation of electrical devices
based on a programmed schedule. This project describes a programmable digital
timer based on a PIC16F628A microcontroller that can be programmed to
schedule the on and off operation of an electrical appliance. The appliance is
controlled through a relay switch. This timer switch allows you to set both on and

off time. That means, you can program when do you want to turn the device on
and for how long you want it to be remained on. The maximum time interval that
you can set for on and off operation is 99 hours and 59 minutes. The project uses
a 162 character LCD with 4 push buttons to interact with the user.

Circuit Design
The circuit diagram of this project is shown below. A 5 V relay is driven by a
PN2222 transistor that is controlled by RB3 pin of PIC16F628A. Digital inputs
from the 4 push buttons are read through port pins RA2, RA3, RA4, and RB0. The
functions of these push buttons are discussed in the operation section below. A
standard 162 character LCD is used in the project to display the the device
status, program menu and time. The LCD is operated in 4-bit mode, therefore,
only 6 I/O pins of PIC16F628A are required to drive it. A piezoelectric buzzer
provides audible tone when the timer is started and stopped. It also beeps when
the device is turned on or off. The + 5V power supply for the circuit is derived
from a LM7805 regulator IC. The input to the regulator is given from a 9V DC
wall adapter.

In the circuit diagram, the pins 15 and 16 of the LCD are shown open. These pins
are available only in those LCDs that have a back light illumination LED. The pins
15 and 16 are the anode and the cathode of the LED. If your LCD has the back
light LED, you can connect these pins to the power supply terminals with a
39 ? resistor in series. The backlight LED enhances the readability of the LCD
display in low illumination condition.
The complete circuit soldered on a general purpose prototyping circuit board is
shown below.

Operation of the timer

The timer gets inputs from the 4 push buttons. Their functions are described as
follows:

ON/OFF TIME : This timer device allows you to set both on and off time.
When the timer is initially powered on, the device is in off condition and
both on and off times are 0. Pressing this button, you can switch between
the on and off time on the display.

SELECT : This allows you to select between the on and off time settings as
well as hour and minute digits. The selected digit is incremented by
pressing the ON/OFF TIME button.

ENTER : When the appropriate hour and minutes are selected, pressing
ENTER finalize the corresponding on or off time.

START/STOP is to start or stop the timer. If the timer is already on, you can
stop it at anytime during its operation by pressing this button.

Now lets see how it works. Suppose, the device connected to the relay switch is
needed to be turned on after 2 minutes. Further, once it is turned on, it is
required to be on for next 20 minutes. In this case, the off time is 00:02 and the
on time is 00:20, in hh:mm format. Once the timer is started, the device will be
turned on after 2 minutes and remained on for 20 minutes. After that it will be
turned off again. The following video shows how to do this.

Software
The firmware is developed using the MikroC Pro for PIC compiler.
Download the Source Code
Download the HEX file

Digital timer switch

Update (04/12/2013)
Mark Weir from Australia sent us his revision of our Programmable digital
timer switch project. He modified the original code, which was written for
PIC16F628A, to incorporate it with PIC18F4620 microcontroller, while hardware
and overall functionality remain the same.

Digital timer using PIC18F4620

Here is a link to download his modified version of the firmware written in MikroC
compiler.

/*
* Project name: Programmable Digital Timer
* Copyright:
(c) Rajendra Bhatt, 2010.
Modified by MRW 10/03/13
MCU:
PIC18F4620

Oscillator:

XT, 4.0 MHz

*/
// LCD module connections
sbit LCD_RS at RB2_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;
sbit LCD_RS_Direction at TRISB2_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;
// End LCD module connections
sbit MODE at RA2_bit;
sbit SELECT at RA3_bit;
sbit ENTER at RA4_bit;
sbit START at RA1_bit;
sbit RelaySW at RD1_bit;
// Define Messages
char MSG1[] = "Device is ";
char MSG2[] = "OFF";
char MSG3[] = "ON ";
char MSG4[] = "HH:MM";
unsigned short HHMM_Pos[] = {6, 7, 8, 9, 10};
unsigned short ON_Time[] = {0, 0, 10, 0, 0}; // 10 + 48 is :
unsigned short OFF_Time[] = {0, 0, 10, 0, 0};
unsigned short Mode_Select = 0 ; // 0:ON, 1:OFF
unsigned short i, j, k, Timer_On, Get_Input, Cur_Pos, Cur_On;
unsigned short temp, refresh, Num, HalfSec, Blink, ChangeMin=0;
unsigned short OFF_HH, OFF_MM, ON_HH, ON_MM;

void Disp_First_Row(){
Lcd_Out(1,1, MSG1);
if (RelaySW == 0) Lcd_Out(1,11, MSG2);
if (RelaySW == 1) Lcd_Out(1,11, MSG3);
}
void Disp_Char(unsigned short col, unsigned short chr){
Lcd_Chr(2, col, chr+48);
}
void Disp_Time(){
for(i=0; i<5; i++){
if(!Mode_Select){
Lcd_Out(2,1, MSG2);
Disp_Char(HHMM_Pos[i],OFF_Time[i]);
}
if(Mode_Select){
Lcd_Out(2,1, MSG3);
Disp_Char(HHMM_Pos[i],ON_Time[i]);
}
}
}
void play_sound(){
Sound_Play(2500, 500);
}
void debounce(){
Delay_ms(250);
}
void cursor_left(){
for(j=0; j<5; j++){
Lcd_Cmd(_LCD_MOVE_CURSOR_LEFT);
}
}
void disable_timer(){

INTCON = 0x00;
RelaySW = 0;
INTCON.T0IF = 0;
Timer_On = 0;
Blink = 0xff;
Mode_Select = 0;
Disp_First_Row();
Disp_Time();
play_sound();
}

void interrupt() {
Num ++;
// Interrupt causes Num to be incremented by 1
if(Num == 9) {
HalfSec ++;
// Increase sec
Num = 0;
Blink = ~Blink;
if (HalfSec == 120){
HalfSec = 0;
ChangeMin = 1;
}
}
TMR0L = 39;
// TMR0 returns to its initial value
TMR0IF_bit = 0;
// Bit T0IF is cleared so that the interrupt could reoccur
}
void main() {
CMCON = 7;
// Disable Comparators
TRISA = 0b00011111;
TRISB = 0b00000000;
TMR0L = 0;
T0CON = 0xC7;
GIE_bit = 1;
TMR0IE_bit = 1;
Sound_Init(&PORTA,5); // Initialize Buzzer o/p pin
RelaySW = 0;
Timer_On = 0;
Get_Input = 0;
Cur_Pos = 0;
Cur_On = 0;

refresh = 0;
Num = 0;
HalfSec = 0;
Lcd_Init();
// Initialize LCD
Lcd_Cmd(_LCD_CLEAR);
// Clear display
Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
Lcd_Out(1,1, "Welcome to");
Lcd_Out(2,1, "Walark Timers.com");
i=0;
while(i<4){
debounce();
i ++;
}
Lcd_Cmd(_LCD_CLEAR);
Disp_First_Row();
Lcd_Out(2,4,"-");
Lcd_Out(2,12, MSG4);
Disp_Time();
do {
if(!MODE && !Timer_On){
debounce();
if(!Get_Input){
Mode_Select = ~Mode_Select;
Disp_Time();
}
if(Get_Input){
if(!Mode_Select){
OFF_time[Cur_Pos] = OFF_time[Cur_Pos]+1;
temp = OFF_time[Cur_Pos];
switch (Cur_Pos){
case 0: if(temp > 9) OFF_time[Cur_Pos]=0;
break;
case 1: if(temp > 9) OFF_time[Cur_Pos]=0;
break;
case 3: if(temp > 5) OFF_time[Cur_Pos]=0;
break;
case 4: if(temp > 9) OFF_time[Cur_Pos]=0;
break;
}

Disp_Char(6+Cur_Pos, OFF_time[Cur_Pos]);
}
if(Mode_Select){
ON_time[Cur_Pos] ++;
temp = ON_time[Cur_Pos];
switch(Cur_Pos){
case 0: if(temp > 9) ON_time[Cur_Pos]=0;
break;
case 1: if(temp > 9) ON_time[Cur_Pos]=0;
break;
case 3: if(temp > 5) ON_time[Cur_Pos]=0;
break;
case 4: if(temp > 9) ON_time[Cur_Pos]=0;
break;
}
Disp_Char(6+Cur_Pos, ON_time[Cur_Pos]);
}
Lcd_Cmd(_LCD_MOVE_CURSOR_LEFT);
}
} // END if(!MODE)
if(!SELECT && !Timer_On){
debounce();
Get_Input = 1;
if(Cur_On) {
Cur_Pos ++;
if (Cur_Pos == 2) {
Lcd_Cmd(_LCD_MOVE_CURSOR_RIGHT);
Cur_Pos ++;
}
if(Cur_Pos > 4) {
Lcd_Cmd(_LCD_MOVE_CURSOR_RIGHT);
Cur_Pos = 0;
cursor_left();
}
else Lcd_Cmd(_LCD_MOVE_CURSOR_RIGHT);

}
if(!Cur_On) {
Cur_On = 1;
cursor_left();
Lcd_Cmd(_LCD_UNDERLINE_ON);
}
}
if(!ENTER && Get_Input){
debounce();
Get_Input = 0;
Cur_On = 0;
Cur_Pos = 0;
Disp_Time();
Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
}
if (!START && !Get_Input){
debounce();
switch(Timer_On){
case 0: play_sound();
Timer_On = 1;
T0CON = 0xC7; // Prescaler (1:256) is assigned to the timer TMR0
TMR0L = 39;
// Timer T0 counts from 39 to 255
INTCON = 0xA0; // Enable interrupt TMR0 and Global Interrupts
TMR0IF_bit = 0;
Mode_Select = 0;
Blink = 0;
Disp_Time();
break;
case 1: disable_timer();
break;
}
}
if(Timer_On){
OFF_HH = OFF_Time[0]*10 + OFF_Time[1];
OFF_MM = OFF_Time[3]*10 + OFF_Time[4];
ON_HH = ON_Time[0]*10 + ON_Time[1];

ON_MM = ON_Time[3]*10 + ON_Time[4];


switch(Blink){
case 0: Lcd_Chr(2,8,' ');
break;
case 255: Lcd_Chr(2,8,':');
break;
}
if(!OFF_HH && !OFF_MM &&!RelaySW){
if(ON_HH || ON_MM){
RelaySW = 1;
Mode_Select = 0xff;
Disp_First_Row();
Disp_Time();
play_sound();
}
else {
disable_timer();
}
}
if(!ON_HH && !ON_MM && RelaySW){
disable_timer();
play_sound();
}
if(ChangeMin) {
switch(Mode_Select){
case 0: if(OFF_MM == 0 && OFF_HH>0){
OFF_MM = 59;
OFF_HH -- ;
}
else if (OFF_MM >>0) OFF_MM --;
OFF_Time[0] = OFF_HH/10;
OFF_Time[1] = OFF_HH%10;
OFF_Time[3] = OFF_MM/10;
OFF_Time[4] = OFF_MM%10;
break;
case 255: if(ON_MM == 0 && ON_HH>0){

ON_MM = 59;
ON_HH -- ;
}
else if(ON_MM >> 0) ON_MM --;
ON_Time[0] = ON_HH/10;
ON_Time[1] = ON_HH%10;
ON_Time[3] = ON_MM/10;
ON_Time[4] = ON_MM%10;
break;
}
ChangeMin = 0;
Disp_Time();
}
}

}while(1);
}

Вам также может понравиться