Home Data Monitoring System


Introduction.

The following routine in QBASIC was written by Jim Dantin. Jim purchased the K1820 kit and he was kind enough to do a great deal of work and he provided this to help other users and I have to thank him.

Please note that aside from fooling with the Basic Stamp, I don't know BASIC. I teach young electrical engineering students and I have a moral responsibility to equip them for today's job market. Thus, I teach C++, 68HC11 and PIC assembly, along with sensors, controlling external devices and data acquisition.

This is not to suggest that BASIC is not important. When I see the kind of work that Jim has done, or John Bourne at Vanderbilt University who can create virtual HP DVMs and scopes that look and behave like the real thing, I am amazed.

However, at this point in my life, I prefer to concentrate on the peripheral hardware. We should all strive for "peaks of excellence" and I will frankly admit that Basic is not currently on my list.

Please appreciate the spirit of this page. The intent is to help other people at all levels to do something they might not otherwise be able to do. Indeed, I charge money for manuals and kits, but they are priced to be affordable, and the bottom line is that my loss for the year currently is some $3500 and this doesn't take into account the many hours I spend developing material or the money that I pay to my students. Many of my students work very hard for little or no money. There is a satisfaction in developing material to help others to do things.

Thus, any routines that you might develop that you would be willing to share with others would be very much appreciated.

Please observe Jim's copyright. His routine is shared for hobbyists. But, if you plan to use his work in a commercial venture, please contact him.


Please note that the character < causes a problem in html. If you save this file, modify all occurances of &lt to <.

' Home Data Monitoring System
' copyright, Jim Dantin jdantin@kih.net, Nov 16, '97
'
' This system is designed to monitor and log temperature from up to
' eight sensors. The system uses the thermometer kit from Peter Anderson
' (pha@access.digex.net). Data logging is done every minute and summary
' statistics are logged daily.
'
' This program is written for use on a low-end PC that can be dedicated to
' the monitoring function.

SCREEN 0, 0, 1, 1
ON ERROR GOTO allstop

'Get labels for the data points
'Customize these labels to match the location of the sensors
FOR i = 0 TO 7
        READ strDescription$(i)
NEXT i
DATA Inside,Outside,HVAC inlet,HVAC outlet,Cold water pipe
DATA Hot water pipe,Water heater flue,

'Initialize the variables and set up the data file
GOSUB init
GOSUB createfile

'Set up the Function Keys
        ON KEY(1) GOSUB fKey1   'toggles the help line
        ON KEY(2) GOSUB fKey2   'shells out to DOS
        ON KEY(3) GOSUB fKey3
        ON KEY(4) GOSUB fKey4
        ON KEY(5) GOSUB fKey5
        ON KEY(6) GOSUB fKey6
        ON KEY(7) GOSUB fKey7
        ON KEY(8) GOSUB fKey8   'ends the program

'Set up the screen display
CLS
LOCATE 1, 10: PRINT "Home Data Monitoring System"
LOCATE 3, 1: PRINT " Temp.   Source"
LOCATE 4, 1: PRINT "------   ---------------"
FOR i = 0 TO 8
        LOCATE 2 * i + 5, 10
        PRINT strDescription$(i)
NEXT i

LOCATE 3, 40:  PRINT "      Current Status:"
LOCATE 4, 40:  PRINT "---------------------------"
LOCATE 5, 40:  PRINT "         Outside Max:"
LOCATE 6, 40:  PRINT "         Outside Min:"
LOCATE 8, 40:  PRINT " Heating Degree Days:"
LOCATE 9, 40:  PRINT "      Heating System:"
LOCATE 10, 40: PRINT "     Heating Minutes:"
LOCATE 12, 40: PRINT " Cooling Degree Days:"
LOCATE 13, 40: PRINT "      Cooling System:"
LOCATE 14, 40: PRINT "     Cooling Minutes:"
LOCATE 16, 40: PRINT "        Water Heater:"
LOCATE 17, 40: PRINT "Water Heater Minutes:"
LOCATE 19, 40: PRINT "           Hot Water:"
LOCATE 20, 40: PRINT "   Hot Water Minutes:"



'Keep a running total of the data scans just so we know it's working
valCount = 0
           
'Open the serial port
OPEN "COM1: 2400,N,8,1,CD0,CS0,DS0,OP0,RS,TB2048,RB2048" FOR RANDOM AS #1


'This causes the thermometer circuit to gather and transmit data
tx:
        LOCATE 3, 62: PRINT "Scanning . . ."
        KEY(0) STOP             'suspends key event trapping
        WRITE #1, "A"

'Wait for and receive the data
rx:
        LINE INPUT #1, a$
        raw$ = a$
        GOTO parse
     
'Parse out the data
parse:
        FOR i = 0 TO 7
        valTemp(i) = VAL(LEFT$(a$, INSTR(a$, " ") - 1))
        a$ = MID$(a$, INSTR(a$, " ") + 1, LEN(a$))
        NEXT i

'Convert to Fahrenheit, but leave the "-99.99" data alone
        FOR i = 0 TO 7
        IF valTemp(i) <> -99.99 THEN valTemp(i) = 32 + valTemp(i) * 9 /5
        NEXT i
                      
display:
        FOR i = 0 TO 7
        LOCATE 2 * i + 5, 1
        IF valTemp(i) <> -99.99 THEN PRINT USING "###.##"; valTemp(i)
        NEXT i
      
update:
'Now update the accumulators
        IF valTemp(1) > 70 THEN valCDD = valCDD + (valTemp(1) - 70) / 1440
        IF valTemp(1) < 70 THEN valHDD = valHDD + (70 - valTemp(1))/1440
        IF valTemp(1) > valTempMax THEN valTempMax = valTemp(1)
        IF valTemp(1) < valTempMin THEN valTempMin = valTemp(1)

