
[Sal] sent us his digital electric meter monitor, which immediately made us nostalgic for some of Forrest Mims’ books. Sal’s schematic and circuit description are similar to Forrest’s style, and we mean that as a compliment. Even in today’s world of CAD and EDS packages, sketching out a circuit by hand is sometimes both easier and faster. The schematic isn’t the only classic aspect of [Sal's] design. He’s collecting data using a parallel port on an unused PC: in this case, a Toshiba Libretto running Windows 95. Before cheap flash-based microcontrollers and dev boards were available, the PC parallel port was the go-to hardware hacking interface for many of us. Plenty of the software running those old hacks was written in basic, and [Sal's] meter is no exception. His software runs on Microsoft QBasic, which shipped with Windows 95.
The circuit takes advantage of the digital meter’s output: a 10mS pulse for every 1kWh of energy used. An IR photo detector from RadioShack detects the meter pulses, which are amplified by an LM324 Op Amp. An NPN transistor then shifts the output to send it to two 74LS73 JK flip flops. The first flip flop uses a transistor to drive an LED for visual output. The second JK flip flop sends the data to the PC. The flip flop has the effect of dividing the number of meter pulses by two, creating a much longer toggled signal that a PC can better detect.
Although using an AVR or PIC would consume less power, [Sal's] setup has already more than paid for its power usage. By monitoring and adapting his electrical usage, [Sal] is saving $20 a month on his electric bill. We’ve included [Sal's] circuit diagram and source code after the break (apologies to our readers on RSS).
First [Sal's] test program:
CLSSCREEN 1210 W = INP(&H379)IF W <= 127 THEN GOTO 10R! = TIMER20 W = INP(&H379)IF W > 127 THEN GOTO 2030 W = INP(&H379)IF W <= 127 THEN GOTO 30S! = TIMERT! = S! – R!IF T! = 0 THEN GOTO 10KW = 7.2 / T!PRINT KW;ON KEY(1) GOSUB 40KEY(1) ONGOTO 1040 ENDHere is the main application:
CLSREM C:\METER011.BAS1 SCREEN 12LOCATE 1, 1: INPUT "INPUT ELECTRICAL METER KWH ", QQLOCATE 1, 1: FOR X = 1 TO 40: PRINT " "; : NEXTDD1$ = MID$(DATE$, 4, 2) 'DAYSTH1$ = LEFT$(TIME$, 2) 'HOURSTM1$ = MID$(TIME$, 4, 2) 'MINUTESTS1$ = RIGHT$(TIME$, 2) 'SECONDS4 A = 0: B = 0: C = 0: D = 0: F = 0: G = 0: K = 0: L = 0: M = 0: N = 0O = 0: P = 0: Q = 0: R = 0: V = 32: LA = 0: MB = 0: NC = 0: OD = 0: NN = 0DD = 1: U = 1DIM A(120): DIM B(120): DIM C(25): DIM D(32)B = VAL(TM1$)C = VAL(TH1$)D = VAL(DD1$)GOSUB 2010GOSUB 5008 Q! = TIMER10 W = INP(&H379)IF W <= 127 THEN GOTO 10R! = TIMER20 W = INP(&H379)IF W > 127 THEN GOTO 20AA& = AA& + 1BB& = BB& + 130 W = INP(&H379)IF W <= 127 THEN GOTO 30S! = TIMERIF S! < Q! THEN S! = S! + 86400T! = S! - R!IF T! >= 0 AND T! <= .5 THEN GOTO 10K = (7.2 / T!)LOCATE 1, 5: PRINT USING "##.###"; K;LOCATE 1, 11: PRINT " KW"ON KEY(1) GOSUB 1000: KEY(1) ON100 A = A + 1: L = L + K: LA = L / AA(A) = KIF K >= 7 THEN A(A) = 7V = 32 + A * 8: Y = A(A) * 16: LINE (V, 135)-(V, 135 - Y), 10TM2$ = MID$(TIME$, 4, 2)IF TM2$ = TM1$ THEN 110 ELSE GOSUB 1005110 IF S! - Q! >= 60 THEN GOSUB 600IF S! - Q! >= 60 THEN 125GOTO 10125 A = 0: B = B + 1: L = 0: M = M + LA: MB = M / BB(B) = LAIF LA >= 5 THEN B(B) = 5V = 32 + B * 8: Y = B(B) * 16: LINE (V, 247)-(V, 247 - Y), 10TH2$ = LEFT$(TIME$, 2)IF TH2$ = TH1$ THEN 126 ELSE GOSUB 700IF TH2$ = TH1$ THEN 126 ELSE GOTO 150126 GOTO 8150 TH1$ = TH2$: B = 0: C = C + 1: M = 0: N = N + MB: NC = N / CC(C) = MBIF MB >= 3 THEN C(C) = 3V = 32 + C * 8: Y = C(C) * 16: LINE (V, 327)-(V, 327 - Y), 10151 IF C >= 24 THEN GOSUB 800IF C >= 24 THEN 175GOTO 8175 C = 0: D = D + 1: N = 0: O = O + NC: OD = O / DD(D) = NCIF NC >= 4 THEN D(D) = 4V = 32 + D * 8: Y = D(D) * 38.4: LINE (V, 423)-(V, 423 - Y), 10IF D >= DA THEN GOSUB 900IF D >= DA THEN 180GOTO 8180 D = 0: O = 0: E = E + 1: P = P + OD * 24: PE = P / EE = 0: P = 0GOTO 4500 REM ONE MINUTE KW PLOTLOCATE 2, 1FOR G = 7 TO 0 STEP -1: PRINT USING "##.#"; G; : PRINT CHR$(45): NEXTFOR GG = 2 TO 9LOCATE GG, 6: FOR T = 1 TO 60: PRINT CHR$(45); : NEXTNEXTLOCATE 10, 6: PRINT " KW/1 MINUTE"REM ONE HOUR KWH PLOTLOCATE 11, 1FOR G = 5 TO 0 STEP -1: PRINT USING "##.#"; G; : PRINT CHR$(45): NEXTFOR GG = 11 TO 16LOCATE GG, 6: FOR T = 1 TO 60: PRINT CHR$(45); : NEXTNEXTLOCATE 17, 6: PRINT " KW/1 HOUR"REM ONE DAY KWH PLOTLOCATE 18, 1FOR G = 3 TO 0 STEP -1: PRINT USING "##.#"; G; : PRINT CHR$(45): NEXTFOR GG = 18 TO 21LOCATE GG, 6: FOR T = 1 TO 24: PRINT CHR$(45); : NEXTNEXTLOCATE 22, 6: PRINT " KWH/1 DAY"REM ONE MONTH TOTAL KWHLOCATE 23, 1FOR G = 40 TO 0 STEP -10: PRINT USING "##.#"; G; : PRINT CHR$(45): NEXTFOR GG = 23 TO 27LOCATE GG, 6: FOR T = 1 TO DA: PRINT CHR$(45); : NEXTNEXTLOCATE 28, 6: PRINT " KWH/1 MONTH"REM DATE AND TIMELOCATE 1, 17: PRINT DATE$LOCATE 1, 30: PRINT TIME$LOCATE 1, 41: PRINT USING "#####.#"; QQ;PRINT " KWH"RETURN600 FOR HH = 2 TO 9: LOCATE HH, 6: FOR H = 1 TO 60: PRINT " "; : NEXT H: NEXT HHFOR GG = 2 TO 9LOCATE GG, 6: FOR T = 1 TO 60: PRINT CHR$(45); : NEXTNEXTRETURN700 FOR HH = 11 TO 16: LOCATE HH, 6: FOR H = 1 TO 60: PRINT " "; : NEXT H: NEXT HHFOR GG = 11 TO 16LOCATE GG, 6: FOR T = 1 TO 60: PRINT CHR$(45); : NEXTNEXTRETURN800 FOR HH = 18 TO 21: LOCATE HH, 6: FOR H = 1 TO 24: PRINT " "; : NEXT H: NEXT HHFOR GG = 18 TO 21LOCATE GG, 6: FOR T = 1 TO 24: PRINT CHR$(45); : NEXTNEXTRETURN900 FOR HH = 23 TO 28: LOCATE HH, 6: FOR H = 1 TO DA: PRINT " "; : NEXT H: NEXT HHFOR GG = 23 TO 27LOCATE GG, 6: FOR T = 1 TO 31: PRINT CHR$(45); : NEXTNEXTRETURN1000 LOCATE 1, 1INPUT "QUIT? YES OR NO ", ANS$IF ANS$ = "YES" THEN ENDRETURNREM 1005 LOCATE 28, 371005 LOCATE 28, 38DA$ = (LEFT$(DATE$, 5))TI$ = (LEFT$(TIME$, 5))PP = ((7.2 * BB&) / 3600)TT = QQ + PPPRINT DA$; " "; TI$; " ";PRINT USING "###.#"; PP;PRINT " KWH"LOCATE 1, 54PRINT USING "#####.#"; TT;PRINT " KWH"REM IF PP >= 0 AND PP < 303 THEN XX = PP * .13: GOTO 1006REM IF PP >= 303 AND PP < 394 THEN XX = 39.52 + (PP - 304) * .16: GOTO 1006REM IF PP >= 394 AND PP < 606 THEN XX = 54.08 + (PP - 395) * .26: GOTO 1006REM IF PP >= 606 AND PP < 648 THEN XX = 109.46 + (PP - 608) * .29: GOTO 1006REM 1006 PRINT " "; "$";REM PRINT USING "###.##"; XXRETURN1007 LOCATE U, 67VV = ((7.2 * AA&) / 3600)PRINT DD2$; " ";PRINT USING "###.##"; VVAA& = 0U = U + 1IF U = 29 THEN U = 1PP = (7.2 * BB&) / 3600TT = QQ + PPRETURN2010 C$ = LEFT$(DATE$, 2)ON VAL(C$) GOTO 2101, 2102, 2103, 2104, 2105, 2106, 2107, 2108, 2109, 2110, 2111, 21122101 DA = 31: GOTO 30002102 E$ = MID$(DATE$, 9, 2)IF VAL(E$) = 16 THEN DA = 29 ELSE DA = 28IF VAL(E$) = 20 THEN DA = 29 ELSE DA = 28IF VAL(E$) = 24 THEN DA = 29 ELSE DA = 28IF VAL(E$) = 28 THEN DA = 29 ELSE DA = 28GOTO 30002103 DA = 31: GOTO 30002104 DA = 30: GOTO 30002105 DA = 31: GOTO 30002106 DA = 30: GOTO 30002107 DA = 31: GOTO 30002108 DA = 31: GOTO 30002109 DA = 30: GOTO 30002110 DA = 31: GOTO 30002111 DA = 30: GOTO 30002112 DA = 31: GOTO 30003000 RETURN3010 LOCATE 28, 24T1$ = LEFT$(TIME$, 5)PRINT T1$RETURN




Filed under: home hacks
