Code:
'****************************************************************
'* Name : Chicken Coop Door Control *
'* Author : Malcolm Crabbe *
'* Date : 30th January 2014 *
'* Version : 1.0 *
'* Notes : Uses PBP 2.60c *
'* : 16F690, int osc 4MHz *
'* : Program uses RTC to turn *
'* : on an electric motor and open a sliding door. *
'* : Door travel controlled by limit switches *
'****************************************************************
ASM
__CONFIG _INTRC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_ON & _MCLRE_OFF
endasm
DEFINE OSC 4
DEFINE HSER_RCSTA 90h 'Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h 'Enable transmit, BRGH = 1
DEFINE HSER_SPBRG 25 '9600 Baud @ 0.16%
DEFINE HSER_CLROERR 1 'Clear overflow automatically
ANSEL = %00000000 'Set all pins digital
ANSELH = %00000000 'Set all pins digital
ADCON0 = %00000000 'AD converter module disabled
OSCCON = %01100101 'bit7 not used, bits 6-4 4mhz default, bit3 int osc, bit2 HS stable (ignored - at 4Mhz), bit1 not stable, bit0 int osc used for system clk
CCP1CON= %00000000 'Turn off CCP module
SSPCON = %00001011 'Ic2 master
TRISA=%00000111 'set PORTA as all output apart from RA0, RA1 and RA2( bits 7&8 unimplimented read as 0)
TRISB=%11110000 'set PORTB as all input ( bits 0-3 unimplimented read as 0)
TRISC=%11111111 'set PORTC as all input (default for POR)
day var byte
RTCMin var byte 'RTC Minutes
RTCHour var byte 'RTC Hours
RTCsec var byte 'RTC Seconds
TimeH var byte 'variable to store Hours
TimeM var byte 'variable to store Minutes
SS VAR Byte 'variable to store Seconds
CounterA var byte 'General purpose Variable
CounterB var byte 'General purpose Variable
TempWD VAR WORD
Counter1 var word 'used to store the current time as a digit. Counts minutes from 0000 at midnight
Char var byte
Relay var PortA.5 'used to activate relay and thus reverse direction
Motor var PortA.4 'used to drive the motor
SW1 VAR PortA.0 'Door open limit switch
SW2 VAR PortA.1 'Door closed limit switch
SW3 var PortA.2 'Manual close button
Tx var PortB.7 'used for sending time value in testing
Rx Var PortB.5 'used for receiveing time value in testing
SetMN var byte 'Used to set time Minutes
SetHR var byte 'Used to set time Hours
SetSS var byte 'Used to set time Seconds
onHR var byte 'Used to set the Opening time (Hrs)
onMN var byte 'Used to set the Opening time (Min)
Ontime var word 'On time value in minutes
RCIF VAR PIR1.5 'USART receive flag
GIE VAR INTCON.7
RCIF=1
SCLpin var PORTB.6 'RTC pin - clk
SDApin var PORTB.4 'RTC pin - data
setHR = 06 'On powerup time set to 00 Hrs
setMN = 44 'On powerup time set to 00 minutes
onHR = 06
onMN = 46
CounterA=SetMN 'convert initial time to BDC and write it to the DS1307
Gosub ConvertBCD
RTCMin=CounterB
CounterA=SetHR
Gosub ConvertBCD
RTCHour=CounterB
I2Cwrite SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour]
day=0 ' set mode to night
low Motor ' set motor to off
low relay ' relay off
'*******************************************************************************
Main:
'*******************************************************************************
I2CREAD SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour] ; read DS1307 chip
timeH=(RTCHour>>4) 'convert the BCD format of the hours register and store in variable timeH
timeH=(timeH &$03)*10
timeH=timeH+(RTCHour&$0F)
timeM=(RTCMin>>4) 'convert the BCD format of the mins register and store in variable timeM
timeM=(timeM &$07)*10
timeM=timeM+(RTCMin&$0F)
ss=(RTCSec>>4) 'convert the BCD format of the sec register and store in variable ss
ss=(ss &$07)*10
ss=ss+(RTCSec&$0F)
Counter1 = (TimeH *60)+ TimeM 'take hours and multiply it by 60 then add odd minutes to get the total minutes into counter1
Ontime = (onHR*60)+onMN
Hserout["Time: ",#TimeH DIG 1,#TimeH DIG 0,":",#TimeM DIG 1,#TimeM DIG 0,":",#ss DIG 1,#ss DIG 0," Counter = ",#counter1," Ontime = ",#ontime,13,10]
pause 200
FOR TempWD = 0 TO 1000
IF RCIF THEN GOto comms ' Check to see if there is communications on the comm port
PauseUs 1000
NEXT TempWD
if counter1 = ontime and SW2=1 then ' If counter matches on time and A.1 is high then
high Motor ' Turn on the motor
high relay ' Energise the relay
endif
if SW1 = 1 then ' Door open limit switch (A.0) hit and applies 5v to pin
low Motor ' Stop motor
low relay ' de-energise relay
endif
if ontime < counter1 or ontime > counter1 then ' If the counter is anything other than ontime, turn everything off
low SW1
low motor ' Turn on the motor
low relay ' Relay kept off for reverse polarity of motor
endif
If SW3 = 1 then
high motor
low relay
Low SW1
endif
if SW2 = 1 and ontime < counter1 or ontime > counter1 then ' Door closed limit switch hit and applies 5v to pin
low Motor ' Stop motor
endif
goto Main
'*******************************************************************************
'*******************************************************************************
convert:
CounterA=SetMN
Gosub ConvertBCD
RTCMin=CounterB
CounterA=SetHR
Gosub ConvertBCD
RTCHour=CounterB
I2Cwrite SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour]
return
'*******************************************************************************
comms:
HSERIN [Char]
SELECT CASE Char
CASE "T","t" ' set time
hserout ["Set Time Hour ",10]
HSERIN [#setHR]
hserout ["Set Time minutes ",10]
HSERIN [#setMN]
gosub convert
CASE "O","o"
Hserout["Set Open Time: ",13,10]
hserout ["Set Hour ",10]
HSERIN [#onHR]
hserout ["Set Minutes ",10]
HSERIN [#onMN]
Ontime = (onHR*60)+onMN
CASE "C","c"
Hserout["Time: ",#TimeH DIG 1,#TimeH DIG 0,":",#TimeM DIG 1,#TimeM DIG 0," Counter = ",#counter1,13,10]
pause 500
end select
goto Main
'*******************************************************************************
' convert BDC format to decimal
ConvertBCD:
CounterB=CounterA DIG 1 ' CounterA is the entry variable
CounterB=CounterB<<4 ' CounterB holds the converted BCD result on exit
CounterB=CounterB+CounterA DIG 0
Return
'*******************************************************************************
Ok the code may be very basic, could possibly be written tighter and isn't really rocket science, but it works for me. Likewise the choice of transistor in the schematic might of been better, but it's what I had and after the debuging - works with the relays etc.
Bookmarks