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.
‘Global variables initialization
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.
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
‘ Load current time into global time variables
‘ Output time and date in human-readable format
If (RTC_Second = 0 Or Updated = 0) Then
‘ * * * * *
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.
‘ 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
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.
‘ Convert time to human readable format
‘ Output result to a CLCD or CVFD
‘ Read Day of Month, set DayEnd index to correct value
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.
‘ Draw just the seconds, to avoid having to redraw the whole display and introduce flickering
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.
‘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
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.