Code:' -----[ Device Declaration ]---------------------------------------------- @ __config _INTRC_OSC_NOCLKOUT & _BOR_OFF & _FCMEN_OFF & _WDT_OFF & _MCLRE_OFF & _CP_OFF ' -----------------[ Declare Variables & Aliases ] ADINPUT VAR WORD ' Stores VP6 value as sampled by the A/D b0 VAr vdd.byte1 ' LSB of VDD when right justified b1 var VDD.Byte0 ' MSB of VDD when right justified dummy VAR Byte ' For read of on-interrupt port & clear mismatch condition ext_pwr VAR PORTC.3 ' Set RC3 to control RL2 as RL1 power control source flush VAR PORTA.3 ' Set RA3 as input for sensing flush switch closure Int i VAR Byte ' Index used in Gallon counter loop LED_Grn VAR PORTC.0 ' Set RC0 (Green LED) for valve open..water flowing LED_Red VAR PORTC.1 ' Set RC1 (Red LED) for solenoid cmnd or low battery meter VAR PORTA.2 ' Set RA2 as input for HS1 meter pulse Interrupt sol_valve VAR PORTC.2 ' Set RC2 as valve solenoid open/close command Vdd VAR WORD ' Stores Vdd value as converted from ADINPUT Vthr CON 32 ' Set threshold (3.2v) to trigger low voltage warning ' -----[ Declare Constants ] k CON 10 ' Calibration factor for flow meter...# pulses per gal ' -----[ Initialization ] Init: ' Setup Timer0 as an 8-bit counter with the clock input on RA2. ' 1:1 TMR0 prescaler ' TMR0 counts on high-to-low transitions OPTION_REG = %00111000 ' PORTA/B pullups enabled, Interrupt on falling ' edge of RA2/INT, TMR0 clock source is RA2, ' increment on high-to-low transitions, prescaler to ' TMR0, TMR0 Rate 1:2 TMR0 = 256 - k ' preload TMR0 to overflow after k counts ' Initialization of inputs/outputs flush = 1 ' Initialize RA3 (flush) at High value for flush interrupt meter = 1 ' Initialize RA2 (meter) at High for METER pulse inputs ' RA2 = TMR0 clock input for simulated meter pulse inputs ext_pwr = 0 ' Intialize RC3 at low value to turn off external power sol_valve = 0 ' Initialize RC2 (sol_valve) at Low value TRISA.2 = 1 ' Set RA2 as input port for clock to TMR0 TRISA.3 = 1 ' Set RA3 as input port for sensing Flush switch closure ' Interrupts Settings TMR0_Enable VAR INTCON.5 ' Alias for On_Off switch of TMR0 counter FLUSH_INT_FLAG VAR INTCON.0 ' Alias RA3(FLUSH) On-change-interrupt flag bit TMR0_INT_FLAG VAR INTCON.2 ' Alias Timer0 overflow flag bit ' Set INT Handler ON INTERRUPT GOTO Int_handler '-----[ Main Code Starts Here ] MAIN: ' Perform following steps to save power during Sleep mode ext_pwr = 0 ' Turn off external power after interrupt is over OPTION_REG.7 = 1 ' Disable PortA/PortB pull-ups OSCCON = %0100011 ' Switch to 1 MHz internal oscillator VRCON = %00100000 ' Set Voltage Reference for minimum power consumption ' Disable CVref ANSEL= %11110011 ' Set PortA to Analog I/O to save power during Sleep but ' leave Bits 2 & 3 as digital for RA2 pulse count ' TMR0 overflow interrupt & RA3 On-Change intterupt. ANSELH= %11111111 ' Analog module enabled to save power during Sleep CM1CON0.7 = 0 ' Turn off comparators during Sleep CM2CON0.7 = 0 PCON.4 = 0 ' Turn off BOR during Sleep WDTCON = %00010110 ' Turn WDT off to SLEEP indefinitely TRISA = %00001101 ' Set RA0, RA2 & RA3 as inputs TRISB = %11111111 ' Set all PORTB pins to inputs during Sleep TRISC = %11111111 ' Set all PORTC pins to input during Sleep PortA = %11111111 ' Write Port A all High to clear mismatch and save ' power during SLEEP PortB = %11111111 ' Set all Port B and C pins High to save power PortC = %11111111 ' in Sleep mode ' Interrupt Settings INTCON = %10001000 ' Enable interrupts: GIE & RABIE but TMR0 disabled IOCA = %00001000 ' before SLEEP. Enable RA3 as RABIE on-change-INT @ sleep @ NOP ' @ NOP statement here makes no difference ' Microcontroller is in Sleep State waiting for external FLUSH Interrupt ' Valve should be closed at this point and no water flowing GOTO Main ' Loop to Main to wait for next Flush interrupt on RA3 change '------{ Begin Interrupt Handler } DISABLE ' Disable interrupts during interrupt handler Int_handler: 'Initialize registers upon Interrupt wakeup from Sleep OPTION_REG.7 = 0 ' Enable PortA/PortB Pullups WDTCON = %0001000 ' Turn WDT on for ops ' A/D & Comparators disabled ANSEL=0 ' Set PortA to digital I/O for use with RA2 and RA3 ANSELH=0 ' Analog module disabled CM1CON0=0 ' Disable comparators CM2CON0=0 ' Port Settings 'TRISA = %00001000 ' Per JoeS to save power TRISA = %11111111 ' Set all PORTA pins to inputs...RA0, RA2 & RA3 are used TRISB = %00000000 ' Set all PORTB pins to outputs 'TRISC = %00000000 TRISC = %11110000 ' Set lower 4 pins of PortC as outputs for LEDs PORTA = %00000000 ' PortA pins all set to Low PORTC = %00000000 ' LEDs off, PULSOUT RC3 provides a high-going pulse HIGH ext_pwr ' Turn on power to RL1 and to external power during ' the Interrupt Service Routine DEFINE WRITE_INT 1 IF FLUSH_INT_FLAG = 1 Then ' Interrupt was from RA3 on change REPEAT ' Wait until the external Flush interrupt is at high level...limits ' interrupt to switch closure only and not also for switch opening Until flush = 1 PULSOUT sol_valve,2000*10 ' Generate 100 msec RC2 pulse to RL1 to ' open valve 'Write 7, flush ' Write FLUSH value..remove comment for test only ' Put code here to start a timer to run for 50 secs as a fail safe ' to prevent overflow of toilet tank in case of sensor failure. 'PULSOUT relay_off,2000 ' Generate 20 msec ' pulse to RL2 to turn off power to RL1 Endif TMR0_Enable = 1 ' Enable the TMR0 pulse counter for overflow interrupt ' Valve is open and water is flowing REPEAT ' Execute this loop while waiting for flow to reach 1.6 gallons. ' Set registers for using A/D converter ' Set ADCON registers for A/D converter ADCON0 = %10110101 ' ADCON0.7 = ADFM = 1 ' 10-bit result is right justified ' ADCON0.6 = VCFG = 0 ' Set VREF+ to Vdd ' CHS<3:0> = 1101 ' Select 0.6V Ref channel ADCON1 = %00110000 ' Select FRC as A/D conversion clock source ' Set FOSC=1MHz to stay inside recommended TAD range when not in SLEEP mode OSCCON = %01000001 ' Set ANSEL register to make RA1 analog input ANSEL= %11110011 ' Set PortA to Analog I/O to save power during Sleep but ' leave Bits 2 & 3 as digital for RA2 and RA3 interrupts ANSELH= %11111111 ' Analog module enabled to save power during Sleep DEFine ADC_BITS 10 ' Flash Green flow light while water flowing until pulse counter overflows. LED_Grn = 1 Pause 125 LED_Grn = 0 Pause 500 ' If Battery is low..flash low battery monitor light while water flowing VRCON.4 = 1 ' Turn 0.6V reference ON PAUSEUS 100 ' Allow VP6 to settle ADCIN 13,ADINPUT ' Get VP6 analog reading (10-bit) VRCON.4 = 0 ' Turn 0.6V reference OFF WRITE 11,ADINPUT 'A/D scale for 0.6 volts is 0.6 * 1024 Full Scale = 6138 VDD = 6138/ADINPUT ' convert input reading to Vdd voltage ' Vdd now holds the measured Vdd voltage * 10 (i.e., 3.4V = 34) ' The formula is the same for any Vdd voltage. Assume normal ' Vdd = +3.95vdc direct from fully charged battery pack input. WRITE 13,b0 ' Remove comments on Write statements for test only WRITE 14,b1 Write 17,Vthr IF Vdd <= Vthr THEN ' If Vdd less than or equal to 3.2v flash the LED_Red =1 ' Blink RED LED for warning to replace batteries. PAUSE 125 LED_Red = 0 Pause 500 EndIF Until TMR0_INT_FLAG = 1 ' Loop ends w/ flow meter pulse counter overflows PULSOUT sol_valve,2000*10' Generate 100 msec pulse to RC2 & Blink LED_Red LED_Red = 1 ' Blink RED LED one time to indicate close command PAUSE 125 LED_Red = 0 Pause 500 'WRITE 19, TMR0_INT_FLAG ' Write TMR0 value..remove comment for test only dummy = flush ' Clear mismatch condition FLUSH_INT_FLAG = 0 ' Clear interrupt flag & enable RA3 on interrupt TMR0_INT_FLAG = 0 ' Clear overflow flag TMR0 = 256 - k ' Reload TMR0 to overflow after k counts RESUME ' Resume Main Program ENABLE '-------{ End of Interrupt Handler } END




Bookmarks