Miniature Real-time Controller

Wichit Sirichote, wichit.sirichote@gmail.com
My long history homeuse controller, a Miniature Real-time Controller controls night light, A/C, household appliances with programmable scheduler. Modified source code and hex file for year 2002 readout.source code in c program.

Introduction

This is my long history the device that controls my home's night light, air-conditioner,etc. The device is a Miniature Real-time Controller. The circuit uses only three chips, a 89C2051, DS275(or MAX232), and 74LS07 open collector driver. The scheduler for time on/off of 6-channel output can be made by downloading from PC and saved into onchip RAM. Each output provides a 20mA sinking suitable for driving a homemade opto-triac or big solid-state relay for heavy load.

Hardware

A circuit diagram of the Miniature Real-time Controller is shown in Figure 1. A 89C2051 with a low-cost X-tal 3.579MHz runs timer6.hex. The 6-channel output is P1.2 to P1.7 driving with sink current. A 74LS07 open collector provides approx. max 20mA @12V suitable for driving a homemade opto-triac shown in Figure 2. Two signal diodes, 1N914, provide simple backing up supply for the 89C2051. Since RST uses simple RC circuit, there is no brownout protection and reset switch thus when the controller operated with battery for long time, the chip may knock. Simply take the battery out and put them again. The RS232 level converter, instead of DS275, any converter may use, say MAX232, or simple circuit using two transistors.


Figure 1: Circuit Diagram of Miniature Real-time Controller (a nice circuit diagram was drawn by my student Patra Pienchob).

Homemade Opto-triac

An opto-triac with zero-crossing can be made easily. I have used an MOC3041 to drive 5A 240V triac. A night light used in my home mostly be an incandescent lamp, the circuit below works fine. For such heavy load as air-conditioner, I used a solid-state relay,one from CRYDOM D2410, say.

Figure 2: Example of Connecting homemade optotriac and SSR to the RTC.

Software

Timer6.hex is the hex file for 2051 chip. The original source program timer6.asm was written in assembly with c32 cross assembler format.

