Garrett’s DIY #2 – Home Automation Project – Part One: Real-Time Clock and Calendar

DIY Home Automation Project
Part One: Real-Time Clock and Calendar


Welcome to the first article in a series about developing a home automation controller! I’ll be developing this project as the series progresses, keep an eye on Zedomax for updates.

Home automation has been around for decades, but in today’s technology-saturated world it’s surprisingly rare. Not many people are convinced of the advantages home automation can deliver. It’s seen as a curiosity, instead of a necessity.

Here’s an example that might change your mind. Consider the one piece of automation that exists in nearly every home: the thermostat. You don’t have to think about turning the furnace or air conditioner on and off, you merely set a desired temperature that you find comfortable. The thermostat does the rest. This saves you a lot of time and frustration, as opposed to walking into the furnace closet and flipping a switch every time you’re too hot, or too cold. Applying automation to other devices can deliver just as much of a benefit.

One of the most useful types of automation is scheduling. Based on the time, date, and time of year, you may want devices to behave differently. This article deals with the first step in creating a scheduled automation system: accessing and processing the current time and date.

The equipment I’ve chosen is a Cubloc CB290 with the CB290-Proto board. I’ve also selected a 16×2 vaccum-fluorescent character display, the CVFD. From a hardware standpoint, this is easy: simply plug the CB290 modules into the board, and the CVFD into the CuNet connector, and we’re ready to start coding.

The Cubloc CB290 offers an internal real-time clock. It will keep accurate time, and provides easy access to the current time and date. The CB290-Proto board has a supercapacitor to maintain the clock for several hours if power should fail (much longer if the capacitor is replaced with a lithium backup battery).

Today’s code accomplishes two goals: retrieve time data from the RTC for later use in scheduling, and display the information in a human-readable format. First I’ll initialize the device and declare several variables I want to be available globally (every part of the chip can access them).

‘ Home Automation Project
‘ Part One: Real-Time Clock & Calendar

‘ Created on 11/14/2006
‘ Garrett Mace
‘ Comfile Technology, Inc.
                                               
‘ This example code is distributed as-is and
‘ is not intended for critical applications
‘ involving the risk of damage or injury.

‘Device initialization
Const Device = CB290
Ramclear

‘Global variables initialization
Dim RTC_Second As Byte, RTC_Minute As Byte, RTC_Hour As Byte, RTC_BCD_Date As Byte
Dim RTC_Date As Byte, RTC_Day As Byte, RTC_Month As Byte, RTC_Year As Byte

Dim Updated As Byte   ‘ Flag to determine if entire display has been updated
‘  since information has changed

The RTC_xxx variables will store the time as last retrieved from the real-time clock. The clock provides binary-coded-decimal (BCD) numbers, so before storing the time each value should be converted to a format easier to use in our program. I’m also declaring an “Updated” variable which currently holds a flag indicating whether the display has been fully painted.

‘ Serial port initialization
Opencom
0,115200,3,16,16        ‘ Set serial port to receive data for time synchronization
On Recv0 Gosub SyncTime         ‘ Interrupt to time synchronization routine
‘ when serial data has been received

The above code sets an interrupt on the Cubloc serial port. When the controller detects that data has been received, it will jump to the SyncTime routine. This is for the purpose of receiving a time sync signal from a computer as an easy way to set the RTC to the correct time.

‘ Data constant arrays
Const String * 2 AmPm = (“PM”, “AM”)
Const String * 2 DaySuffix = (“th”, “st”, “nd”, “rd”)
Const String * 3 Weekdays = (“Sun”, “Mon”, “Tue”, “Wed”, “Thu”, “Fri”, “Sat”)
Const String * 3 Months = (“Jan”, “Feb”, “Mar”, “Apr”, “May”, “Jun”,_
                                           “Jul”, “Aug”, “Sep”, “Oct”, “Nov”, “Dec”)

These constant arrays store text that I want to display on the CVFD. It’s not necessary to always access text this way, but it’s a handy method for translating a raw number into the appropriate text.

‘Display initialization
Set Display 2,0,0,32                ‘ Set display to CLCD/CVFD
Cls                                 ‘ Clear screen
Print &H1B, &H73                    ‘ Turn off cursor

The CB290 needs to know that a display is attached; the above code defines the type of display, clears the screen, and sends codes to disable the underline cursor. This startup sequence is all that is required to get the CVFD ready to display text.

‘ * * * * *
‘ Main Program Loop

Do

‘ Load current time into global time variables
Gosub UpdateTime

‘ Output time and date in human-readable format
If (RTC_Second = 0 Or Updated = 0) Then
    Gosub PrintTime
Else
    Gosub PrintSeconds
Endif

Delay 250

Loop

‘ * * * * *

This is the main program loop, which endlessly repeats and decides when to activate the other subroutines. Approximately every quarter second, it activates the UpdateTime routine to dump the current date and time into the RTC_xxx variables. Then it decides whether to update just the seconds on the display, or repaint the entire display. This keeps display flicker to a minimum and avoids processing the whole human-readble routine every 250 milliseconds.

UpdateTime:
‘ Load each value from the RTC
‘ Convert from BCD to binary encoding
‘ Place in appropriate global variable

