Академический Документы
Профессиональный Документы
Культура Документы
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
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.
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
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.
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:
*/
// 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 = 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);
}