Example of scheduler air.pgm was written as a text file. Downloading to the controller may simply do via communication program, Xtalk or any others program but sending each character should matched the receiving speed of the controller. For Xtalk, the speed may reduced by changing CWAIT command( there's no XON/XOFF flow control).

If you use Hyperterminal, you may slow down the sending speed by clicking the ASCII setup menu. There is a dialog box to set delay between each character.

Figure 3 shows an example of downloading scheduler using command p(program) followed by command r(read) to check the stored program.


Figure 3: Checking stored program via Read command after air.pgm downloaded

Figure 4: Using Help, Enter time & Date

Software updated

I got a mail asking for changing year readout. The readout shown in Figure 4 is for Thailand, we use Buddhist Era. So I modified the byte 25 to 20. This byte is fixed to 20, next 100 years you have to change it again to 21, say. But I thought may be no need anymore.

Timer6-1.hex was modified for year 2002, instead of year 2545.

Here is the original source program timer6-1.asm It was written in assembly code with c32 cross assembler format.


Using 8051SBC as a terminal for time setting

The new version of miniature real-time controller is developed with c source code and use 8051SBC as a terminal for time setting. Time scheduler is fixed. To modify it, edit the array, PGM[] and recompile the source code. Figure 5 shows the connection using RS232 cross cable between RTC and 8051SBC. The onboard two buttons are used for HOUR and MIN adjusting.

 

Figure 5: Using 8051SBC terminal for time setting

Source code for 89C2051 chip

Main program is timer0 interrupt driven. The timer0 is set to 16-bit timer mode with 1/10s interrupt rate. Every 0.1s the time functions is entered updating the clock. In time function, the program prints current time every one second and scans the preset scheduler every one minute. Adjusting current hour and minute are done by waiting the character sent from terminal. Command 'h' will adjust current hour and 'm' for current minute. P3.2 has push button key, when pressed it will make P1.7 to logic 0. This key is for manual turn on for some device. I used it for manual turn on the air conditioning, since the scheduler will turn it on at 22:00. Sometime I need it to turn on earlier. The array pgm[] contains 7x3 bytes. The first two bytes for each one are set HOUR:MIN. The third byte is byte to be sent to the output port P1. Logic one for each bit represents ON condition. The output is buffered with open collector gate, 7407, so the bit is then complemented before written.

/*           
 Realtime controller with c source code
 Copyright (C) 2006-2007 Wichit Sirichote, kswichit@kmitl.ac.th
*/
#include <reg51.h>
#include <stdio.h>

char sec10,sec,min,hour;
char i;
char command;
/*
           / air.pgm
           / activates four devices by time setting
           / '1' is on and '0' is off
           / OUTPUT [1...8]
           / output 1 is a SSR controlled 12,000btu air conditioner
           / output 2 is a 7W night lamp at bed
           / output 3 is a 10W lamp at bedroom's door
           / output 4 is a 20W fluorescent at kitchen
           / output 5 reserved
           / output 6 high current 12Vdc solenoid driver
           / output 7 reserved
           / output 8 reserved
/line day time output 1...8
           :01 24 1900 0 0 1 1 0 0 0 0 / on lamp at bedroom door and kitchen
           :02 24 2000 0 1 1 1 1 0 0 0 / also bed lamp, and fan
           :03 24 2200 1 0 1 1 1 0 0 0 / off bed lamp, on air conditioner
           :04 24 2230 1 0 0 0 1 0 0 0 / off door lamp
           :05 24 2310 1 0 0 0 0 0 0 0 / off fan
           :06 24 0530 0 0 0 0 1 0 0 0 / off air-conditioner and on fan again
           :07 24 0600 0 0 0 0 0 0 0 0 / off all
           :00
           */
char pgm[]={ 19,0, 0x30, 20,0,0x78,22,0,0xb8,22,30,0x88,23,10,0x80,5,30,0x08,6,0,0x00};

           print_time()
           {
           printf("\r%02bd:%02bd",hour,min);
           }

           void scan_pgm()
           {
           for(i=0; i<7; i++)
           {
           if(hour == pgm[i*3] && min == pgm[(i*3)+1])
           P1 = ~pgm[(i*3)+2];
           }
           }
get_command()
           {
           if(RI)
           {
           RI = 0;
           command = SBUF;
           }
           else command = -1;
           }
adjust_hour()
           {
           if(command == 'h')
           {
           if(++hour >=24)
           hour =0;
           print_time();
           }
           }
adjust_min()
           {
           if(command == 'm')
           {
           sec =0;
           if(++min>59)
           min =0;
           print_time();
           }
           }
time() 
           {
           if(++sec10==10)
           {
           sec10 =0;
           P3 ^= 0x80;
           print_time(); // print time every second
           
           if ( ++sec >= 60)
           {
           sec = 0;
           scan_pgm(); // scan program every minute
           if ( ++min >= 60)
           {
           min = 0;
           
           if ( ++hour >= 24)
           hour = 0;
           }
           }
           }
}
void timer0int (void) interrupt 1 using 1
 {
           TH0 = 0x8b; // reload timer 0
           TL0 = 0x92;
           time(); // update realtime clock
           get_command();
           adjust_hour();
           adjust_min();
           
           }
void external0int (void) interrupt            0
           {
           P1 &= ~0x80; // turn P1.7 on manually
           }

           void main()
           {
           EA = 1;
           ET0 = 1; // or IE |= 0x82; /* set bit EA and Timer0 enable */ 
           EX0 = 1; // enable external interrupt 0
           SCON = 0x52; // 8-bit UART mode
           TMOD = 0x21; // timer 1 mode 2 auto reload
           TH1= 0xfe; // 9600 8n1 with 3.579545MHz XTAL
           PCON = 0x80; //smod = 1
           TR1 = 1;
           TR0 = 1; // run timer0 and timer1
           hour = 8; // when reset set current time to 8:00
           min = 0;
           sec = 0;
           
           while(1)
           continue;
           
           }
Figure 6: Listing of source code for 89C2051 chip

Source code for 8051SBC

The program prints current time sent from the RTC board on LCD display. Main function is forever loop waiting for ASCII code. If the first character is control code, i.e. value less than 0x20 or SPACE, then the current position of the cursor will set to 2nd line first digit. The RTC sent current time with following format.

printf("\r%02bd:%02bd",hour,min);

If no character in SBUF, then the buttons that tied to GPIO2 are then sampling. Set HOUR key is masked with 0x10, set MIN with 0x20. If the logic at HOUR key is low, then send the character 'h' to RTC board, similarly for MIN key, the character 'm' will be sent..

/* 
Using the 8051SBC as the terminal for time setting the Realtime Controller
The onboard two button switches are used to set Hour and Min
Copyright (C) 2006-2007 Wichit Sirichote, kswichit@kmitl.ac.th
*/
#include <stdio.h>
#include <reg52.h>
xdata char GPIO2 _at_ 0x200;
char *Puts(char *str);
InitLcd(void);
goto_xy(char x,char y);
void putch_lcd(char ch);
char hour_press, min_press;

           print_text()
           {
           char buffer[10];
           if(RI)
           {
           gets(buffer,10);
           goto_xy(0,1);
           Puts(buffer);
           }
           }
get_character()
           {
           char c;
           if (RI)
           {
           c = getchar();
           if(c < ' ') goto_xy(0,1);
           putch_lcd(c);
 }
           }
set_hour()
           {
           if((GPIO2 & 0x10)==0 && hour_press == 0)
           {
           putchar('h');
           hour_press=1;
           }
           }
set_min()
           {
           if((GPIO2 & 0x20)==0 && (min_press == 0))
           {
           putchar('m');
           min_press = 1;
           }
           }
key_released()
           {
           if((GPIO2 & 0xf0) == 0xf0)
           {
           min_press=0;
           hour_press = 0;
           }
           }

           main()
           {
 InitLcd();
           Puts("RTC TERMINAL");
           hour_press = min_press = 0;
           RI = 0;
 while(1)
           {
           get_character();
           set_hour();
           set_min();
           key_released();
           }
}
            
Figure 7: Listing of source code for 8051SBC

Download

Source code RTC4.c terminal.c


 

18 December 2006

recovered 18 December 2015