' Loggersx.bsx ' Records Environmental data on a Secure Digital Module ' Used with a Breakout Box and outside Humidity/Temperature/Ambient light box ' Slot 0 - Initialization and time set ' John Saunders 12/15/2006 ' {$STAMP BS2sx,Loggersx1.bs2,Loggersx2.bs2,Loggersx3.bs2} ' {$PBASIC 2.5} 'initialization data MainIOInit CON %00010010 'sets the initial state of 74259 #1, LSB is Q0 AuxIOInit CON %00000010 'sets the initial state of 74259 #2, LSB is Q0 DispInitData DATA 32,29,32,31,32,31,32,32,31,32,31,32 DispInitLen CON 8 DayInMonth DATA 31,28,31,30,31,30,31,31,30,31,30,31 DayLoc DATA 15 'using EEPROM to reduce need to re-enter MonthLoc DATA 12 'using EEPROM to reduce need to re-enter YearLoc DATA 06 'using EEPROM to reduce need to re-enter '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 '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 '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 '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 start: IF year > 0 THEN softreset DIRS = %0001111100001111 GOSUB InitCmds GOSUB InitDisp GOSUB ReadDate softreset: SettingIndex = 0 StartCount = 0 BattCount = 0 Recording = 0 IoData = 0 OUTC = RELAY 'Cut off power TO the SD chip PULSOUT AuxIOGate,10 SDCmd = 0 'Set the input low to prevent current drain moredigits: GOSUB GetInputData SWData = InputData.LOWBYTE IF SetRunSw = 0 THEN SettingIndex = 1 RUN 1 ENDIF IF Phase <> RTC THEN Phase = RTC GOSUB DispTime IF Phase = 1 THEN GOSUB SetTime ENDIF ENDIF GOTO moredigits InitCmds: MainIOGate = 1 AuxIOGate = 1 ChimeGate = 0 IOCLK = 0 OldDigitals = 0 OutputData = MainIOInit PAUSE 20 FOR Iter = 0 TO 7 OUTC = Iter IOData = SelectData PULSOUT MainIOGate,1 OutputData = OutputData >> 1 NEXT OutputData = AuxIOInit FOR Iter = 0 TO 7 OUTC = Iter IOData = SelectData PULSOUT AuxIOGate,1 OutputData = OutputData >> 1 NEXT RETURN InitDisp: FOR Iter = 0 TO DispInitLen READ DispInitData + Iter,OutputData GOSUB DispCmd NEXT RETURN ReadDate: READ YearLoc,Year READ MonthLoc,Month READ DayLoc,Day RETURN SetTime: IF EnterSw = 1 THEN SettingIndex = SettingIndex + 1 OUTC = HighBeep 'Audible inDivation of putton press PULSOUT ChimeGate,100 IF SettingIndex > 4 THEN SettingIndex = 0 ENDIF Sec = 0 ENDIF SELECT SettingIndex CASE 0 DECData = Hour Div = 23 GOSUB AdjustTimeValue hour = DECData CASE 1 DECData = Minute Div = 59 GOSUB AdjustTimeValue Minute = DECData CASE 2 DECData = Month - 1 Div = 11 'computations start at 0, corrected in DispTime GOSUB AdjustTimeValue Month = DECData + 1 WRITE MonthLoc,Month CASE 3 READ (DayInMonth + Month),Div 'to index Day in month DECData = Day - 1 GOSUB AdjustTimeValue Day = DECData + 1 WRITE DayLoc,Day CASE 4 DECData = Year Div = 99 GOSUB AdjustTimeValue WRITE YearLoc,DECData Year = DecData ENDSELECT RETURN AdjustTimeValue: 'value to be updated is in DECData, Div is in Div IF ModeSw = 1 THEN IF DECData = 0 THEN DECData = Div ELSE DECData = DECData - 1 ENDIF ENDIF IF UpSw = 1 THEN IF DECData >= Div THEN DECData = 0 ELSE DECData = DECData + 1 ENDIF ENDIF RETURN 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 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 DispTime: 'format is hh:mm:ss mm/dd/20yy OutputData = row0addr GOSUB DispCmd DECData = Hour GOSUB Disp2Dec OutputData = ":" GOSUB Dispchar Iter = 2 DECData = Minute GOSUB Disp2Dec OutputData = ":" GOSUB Dispchar DECData = Sec GOSUB Disp2Dec OutputData = row0addr + 9 GOSUB DispCmd DECData = Month GOSUB Disp2Dec OutputData = "/" GOSUB Dispchar DECData = Day GOSUB Disp2Dec OutputData = "/" GOSUB Dispchar OutputData = "2" GOSUB Dispchar OutputData = "0" GOSUB Dispchar DECData = Year GOSUB Disp2Dec IF RTC = 1 THEN LOOKUP SettingIndex,[row0addr,row0addr+3,row0addr+9,row0addr+12,row0addr+17],OutputData GOSUB DispCmd OutputData = " " GOSUB Dispchar OutputData = " " GOSUB Dispchar ENDIF 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