;PIC Lead/Acid Grid Charger Control
;Tom Woods 3/4/2006
;This program monitors battery voltage. When it drops below an adjustable
;preset voltage, it turns on a solid state relay that can control a battery 
;charger that is connected to the public utility power grid. The relay will 
;remain on for a period of time set by jumpers SW1 and SW2, or
;until battery reaches an adjustable preset high voltage cut-off.
;When the relay turns off, charging reverts to the solar or other alternative energy 
;source. Grid power will not be switched on until battery voltage again drops
;below the setpoint. A reset switch will toggle the relay OFF and ON. The unit will
;turn itself ON when battery voltage is below the setpoint.
;When the reset button is pressed, the LED will blink the number of times the 
;charger has turned on since the last reset.
;
; Relay ON duration is approximately as follows 
; (n=no jumper, y=jumper connected to ground):
;         SW1	SW2  Duration
;          y     y   1 hour 
;          n     y   2 hours
;          y     n   3 hours
;          n     n   4 hours

    	include "c:\program files\mplab ide\mchip_tools\p16f676.inc"
RELAY	EQU	0		;Bit 0 (Pin 10) is the relay control line
LED		EQU 1		;Bit 1 (Pin 9) is the LED line
SW1		EQU 5		;Jumpers on these bits of PORTC determine Relay ON duration
SW2		EQU 4
SECONDS	EQU h'20'	;Address of location that stores count of seconds
MINUTES	EQU h'21'	;Address of location that stores count of minutes
HOURS	EQU h'22'	;Address of location that stores count of hours
CYCLES	EQU h'23'	;Address of location that stores number of times the charger 
					;  was turned on since the last reset.
DELAY1	EQU h'24'	;Address of locations that process a delay during the LED blink.
DELAY2	EQU h'25'
SCRATCH	EQU h'26'
PAUSETIME	EQU h'3'	;Number of iterations for the wait loop
MAXVOLTS EQU d'128'     ;This value is good when the battery high cut-off voltage
						;is trimmed to 2.5 volts as measured at pin 8 and pin 12.
 
;Summary of 16F676 Pin Assignments
	;Pin 4  MCLR		Reset Button Input
	;Pin 5  SW1			Relay ON duration jumpers, SW1, SW2
	;Pin 6  SW2
	;Pin 8  A/D 		+ Battery Voltage Input
	;Pin 9  LED			Output to LED 
	;Pin 10	Relay		Control Output to relay
	;Pin 12	Comparator	Battery + Voltage Input
	;Pin 13 Comparator	Reference Voltage Input

				ORG		0
				movfw STATUS
RESETVECTOR		BSF	STATUS,RP0		;Select bank 1
				BTFSS PCON,1
				GOTO POWERUP
INITIALIZE		CLRF ANSEL			;Power ON and button resets initialize 
									;the peripherals...  
				MOVLW b'00110100' 	;Make RC2 (pin 8) an input for the A-D (AN6)
									;RC5 (pin 5) and RC4 (pin 6) digital inputs,
				MOVWF TRISC		  	;and other lines of PORTC outputs
				BCF STATUS,RP0		;Select bank 0
				CLRF INTCON			;disable peripheral interrupts.
									;Initialize A-D converter on AN6 (Pin 8)
				MOVLW b'00011000'	;Left justified, AN6, VDD=Vref
				MOVWF ADCON0
				CLRF ADRESH			;Zero out the AD converter
				BSF STATUS,RP0 		;Bank 1
				MOVLW b'01000011' 	;Enable AN6, AN0, AND AN1 (Pins 8,13,12)as analog
				MOVWF ANSEL
				MOVLW b'01010000' 	;Set AD clock to Fosc/16
				MOVWF ADCON1
									;Initialize comparator and timer.
				BSF		TRISA,1		;Pin 12 is comparator input.
				BSF		TRISA,0		;Pin 13 is comparator input.
				BCF		STATUS,RP0	;Bank 0
				MOVLW	b'00000010'	;Comparator goes high when
				MOVWF	CMCON		;battery voltage (pin 12) is less than
                                    ; reference voltage (pin 13)
				CLRF	TMR0		; Clear the clock value
				BSF		STATUS,RP0	;Bank 1
				MOVLW	b'10000110'
			

				MOVWF	OPTION_REG
				BCF 	STATUS,RP0	;Bank 0
				BTFSS	PORTC,RELAY ;What is the status of the relay?
				GOTO 	RELAYISOFF
RELAYISON		INCF	CYCLES,1
				CALL	LEDBLINK
				GOTO	RELAYOFF

