' MeasureAll.bs2 ' Uses all of the 3 accessories ' John Saunders 3/28/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 InputA VAR DIGdata.BIT7 'Signal connected to DC-29P, pin 20 InputB VAR DIGdata.BIT6 'Signal connected to DC-29P, pin 7, shorted on Temperature InputC VAR DIGdata.BIT5 'Signal connected to DC-29P, pin 6, shorted on AC Amps VRange VAR DIGdata.BIT4 'Signal connected to DC-29P, pin 19 and the Voltage 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 Accessory VAR Nib 'Shunt = $60, AC Amps = $40, Temperature = $20 ShuntID CON $60 ACAmpsID CON $40 TempID CON $20 AccMask CON $60 Volts VAR Word VoltsValid VAR Bit Bipolar VAR Word Offset VAR Byte OffsetLoc DATA 43 OffsetBase CON 2207 'For temperature MvZeroBase CON 462 'For both amps ARange VAR Byte 'For AC Amps 'Allowable values: 1(1 AMP) 'Allowable values: 4(2 AMP) 'Allowable values: 7(5 AMP) 'Allowable values: 10(10 AMP) 'Allowable values: 13(20 AMP) 'Allowable values: 16(50 AMP) 'For DC Amps (Shunt) 'Allowable values: 1(4 OHM,+/- 50 MA 'Allowable values: 2(2 OHM,+/- 100 MA 'Allowable values: 3(1.33 OHM,+/- 150 MA 'Allowable values: 4(1 OHM,+/- 200 MA 'Allowable values: 5(0.8 OHM,+/- 240 MA 'Allowable values: 6(0.67 OHM,+/- 300 MA 'Allowable values: 10(0.4 OHM,+/- 500 MA 'Allowable values: 12(0.33 OHM,+/- 600 MA 'Allowable values: 20(0.2 OHM,+/- 1000 MA ARangeLoc DATA 1,1,2,$F,2,4,$F,5,1,$C,10,2,$B,20,4,$B,50,1,$A '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 GetVolts ENDIF ELSE IF halfsec = 1 THEN 'Once per second GOSUB GetBiPolar 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 Accessory = DIGdata & AccMask 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 OR DispMode = $D THEN TwoDigit IF DispMode = 2 OR DispMode = $A OR DispMode = $C THEN ThreeDigit div = DECData/1000 'DispMode Format rem = DECData//1000 '0 # DECData = div + "0" '1 ## GOSUB DispChar '2 ### IF DispMode = $E THEN '$A ##.# DECData = "." '$B ###.# GOSUB DispChar '$C #.## ENDIF '$D #.# DECData = rem '$E #.### ThreeDigit: '$F ##.## div = DECData/100 rem = DECData//100 DECData = div + "0" GOSUB DispChar IF Dispmode = $F OR DispMode = $C 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 OR DispMode = $D THEN DECData = "." GOSUB DispChar ENDIF DECData = rem OneDigit: DECdata = DECdata + "0" GOSUB DispChar ENDIF Blink = 0 RETURN DispSettings: DecData = row3addr GOSUB DispCmd READ ARangeLoc,ARange READ (ARangeLoc + ARange),DecData DispMode = 1 IF ModeSW = 4 THEN Blink = 1 ENDIF GOSUB DispDec DECData = " " GOSUB DispChar READ OffsetLoc,DECData DispMode = 1 IF ModeSW = 3 THEN Blink = 1 ENDIF GOSUB DispDec FOR iter = 0 TO 7 LOOKUP iter,[-16,Vrange,-16,InputA,-16,InputB,-16,InputC],Limit Decdata = "0" + Limit GOSUB DispChar NEXT RETURN Record: SELECT sec CASE 1 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 /M",DEC3 rem,".CSV",CR] CASE 3 SEROUT RS232Out,84,2,["W 1 16",CR, DEC2 month,"/",DEC2 day,"/20",DEC2 year,",",DEC2 hour,":",DEC2 minute] CASE 4 'Volts will be valid SEROUT RS232Out,84,2,["W 1 10",",",CR,DEC4 Volts,",",DEC4 BiPolar] CASE 5 SEROUT RS232Out,84,2,["W 1 16",CR, ",",DEC2 Offset,",",DEC VRange,",",DEC2 ARange,",",DEC InputA,",",DEC InputB,",",DEC InputC,CR,LF] CASE 6 SEROUT RS232Out,84,2,["C 1",CR] ENDSELECT RETURN GetVolts: IF VoltsValid = 1 THEN Volts = 0 VoltsValid = 0 ENDIF rem = 0 SHIFTIN ad1in,ad1clk,MSBPRE,[rem\10] Volts = Volts + rem IF Sec & (3-2*Vrange) = 0 THEN DecData = row2addr GOSUB DispCmd DispMode = $E + VRange '4 digits with 2 after the DP DecData = Volts GOSUB DispDec DecData = " " GOSUB DispChar DecData = "V" GOSUB DispChar VoltsValid = 1 ENDIF RETURN GetBipolar: DecData = row1addr + 8 GOSUB DispCmd Rem = 0 SHIFTIN ad2in,ad2clk,MSBPRE,[rem\10] READ Offsetloc,Offset IF Accessory = TempID THEN Bipolar = (2 * rem) + Offset + OffsetBase Bipolar = Bipolar / 5 ELSE IF rem > (MvZeroBase + Offset) THEN rem = rem - MvZeroBase - Offset DecData = "-" ELSE rem = MvZeroBase + Offset - rem DecData = " " ENDIF GOSUB DispChar ENDIF DecData = " " GOSUB DispChar DECData = Bipolar SELECT Accessory CASE TempID DispMode = $A GOSUB DispDEC DecData = $DF 'Degree symbol GOSUB DispChar DecData = "F" GOSUB DispChar CASE ACAmpsID READ (ARangeLoc + ARange + 2),DispMode GOSUB DispDEC FOR iter = 0 TO 2 LOOKUP iter,[" ","A"," "],DECData GOSUB DispChar NEXT CASE ShuntID DispMode = $A READ ARangeLoc,ARange DECData = rem * ARange Bipolar = DECdata GOSUB DispDEC FOR iter = 0 TO 3 LOOKUP iter,[" ","M","A"," "],DECData GOSUB DispChar NEXT ENDSELECT RETURN