checkheating:
        IF valTemp(3) - valTemp(2) < 25 THEN StatusHeater$ = "Off": GOTO
checkcooling
        valHeatMinutes = valHeatMinutes + 1
        StatusHeater$ = " On"

checkcooling:
        IF valTemp(2) - valTemp(3) < 25 THEN StatusAC$ = "Off": GOTO
checkWater
        valCoolMinutes = valCoolMinutes + 1
        StatusAC$ = " On"

checkWater:
        IF valTemp(5) - valTemp(4) < 50 THEN StatusHotWater$ = "Off":
GOTO checkwaterheater
        valHotWaterMinutes = valHotWaterMinutes + 1
        StatusHotWater$ = " On"

checkwaterheater:
        IF valTemp(6) < 100 THEN StatusWaterHeater$ = "Off": GOTO logit
        valWaterHeaterMinutes = valWaterHeaterMinutes + 1
        StatusWaterHeater$ = " On"

logit:
'Log the raw data to the disk file
        LOCATE 3, 62: PRINT "Logging . . .  "
        WRITE #2, DATE$, LEFT$(TIME$, 5), valTemp(0), valTemp(1),
valTemp(2), valTemp(3), valTemp(4), valTemp(5), valTemp(6), valTemp(7)

showit:
'display the data 
        LOCATE 1, 62: PRINT DATE$; " "; TIME$
        valCount = valCount + 1                 'how many scans since we
started
        LOCATE 2, 70: PRINT USING "###,###,###"; valCount
        LOCATE 5, 62: PRINT USING "###.##"; valTempMax
        LOCATE 6, 62: PRINT USING "###.##"; valTempMin
        LOCATE 8, 62: PRINT USING "###.##"; valHDD
        LOCATE 9, 65: PRINT StatusHeater$
        LOCATE 10, 62: PRINT USING "###.##"; valHeatMinutes
        LOCATE 12, 62: PRINT USING "###.##"; valCDD
        LOCATE 13, 65: PRINT StatusAC$
        LOCATE 14, 62: PRINT USING "###.##"; valCoolMinutes
        LOCATE 16, 65: PRINT StatusWaterHeater$
        LOCATE 17, 62: PRINT USING "###.##"; valWaterHeaterMinutes
        LOCATE 19, 65: PRINT StatusHotWater$
        LOCATE 20, 62: PRINT USING "###.##"; valHotWaterMinutes



'Log summary data at the end of the day
        IF LEFT$(TIME$, 5) <> "23:59" THEN GOTO skipsummary
        OPEN "HDS_smry.DAT" FOR APPEND AS #3
        WRITE #3, DATE$, valTempMax, valTempMin, valHDD, valCDD,
valHeatMinutes, valCoolMinutes, valHotWaterMinutes, valWaterHeaterMinutes
        CLOSE #3
        GOSUB init      'reinitialize the counters for the start of a new
day

'

skipsummary:

'Wait for the next minute and give the user a chance for options
'Enable keystroke trapping
        KEY(0) ON

waitawhile:
        valMinute = VAL(MID$(TIME$, 4, 2))
        LOCATE 3, 62: PRINT "Waiting . . .  ";
waitsomemore:
        IF valMinute <> VAL(MID$(TIME$, 4, 2)) THEN GOTO newmonth
        LOCATE 1, 62: PRINT DATE$; " "; TIME$    'update the clock to show
we're working
        GOTO waitsomemore

newmonth:
'Is this the start of a new month?
        KEY(0) STOP
        IF (MID$(DATE$, 3, 2) <> "01") AND (LEFT$(TIME$, 5) <>
"00:00") THEN GOTO samemonth
        CLOSE #2
        GOSUB createfile

samemonth:
'Not a new month, so back for more data 
        GOTO tx


init:
'Initialize the accumulators
        valHDD = 0              'heating degree-days accumulator
        valCDD = 0              'cooling degree-days accumulator
        valHeatMinutes = 0      'time that heating system was on
        valCoolMinutes = 0      'time that cooling system was on
        valHotWaterMinutes = 0  'time that hot water was flowing
        valWaterHeaterMinutes = 0'time that hot water heater was on
        valTempMax = -9999      'daily maximum temperature
        valTempMin = 9999       'daily minimum temperature
        flgHelp = -1
        RETURN

createfile:
'Build a file name from the month and year (not Y2K compliant but who
cares!)
'This file will contain a data record for each minute of the month
'(44,640 records for a 31-day month)
        fileraw$ = "HDS_" + MID$(DATE$, 9, 2) + MID$(DATE$, 1, 2) + ".dat"
        OPEN fileraw$ FOR APPEND AS #2
        RETURN

'Function key routines
fKey1:
'Display the function key options - toggle on and off
        
        IF flgHelp THEN LOCATE 24, 1: PRINT "<F1=Toggle Help>
<F2=Shell to DOS> <F8=END>";
        IF NOT flgHelp THEN LOCATE 24, 1: PRINT SPACE$(80);
        flgHelp = NOT (flgHelp)
        RETURN

fKey2:
        SCREEN 0, 0, 2, 2
        SHELL
        SCREEN 0, 0, 1, 1
        RETURN
fKey3:
        RETURN
fKey4:
        RETURN
fKey5:
        RETURN
fKey6:
        RETURN
fKey7:
        RETURN
fKey8:
allstop:
        CLOSE 1
        CLOSE 2
        CLOSE 3

END