RELAYISOFF		CALL	LEDBLINK
				GOTO	RELAYSET

RELAYOFFA		INCF	CYCLES,1	
RELAYOFF		BCF		STATUS,RP0	;Bank 0
				BCF		PORTC,RELAY	;Turn OFF the relay and LED
				BCF		PORTC,LED
							
				
;At this point everything is initialized and the relay is OFF.
;All we do is watch the voltages and the clock.
COMPARATOR		BTFSS		CMCON,6   		;Is the battery < Vref? (was BTFSS)
				GOTO		RELAYOFF		;No. Go back and wait.
				CALL	WAIT			;Yes. Then resample to make sure
				BTFSS	CMCON,6			;we're not looking at a load spike.(was BTFSS)
				GOTO	RELAYOFF		;Is battery<Vref? No. Go back and wait.
										;Otherwise we have a true reading and need
										;to turn on the relay. 
				CLRF		HOURS		;Zero out the counters
				CLRF		MINUTES
				CLRF		SECONDS
				CLRF		TMR0
CHECKAD			BSF		ADCON0,0	;Turn ON the A/D
				BSF		ADCON0,1	;Read the A/D. Set the GO bit
ADHOLD			BTFSC	ADCON0,1	;and wait for it to go low (DONE)
				GOTO	ADHOLD
				BCF		ADCON0,0	;Turn OFF the A/D
				MOVLW 	MAXVOLTS	
				SUBWF	ADRESH,0	;Subtract maxvolts from battery volts
				BTFSC	STATUS,C	
				GOTO	RELAYOFF	;If battery>MAXVOLTS, go back and turn off the relay

									
									
									;If Battery < MAXVOLTS...
RELAYSET		BSF		PORTC,RELAY	;Turn ON the relay
				BSF		PORTC,LED	; and LED.
TLOOP			MOVLW	d'63'		;Approximate 'ticks' per second.
				SUBWF	TMR0,0
				BTFSS	STATUS,Z
				GOTO	TLOOP
				
									
				INCF	SECONDS,1 	;Once per second
				CLRF	TMR0
				MOVLW	D'60'
				SUBWF	SECONDS,0
				BTFSS	STATUS,Z
				GOTO 	CHECKAD

ADVANCE			INCF	MINUTES,1		;Once per minute
				CLRF	SECONDS
				MOVLW	d'60'
				SUBWF	MINUTES,0
				BTFSS	STATUS,Z
				GOTO 	CHECKAD

				INCF	HOURS,1			;Once per hour
				CLRF	MINUTES
				CALL	ONTIME			;Find out how long the relay should be ON.
				SUBWF	HOURS,0
				BTFSS	STATUS,Z
				GOTO 	CHECKAD			;Keep counting if time is not up.
				GOTO	RELAYOFFA		;Shut off and wait when time is up.

LEDBLINK		BCF		PORTC,LED		;Subroutine that handles the blinking of
				CALL	WAIT			;the LED equal to the number of times the
				MOVF	CYCLES,W		;charger was turned on since the last reset.
				MOVWF	SCRATCH			;The count is set to zero
				INCF	SCRATCH,1
BLINK2			DECF	SCRATCH,1
				BTFSC	STATUS,Z
				GOTO	OUT
BLINK3			BSF		PORTC,LED
				CALL	WAIT
				BCF		PORTC,LED
				CALL	WAIT
				GOTO	BLINK2
OUT				CALL 	WAIT
				CLRF	CYCLES
				RETURN

WAIT			MOVLW	PAUSETIME		;A subroutine to delay
				MOVWF	DELAY1
WAIT1			MOVLW	h'ff'
				MOVWF	DELAY2
WAIT2			DECFSZ	DELAY2,1
				GOTO 	WAIT2
				DECFSZ	DELAY1,1
				GOTO	WAIT1
				RETURN
ONTIME			CLRF	SCRATCH			;Subroutine returns with W=# hrs the relay
				BTFSC PORTC,SW1			;should be ON. Transfer SW2 and SW1 to W bits
				BSF	SCRATCH,0			;1 and 0. Then increment W so the subroutine will
				BTFSC PORTC,SW2			;return with W=1,2,3,4
				BSF SCRATCH,1
				INCF SCRATCH
				MOVF SCRATCH,W
				RETURN
		
POWERUP			BSF PCON,1				;The initial powerup. 
				BCF STATUS,RP0		;Select Bank 0
				CLRF PORTC
				CLRF CYCLES	
				CLRF MINUTES
				CLRF HOURS
				CLRF SECONDS
				BSF STATUS,RP0		;Bank 1
				GOTO INITIALIZE

				end


