' Loggersx3.bs2 ' Records Environmental data on a Secure Digital Module ' Used with a Breakout Box and outside Humidity/Temperature/Ambient light box ' Slot 3 - measure,display and record auxiliary mearurements ' John Saunders 12/13/2006 ' {$STAMP BS2sx} ' {$PBASIC 2.5} 'Microcontroller IO 'The IO subsystem consists of two 8-bit input shift registers, 74HCT165, 'and an 8-bit output shift register 74HC595 for data, MSB first, and 'three decoders: two latched 74295 and a non-latched 74LS138 'IO pin assignments IOCLK PIN 0 'output - clocks all three shift registers and the DS1620 (inverted) IOData PIN 1 'output - data in for both 74295 MainIOGate PIN 2 'output - negative-going gate to enable 74HC595 #1 for display and shift register control AuxIOGate PIN 3 'output - negative-going gate to enable 74HC595 #2 for Ext Dig 1-4 ADC, Relay, and MOSFET IOIn PIN 4 'input - Serial input from both 74HCT165 EOC PIN 5 'input - 0 during ADC conversion, 1 at EOC RTC PIN 6 'input -1 Hz clock pin:almost square at 1 Hz DSDQ PIN 7 'input/output - DS1620 DQ Data 'Command decoder pins ' OUTC Is defined in stamp syntax to be pins 8-11. Set to 0-7 to select both 74295. ' Set to 8-15 for the 74LS138 address (chime). 'Chime decoder gate ChimeGate PIN 11 'output - positive-going pulse to gate of 74LS138 triggers the selected chime ' (some pulsed, some persist) 'RS232 pin assignments SDCmd PIN 12 'Secure digtal card interface command TX PIN 13 'RS-232 output, use driven and non-inverted RX PIN 14 'input, use driven and inverted DTR PIN 15 'input from PC (not used) 'Command Addresses for OUTC 'MainIO addresses ADCLoadaddr CON 0 'Latches input selector after setting 74HC595 output,pulse IOData to 1 ADCStartaddr CON 1 'Starts conversion after latching input selector, pulse IOData to 1 IOOUTaddr CON 2 'Use SHIFTOUT ON IOData TO Output Data IORCKaddr CON 3 'Latches 74HC595 output latches after SHIFTOUT, pulse IOData to 1 DispEnaddr CON 4 'Latches 74HC595 output into display, pulse IOData to 1 DispRSaddr CON 5 'Set IOData to 1 for data, 0 for command before DispEn IOINaddr CON 6 'Loads both 74HCT165, pulse IOData to 0 DSRST CON 7 'Positive to use the DS1620 digital temperature sensor 'Aux IO addresses MOSFET CON 1 'Set IOData to 0 to close the MOSFET RELAY CON 2 'Set IOData to 1 to close the Relay Audio CON 3 'Use IOData with FREQOUT to make a tone ExtDigOut CON 4 'External Digital Output 1 (D15S Pin 14) DSR CON 5 'Output for RS-232 DSR, set low 'Display constants row0addr CON $80 'location of top row row1addr CON $C0 'location of row 2 row2addr CON $94 'location of row 3 row3addr CON $D4 'location of bottom row 'Serial baud rate codes RXCode CON 240 + $4000 TXCode CON 240 'Chime addresses, used with OUTC Ringing CON 4 Autodial CON 6 MedTone CON 5 HighBeep CON 7 LowBeep CON 3 LowTone CON 2 MusicBox CON 1 BusyTone CON 0 'Data record format, analogs are hard - wired 0 - 7: '0 = +/- 15 V on terminal strip(+/-0,1 = +15 V on Breakout Box(15V),2 = Back Light(BAK) '3 = Patio Light(PAT),4 = humidity(HUM),5 = +/- 0.5V differential on terminal strip(0.5) '6 = Line voltage(LIN),7 = ext temperature(ETMP) 'Other channels: ExtDigitals(DIG),flags:Humidity Flag(HF),Light Flag(LF),Gate Flag(GF) 'Digital 3 Flag(DF),Minute Flag(TF),DS1620 temp(ITMP) ChOrder DATA 1,6,0,5 'The order of the analog channels 'Analog Conversion factors Basic 19.23 mv/count TempSlope CON 6 'in tenths of a deg F: gain of 6 gives 1/3 deg C per count, 0.6 deg F TempIntercept CON 46 'zero count is -4.6 deg F BoxSlope CON 117 BoxIntercept CON 15230 HumSlope CON 4 HumIntercept CON 261 ShuntSlope CON 39 'with charger adapter: 10 amp = 12.91, 1 amp = 130.5 ShuntIntercept CON 4961 'with charger adapter: 130.2 SpareSlope CON 60 '60 is with 47.5 K ohm added in BoB for 15 V SpareIntercept CON 0 ' Tne "line" input has a range switch as follows: LineLSlope CON 5 'For line use 5, for 5V, 20, 10V,40,15V,60, etc LineLIntercept CON 370 'For line use 370, for volts, use 0 LineDSlope CON 192 'For Direct range 'ADC Channels, used with ADCCh TempCh CON 7 HumCh CON 4 PatioCh CON 3 BackCh CON 2 LineCh CON 6 ShuntCh CON 5 BoxCh CON 0 SpareCh CON 1 'persistent variables InputData VAR Word 'The result of SHIFTIN to the two 74HC165s SwData VAR Byte 'saved from InputData low byte ExtDig1 VAR SwData.BIT7 ExtDig2 VAR SwData.BIT6 ExtDig3 VAR SwData.BIT5 ResetSw VAR SwData.BIT4 EnterSw VAR SwData.BIT3 ModeSw VAR SwData.BIT2 UpSw VAR SwData.BIT1 ' opposite MODE SetRunSw VAR SwData.BIT0 '1 is up (SETUP) ExtDigitals VAR SwData.HIGHNIB ' External digital inputs, buffered by 74LS04 + reset switch OldDigitals VAR Byte ' Previous External digital inputs and switch settings OldDig1 VAR OldDigitals.BIT7 OldDig2 VAR OldDigitals.BIT6 OldDig3 VAR OldDigitals.BIT5 OldReset VAR OldDigitals.BIT4 OldEnter VAR OldDigitals.BIT3 OldMode VAR OldDigitals.BIT2 OldUp VAR OldDigitals.BIT1 OldsetRun VAR OldDigitals.BIT0 OldPatio VAR Byte 'Previous Patio Light Value OldBack VAR Byte 'Previous Back Light Value DECData VAR Byte ' For decimal display Phase VAR Bit ' the last 1-Hz input state Sec VAR Byte Minute VAR Byte Hour VAR Byte Year VAR Byte Month VAR Byte Day VAR Byte DsTemp VAR Byte ' Last DS1620 reading HumTemp VAR Byte ' Last Valid Humidity Reading BattCount VAR Nib ' Seconds while Battery is set (Ext Dig In #1) StartCount VAR Nib ' Delay to allow SD chip to initialize Recording VAR Bit ' The SD has power applied and been initialized 'Event and Control Flags Flags VAR Nib TimerFlag VAR Flags.BIT0 ' If 1, then record is on the minute only HumFlag VAR Flags.BIT1 ' If 1, then the battery is up for BattDelay secs DigFlag VAR Flags.BIT2 ' If 1, then the gate(Dig In 2)or Digital 3 has changed LightFlag VAR Flags.BIT3 ' If 1, then either the patio or back light has suddenly changed 'Slot-specific variables Div VAR Word ' temporary variable OutputData VAR Byte ' A display command or character or an ADC address SelectData VAR OutputData.BIT0 ADCchannel VAR OutputData.LOWNIB Iter VAR Byte ' temporary variable for loops Limit VAR Byte ' counter for EEPROM arrays Rem VAR Byte ' used in multi-digit display math ADCCh VAR Nib ' Index of parameter, 0-7 is ADC channel address SettingIndex VAR Byte ' 0=not setting, 1=hour,2=minute,3=month.4=day,5=year Range VAR Byte ' 0=Line,6=Direct,1=5V,2=10V,3=15V,4=20V,5=25V DisplayRS VAR Bit ' 1 for a display character, 0 for a command Neg VAR Bit ' To display or record negative numbers if 1 Tenths VAR Bit 'To display in tenths voltages: IF SettingIndex = 10 THEN 'write the preamble of the voltages file SEROUT SDCmd,TxCode, ["W 2 ",DEC2 34,CR,DEC2 Hour,":",DEC2 Minute,":",DEC2 Sec] ENDIF FOR Iter = 0 TO 3 'Read analog ADC channel order READ ChOrder + Iter,ADCCh GOSUB GetADC 'Get the values SELECT ADCCh CASE LineCh SELECT Range CASE 0 Div = DECData + LineLIntercept 'for line volt DECData = Div/LineLSlope 'for line volts CASE 6 Div = DECData*LineDSlope ' For direct range DECData = Div/1000 Tenths=1 CASE ELSE Div = DECData*20*Range ' For other ranges DECData = Div/100 Tenths=1 ENDSELECT CASE BoxCh IF (BoxSlope * DECData) > BoxIntercept THEN Div = (BoxSlope * DECData) - BoxIntercept ELSE Div = BoxIntercept - (BoxSlope * DECData) Neg = 1 ENDIF DECData = Div/100 Tenths = 1 CASE SpareCh Div = SpareSlope * DECData DECData = Div/100 Tenths = 1 ENDSELECT OutputData = row2addr + (5 * Iter) GOSUB DispCmd GOSUB Disp3DEC IF SettingIndex = 10 THEN 'Append to the record SEROUT SDCmd,TxCode, [",",DEC3 DECData] ENDIF NEXT ' Add the flags, digitals, and internal temperature to the record IF SettingIndex = 10 THEN 'Complete the record SEROUT SDCmd,TxCode,[",",DEC3 DsTemp,",",BIN ExtDig1,BIN ExtDig2,BIN ExtDig3,CR,LF] ENDIF OutputData = row3addr 'Display the Internal Temperature. digitals and record flags GOSUB DispCmd DECData = DSTemp GOSUB Disp3Dec OutputData = Row3Addr + 5 GOSUB DispCmd OutputData = ExtDig1 + "0" GOSUB DispChar OutputData = ExtDig2 + "0" GOSUB DispChar OutputData = ExtDig3 + "0" GOSUB DispChar OutputData = Row3Addr + 10 GOSUB DispCmd OutputData = " " IF Recording = 1 THEN OutputData = "R" ENDIF IF SettingIndex = 10 THEN OutputData = "T" SettingIndex = 11 ENDIF GOSUB DispChar RUN 1 'continue at next clock positive transition 'subroutines DispCmd: 'puts a command (IoData) in OutputData into the display DisplayRS = 0 GOSUB DispChar ' The default is characters to reduce subroutne nesting levels DisplayRS = 1 RETURN DispChar: 'enters DisplayRS into the R/S latch in the display, then the data (command or character) OUTC = DispRSaddr IOData = DisplayRS PULSOUT MainIOGate,10 'Set display to get command or data OUTC = IOOUTaddr MainIOGate = 0 'Sets up a path from IOData to the serial input of the 74HC595 SHIFTOUT IoData,IOCLK,1,[OutputData\8] 'clocks the data into the shift register MainIOGate = 1 OUTC = IORCKaddr IOData = 1 PULSOUT MainIOGate,10 'transfers the shifted data to the output latches of the 74HC595 IOData = 0 PULSOUT MainIOGate,10 'restores the state OUTC = DispEnaddr IOData = 0 PULSOUT MainIOGate,10 'transfers the display command or character to the display IOData = 1 PULSOUT MainIOGate,10 'restores the state RETURN GetADC: 'The channel to be measured is in the three low bits of OutputData OUTC = IOOUTaddr MainIOGate = 0 'Sets up a path from IOData to the serial input of the 74HC595 SHIFTOUT IoData,IOCLK,1,[ADCCh\8] 'clocks the instruction into the shift register MainIOGate = 1 OUTC = IORCKaddr IOData = 1 PULSOUT MainIOGate,1 'transfers the shifted data to the output latches of the 74HC595 IOData = 0 PULSOUT MainIOGate,1 'restores the state OUTC = ADCLoadaddr IOData = 1 PULSOUT MainIOGate,10 'enters the channel into the ADC IOData = 0 PULSOUT MainIOGate,1 'restores the state OUTC = ADCStartaddr IOData = 1 PULSOUT MainIOGate,10 'starts the conversion IOData = 0 PULSOUT MainIOGate,1 'restores the state Rem = 0 DO PAUSE 1 LOOP WHILE EOC = 0 GOSUB GetInputData 'result is in InputData DECData = InputData.HIGHBYTE 'The ADC output RETURN GetInputData: OUTC = IOInaddr IOData = 0 PULSOUT MainIOGate,100 'loads the input data into the 74HCT165s IOData = 1 PULSOUT MainIOGate,100 'restores the state SHIFTIN IoIn,IOCLK,0,[InputData\16] 'clocks the input data out of the shift register RETURN Disp3Dec: 'displays a byte as a 3-digit signed number with decimal point IF Neg = 1 THEN OutputData = "-" GOSUB DispChar ENDIF Div = DECData/100 Rem = DECData//100 OutputData = Div + "0" GOSUB DispChar DECData = Rem Div = DECData/10 Rem = DECData//10 OutputData = Div + "0" GOSUB DispChar IF Tenths = 1 THEN OutputData = "." GOSUB DispChar ENDIF OutputData = Rem + "0" GOSUB DispChar OutputData = " " GOSUB DispChar Neg = 0 Tenths = 0 RETURN Disp2Dec: 'displays a byte as a 2-digit unsigned number Rem = DECData//100 'truncate if > 99 DECData = Rem Div = DECData/10 Rem = DECData//10 OutputData = Div + "0" GOSUB DispChar OutputData = Rem + "0" GOSUB DispChar RETURN