' MeasureVanFridge.bs2 ' Measures van Volts and Fridge temperature with adapter ' John Saunders 2/13/2008 ' {$STAMP BS2} ' {$PBASIC 2.5} 'Stamp Ports PwrGood PIN 0 'Input:1 if line is up RS232In PIN 1 'Input:RS-232 Serial in DTR PIN 2 'Input:Data Terminal Ready RS232Out PIN 3 'Output:RS-232 Serial out MOSFET PIN 4 'Output:1 energises the MOSFET output on DC-25 pins 17&18 IOCLK PIN 5 'Output:74HC165 and 74HCT164 clock SwData PIN 6 'Input:Switch and external discrete inputs IOData PIN 7 'Output:Display character, mode and command,165 Load DispLD PIN 8 'Output:Display load SwDn PIN 9 'Input:0 = switch down, also DC-25P pin 21 SwUp PIN 10 'Input:0 = switch up, also DC-25P pin 22 AD1CLK PIN 11 'Output:10 clock pulses to input analog 1 value AD1In PIN 12 'Input:analog 1 value, MSB first AD2CLK PIN 13 'Output:10 clock pulses to input analog 2 value AD2In PIN 14 'Input:analog 2 value, MSB first TwoHz PIN 15 'Input:2-Hz square wave timing input 'time processing parameters sec VAR Byte 'current seconds minute VAR Byte 'current minutes hour VAR Byte 'current hour day VAR Byte 'current day, starting at 1 month VAR Nib 'current month, 1 to 12 year VAR Nib 'current year, add to 0, assume 20XX phase VAR Bit '2 Hz waveform from CD4060,1=high halfsec VAR Bit 'To run some processes once per second 'Initialization DispInitData DATA $30,$30,$30,$38,$0C,$01,$06,$14,$80 DispInitLen CON 8 DayInMonth DATA 31,28,31,30,31,30,31,31,30,31,30,31 DayLoc DATA 13 'using EEPROM to reduce need to re-enter MonthLoc DATA 2 'using EEPROM to reduce need to re-enter YearLoc DATA 08 'using EEPROM to reduce need to re-enter 'Display parameters DECdata VAR Word 'actual character or value to be displayed div VAR Nib 'dividend used in writing numbers rem VAR Word 'remainder used in writing multiple-digit numbers DispMode VAR Nib 'Controls the way a value is to be displayed, bits 0, 1 = no of digits - 1 row0addr CON $80 'instruction for top row row1addr CON $C0 'second row row2addr CON $94 'third row row3addr CON $D4 'bottom row Blink VAR Bit 'Control variables and External Digital Inputs DIGdata VAR Byte 'Signals connected to the 74HC165 shift register ModeSW VAR Byte Charging VAR DIGdata.BIT7 'Signal connected to DC-29P, pin 20 InputB VAR DIGdata.BIT6 'Signal connected to DC-29P, pin 7 InputC VAR DIGdata.BIT5 'Signal connected to DC-29P, pin 6 Range VAR DIGdata.BIT4 'Signal connected to DC-29P, pin 19 and the range switch EnterSw VAR DIGdata.BIT3 'Signal connected to DC-29P, pin 16 and the push-button OldDigitals VAR Byte 'Previous value of DIGData OldMode VAR OldDigitals.LOWNIB OldEnter VAR OldDigitals.BIT3 OldUp VAR Bit 'Previous value of SwUp OldDn VAR Bit 'Previous value of SwDn SettingIndex VAR Nib 'Cursor position when setting values Iter VAR Nib 'for loop variable Limit VAR Byte 'For loop end point 'Analog variables and constants Volts VAR Word Temperature VAR Word Reading VAR Word Offset VAR Byte OffsetLoc DATA 125 '10-deg adjustment for temperature for zero count OffsetBase CON 1000 '40 deg F offset, pot set to .65V 'monitoring FileNoLoc DATA 100 'Set to one more than the last one start: DIRS = %0010100110111000 LOW DispLD 'display enable pin phase=TwoHz 'make sure to find the first transition GOSUB InitCmds GOSUB InitDisp GOSUB ReadDate softreset: SettingIndex = 0 GOSUB GetInputData OldDigitals = DIGdata OldDn = SwDn OldUp = SwUp 'find the 2 Hz transitions transition: DO WHILE TwoHz=phase 'Clock signal is not changing GOSUB GetInputData 'get the inputs 4 times a second LOOP 'transition processing phase=TwoHz 'reset the phase IF ModeSW = 5 THEN GOSUB SetTimeDate GOSUB DispTime OldDigitals = DIGData GOTO transition ENDIF IF phase=0 THEN halfsec = ~ halfsec IF halfsec = 1 THEN 'Once per second GOSUB DispTime ELSE GOSUB GetAnalog ENDIF ELSE IF halfsec = 1 THEN 'Once per second IF ModeSW = 6 THEN IF EnterSw = 0 THEN start ENDIF IF ModeSW = 3 THEN READ OffsetLoc,DECData rem = 255 GOSUB AdjustValue WRITE OffsetLoc,DECData ENDIF ELSE GOSUB TimeUpdate ENDIF ENDIF GOSUB DispSettings OldDigitals = DIGData GOTO transition 'continue monitoring the 2 Hz clock 'subroutines: 'subroutines for LCD display: InitCmds: IOCLK = 0 OldDigitals = 0 sec = 7 RETURN InitDisp: FOR Iter = 0 TO DispInitLen READ DispInitData + Iter,DECData GOSUB DispCmd NEXT RETURN ReadDate: READ YearLoc,Year READ MonthLoc,Month READ DayLoc,Day RETURN SetTimeDate: IF EnterSw = 0 AND OldEnter = 1 THEN SettingIndex = SettingIndex + 1 IF SettingIndex > 4 THEN SettingIndex = 0 ENDIF Sec = 0 ENDIF SELECT SettingIndex CASE 0 DECData = Hour rem = 23 GOSUB AdjustValue Hour = DECData CASE 1 DECData = Minute rem = 59 GOSUB AdjustValue Minute = DECData CASE 2 DECData = Month - 1 rem = 11 'computations start at 0, corrected in DispTime GOSUB AdjustValue Month = DECData + 1 WRITE MonthLoc,Month CASE 3 READ (DayInMonth + Month),rem 'to index Day in month DECData = Day - 1 GOSUB AdjustValue Day = DECData + 1 WRITE DayLoc,Day CASE 4 DECData = Year rem = 99 GOSUB AdjustValue WRITE YearLoc,DECData Year = DecData ENDSELECT OldDn = SwDn OldUp = SwUp RETURN AdjustValue: 'value to be updated is in DECData, Div is in Div IF SwDn = 0 AND OldDn = 1 THEN IF DECData = 0 THEN DECData = Rem ELSE DECData = DECData - 1 ENDIF ENDIF IF SwUp = 0 AND OldUp = 1 THEN IF DECData >= Rem THEN DECData = 0 ELSE DECData = DECData + 1 ENDIF ENDIF RETURN DispCmd: 'puts a command (IoData) in OutputData into the display SHIFTOUT IOData,IOCLK,1,[DECdata\8] 'clocks the instruction into the shift register LOW IOData 'instruction function is low, IOData does double duty PULSOUT DispLD,10 'clocks the instruction and the function into the display PAUSE 1 RETURN DispChar: 'puts one character onto the display SHIFTOUT IOData,IOCLK,1,[DECdata\8] 'clocks the character into the shift register HIGH IOData 'data function is high PULSOUT DispLD,1 'clocks the instruction and the character into the display RETURN GetInputData: 'inputs are scanned at 4 hz HIGH IOData 'load the inputs into the 74165 shift register PULSOUT IOData,2 HIGH IOData SHIFTIN SWData,IOCLK,1,[DIGdata\8] 'clock input states out of the shift register into the stamp ModeSW = DIGdata & 7 RETURN TimeUpdate: sec = sec +1 IF sec > 59 THEN sec = 0 minute = minute + 1 IF minute > 59 THEN minute = 0 hour = hour + 1 IF hour > 23 THEN hour = 0 READ (DayInMonth + Month - 1),Limit 'to index Day in month Day = Day + 1 WRITE DayLoc,Day READ FileNoLoc,rem rem = rem + 1 WRITE FileNoLoc,rem IF Day > Limit THEN Day = 1 WRITE DayLoc,1 Month = Month + 1 WRITE MonthLoc,Month IF Month > 12 THEN Month = 1 WRITE MonthLoc,1 Year = Year + 1 WRITE YearLoc,Year ENDIF ENDIF ENDIF ENDIF ENDIF RETURN DispTime: 'format is hh:mm:ss mm/dd/20yy DECdata = row0addr GOSUB DispCmd DECData = Hour DispMode = 1 'Two digits IF SettingIndex = 0 THEN Blink = 1 ENDIF GOSUB DispDec DECData = ":" GOSUB Dispchar Iter = 2 DECData = Minute IF SettingIndex = 1 THEN Blink = 1 ENDIF GOSUB DispDec DECData = ":" GOSUB Dispchar DECData = Sec GOSUB DispDec DECData = row0addr + 9 GOSUB DispCmd DECData = Month IF SettingIndex = 2 THEN Blink = 1 ENDIF GOSUB DispDec DECData = "/" GOSUB Dispchar DECData = Day IF SettingIndex = 3 THEN Blink = 1 ENDIF GOSUB DispDec DECData = "/" GOSUB Dispchar DECData = "2" GOSUB Dispchar DECData = "0" GOSUB Dispchar DECData = Year IF SettingIndex = 4 THEN Blink = 1 ENDIF GOSUB DispDec RETURN DispDec: IF DispMode = 0 THEN OneDigit IF DispMode = 1 THEN TwoDigit IF DispMode = 2 OR DispMode = "A" THEN ThreeDigit div = DECData/1000 rem = DECData//1000 DECData = div + "0" GOSUB DispChar IF DispMode = $E THEN DECData = "." GOSUB DispChar ENDIF DECData = rem ThreeDigit: div = DECData/100 rem = DECData//100 DECData = div + "0" GOSUB DispChar IF Dispmode = $F THEN DECData = "." GOSUB DispChar ENDIF DecData = rem TwoDigit: IF Phase = 1 AND Blink = 1 THEN DECData = " " GOSUB DispChar DECData = " " GOSUB DispChar ELSE div = DECData/10 rem = DECData//10 DECData = div + "0" GOSUB DispChar IF Dispmode = $B OR DispMode = $A THEN DECData = "." GOSUB DispChar ENDIF DECData = rem OneDigit: DECdata = DECdata + "0" GOSUB DispChar ENDIF Blink = 0 RETURN GetAnalog: Reading = 0 SHIFTIN ad1in,ad1clk,MSBPRE,[Reading\10] volts = volts + Reading '1 count = 4mv, * 2 is 2 mv gain is 0.2 for 20 V = 2000 Reading = 0 SHIFTIN ad2in,ad2clk,MSBPRE,[Reading\10] 'DecData = row2addr 'GOSUB DispCmd 'DecData = Reading 'DispMode = 2 '3 digits 'GOSUB DispDec READ Offsetloc,Offset Temperature = Temperature + Reading + Offset + OffsetBase IF Sec & $01 = 0 THEN DecData = row1addr GOSUB DispCmd DecData = volts DispMode = $F '4 digits with 2 after the DP GOSUB DispDec DecData = " " GOSUB DispChar DecData = "V" GOSUB DispChar DecData = " " GOSUB DispChar Temperature = Temperature / 5 DispMode = $A DECData = Temperature GOSUB DispDEC DecData = " " GOSUB DispChar DecData = $DF 'Degree symbol GOSUB DispChar DecData = "F" GOSUB DispChar SELECT sec CASE 0 SEROUT RS232Out,84,2,["S 1 5",CR] '50 ms timeout for missing bytes CASE 2 READ FileNoloc,rem SEROUT RS232Out,84,2,["O 1 A /T",DEC3 rem,".CSV",CR] CASE 4 SEROUT RS232Out,84,2,["W 1 29",CR, DEC2 month,"/",DEC2 day,"/20",DEC2 year,",",DEC2 hour,":",DEC2 minute,",",DEC4 Temperature,",",DEC4 Volts,CR,LF] CASE 6 SEROUT RS232Out,84,2,["C 1",CR] ENDSELECT volts = 0 Temperature = 0 ENDIF RETURN DispSettings: DecData = row3addr GOSUB DispCmd READ OffsetLoc,Offset DECData = Offset DispMode = 2 IF ModeSW = 3 THEN Blink = 1 ENDIF GOSUB DispDec RETURN