RTC_Second     =     Bcd2bin(Time(0))       ‘ 00-59, BCD encoded
RTC_Minute     =     Bcd2bin(Time(1))       ‘ 00-59, BCD encoded
RTC_Hour       =     Bcd2bin(Time(2))       ‘ 00-23, BCD encoded
RTC_BCD_Date   =     Time(3)                ‘ 01-31, BCD encoded
RTC_Date       =     Bcd2bin(RTC_BCD_Date)  ‘ Need BCD form of Date for suffix calculation
RTC_Day        =     Bcd2bin(Time(4))       ‘ 00-06, BCD encoded, 0 = Sunday
RTC_Month      =     Bcd2bin(Time(5))       ‘ 01-12, BCD encoded, 1 = January
RTC_Year       =     Bcd2bin(Time(6))       ‘ 00-99, BCD encoded, assume 21st century
Return

The UpdateTime subroutine uses the CB290’s built-in Time() command to retrieve all the information from the RTC. Since the numbers are in BCD format, I use the built in Bcd2bin() command to easily convert into a byte format that is simpler to use in math operations.

PrintTime:
‘ Convert time to human readable format
‘ Output result to a CLCD or CVFD

‘ Read Day of Month, set DayEnd index to correct value
‘ 0 = th, 1 = st, 2 = nd, 3 = rd
‘ Use BCD equivalent (0-9 in lower nibble) to index DaySuffix
Dim DayEnd As Byte ‘ Array index to correct day-of-month suffix
    DayEnd = RTC_BCD_Date.LOWNIB

    ‘ Check for special cases (everything that needs to end in “th”)
    If ((RTC_Date > 10 And RTC_Date < 20) Or DayEnd > 3) Then DayEnd = 0

    ‘ Convert hours to 12-hour format, determine AM or PM
    Dim FriendlyHour As Byte ‘ Variable to hold 12-hour format
    Dim AM As Byte ‘ Variable to hold AM/PM status
    If (RTC_Hour >= 12) Then
        AM = 0
        FriendlyHour = RTC_Hour – 12
        If (FriendlyHour = 0) Then FriendlyHour = 12
    Else
        AM = 1
    Endif

    ‘ Print month, day, day suffix, and year to the display
    Locate 1,0 ‘ Place cursor one space into the first line
    Print Months(RTC_Month-1), ” “
    Print Dp(RTC_Date,2,1), DaySuffix(DayEnd)
    Print Chr(&H2C), ” 20″, Dp(RTC_Year,2,1)

    ‘ Print weekday, hour, minute, second, and AM/PM indicator
    Locate 0,1 ‘ Place cursor at beginning of second line
    Print Weekdays(RTC_Day)
    Print Chr(&H2C), ” “
    Print Dp(FriendlyHour,2,1), “:”, Dp(RTC_Minute,2,1), “:”, Dp(RTC_Second,2,1), ” “, AmPm(AM)
    Updated = 1 ‘ Set flag indicating we drew the whole display

Return

The main concept in the above routine is getting the date information numbers to match up with the desired array indexes for those string array constants defined earlier. For example, the Months array can be accessed by simply dumping the value of RTC_Month – 1 as the array index. This eliminates the need for bulky Select Case statements. Accessing the display is as simply as Print and then the characters to display. The Dp() function converts a number to a string and pads with zeroes if needed, perfect for writing the RTC time values directly to the CVFD. I’m also converting a 24-hour time format into a 12-hour format, and writing an AM or PM where necessary.

PrintSeconds:
‘ Draw just the seconds, to avoid having to redraw the whole display and introduce flickering

Locate 11,1
    Print Dp(RTC_Second,2,1)

Return

This routine allows only the seconds to be updated, if they are the only thing that needs to change. This will free the processor up for other tasks later on.

SyncTime:
‘Time synchronization routine
‘Receives data from computer through a serial port and sets the time on the RTC chip.

Dim k As Byte

If (Blen(0,0) > 6) Then             ‘ Check buffer for expected size of time packet
For k = 0 To 6                  ‘ Index through each Timeset() location
Timeset k,Bin2bcd(Get(0,1)) ‘ Set each parameter to the BCD equivalent
Next
Updated = 0                     ‘ Clear Updated flag so that the full display will be
‘ refreshed on the next cycle

Endif

Return

This final routine allows the CB290’s RTC to sync to a computer clock. A small program on the host computer outputs seven bytes containing the date and time values read from the computer’s clock. Then the CB290 dumps each byte into a register on the internal RTC. To prevent accidental incorrect time settings, this will eventually include a serial number mechanism before the time is accepted and written to the internal clock. This routine will eventually become part of a larger serial event handling system for configuring and controlling the CB290 home automation project.

That’s all I have for today, and if you download the code linked below and run it on a CB290 and CVFD you’ll have a somewhat fancy clock and calendar. Next time, I’ll show how to schedule events based on the internal clock, making this a useful device for scheduling outdoor lights, coffee makers, and other appliances.

3 Responses to Garrett’s DIY #2 – Home Automation Project – Part One: Real-Time Clock and Calendar

  1. Pingback: Garre’ts DIY - Home Automation Project - Part One: Real-Time Clock and Calendar | zedomax.com - blog about emerging technologies, diy, hacks, gadgets, and more!

  2. bimal says:

    we want a ckt. digram for digital display panel ckt. for our project i’ll u plz recommanded us.

  3. John says:

    lol… supercapacitor

Leave a Reply

Your email address will not be published.