Code:
ASM
__CONFIG _CONFIG1H, _OSC_HS_1H
__CONFIG _CONFIG2L, _PWRT_ON_2L
__CONFIG _CONFIG2H, _WDT_ON_2H & _WDTPS_512_2H
__CONFIG _CONFIG3H, _MCLRE_ON_3H & _LPT1OSC_OFF_3H & _PBADEN_OFF_3H
__CONFIG _CONFIG4L, _LVP_OFF_4L & _XINST_OFF_4L
ENDASM
INCLUDE "DT_INTS-18.bas" ; Base Interrupt System
INCLUDE "SPWM_INT.bas" ; Software PWM module
DEFINE SPWM_FREQ 200 ; SPWM Frequency
DEFINE SPWM_RES 256 ; SPWM Resolution
ASM
SPWM_LIST macro ; Define Pin's to use for SPWM
SPWM_PIN PORTC, 1, _B_PWM ; and the associated DutyCycle variables
SPWM_PIN PORTC, 2, _W_PWM ; Notice the underscore before variables
endm
SPWM_INIT SPWM_LIST ; Initialize the Pins
ENDASM
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, SPWMhandler, ASM, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts
INCLUDE "LCDbar_INC.bas" ' Include the BARgraph routines
DEFINE LCD_DREG PORTB ' LCD Data port
DEFINE LCD_DBIT 0 ' starting Data bit (0 or 4)
DEFINE LCD_EREG PORTB ' LCD Enable port
DEFINE LCD_EBIT 5 ' Enable bit (on EasyPIC 5 LCD)
DEFINE LCD_RSREG PORTB ' LCD Register Select port
DEFINE LCD_RSBIT 4 ' Register Select bit (on EasyPIC 5 LCD)
DEFINE LCD_BITS 4 ' LCD bus size (4 or 8 bits)
DEFINE LCD_LINES 4 ' number of lines on LCD
DEFINE LCD_COMMANDUS 2000 ' Command delay time in us
DEFINE LCD_DATAUS 50 ' Data delay time in us
DEFINE OSC 20 ' 18F4520, 20mhz crystal
ADCON1 = $0F
clear
'*******************************************************************************
'DS18B20 temp probe setting
'*******************************************************************************
DQ VAR PORTA.5 ' One-wire data pin
temperature VAR WORD ' Temperature storage
count_remain VAR BYTE ' Count remaining
count_per_c VAR BYTE ' Count per degree C
'*******************************************************************************
'Port and Register settings
'*******************************************************************************
TRISA = %11101111
TRISB = %00000011
TRISD = %00000011
T0CON = %11000111
ADCON0 = %00000000; // AD converter module disabled
ADCON1 = %00001111; // All Digital
ADCON2 = %00000000; //
CMCON = 7
'*******************************************************************************
' Data presets
'*******************************************************************************
data @0
data 00 'Blue fade IN duration hours
data 5 'Blue fade IN duration minutes
data 00 'Blues fade OUT duration hours
data 45 'Blue fade OUT duration minutes
data 00 'Whites fade IN duration hours
data 7 'Whites Fade IN duration MINS
data 00 'Whites Fade OUT duration HOURS
data 20 'Whites Fade OUT duration MINS
data 255 'Blue MAX Intensity %
data 255 'Whites MAX Intensity %
data word 840 'Blue ON time 14:00
Data word 840 'Whites ON time 14:00
data word 1200 'Blue OFF time 20:00
Data word 1200 'White OFF time 20:00
Data word 1200 'Sump light on time 20:00
Data word 1200 'Sump light off time 8:00
'*******************************************************************************
' Variables
'*******************************************************************************
fadesetHR VAR WORD[2]
fadesetHR1 VAR fadesetHR[0] 'blue fade in hour
fadesetHR2 VAR fadesetHR[1] 'White fade in hour
fadesetMN VAR WORD[2]
fadesetMN1 VAR fadesetMN[0] 'blue fade in minutes
fadesetMN2 VAR fadesetMN[1] 'white fade in minutes
fadeoutHR VAR WORD[2]
fadeoutHR1 VAR fadeoutHR[0] 'blue fade out hour
fadeoutHR2 VAR fadeoutHR[1] 'white fade out hour
fadeoutMN VAR WORD[2]
fadeoutMN1 VAR fadeoutMN[0] 'blue fade out minute
fadeoutMN2 VAR fadeoutMN[1] 'white fade out minutes
lightsetHR VAR word[2]
lightsetHR1 VAR lightsetHR[0] 'blue on time hour
lightsetHR2 VAR lightsetHR[1] 'white on time hour
lightsetMN VAR word[2]
lightsetMN1 VAR lightsetMN[0] 'blue on time minutes
lightsetMN2 VAR lightsetMN[1] 'white on time minutes
lightoffHR VAR word[2]
lightoffHR1 VAR lightoffHR[0] 'blue off time hour
lightoffHR2 VAR lightoffHR[1] 'white off time hour
lightoffMN VAR word[2]
lightoffMN1 VAR lightoffMN[0] 'blue off time minutes
lightoffMN2 VAR lightoffMN[1] 'white off time minutes
DecButton var PORTA.0 ' Press to Decrement Button
SetButton var PORTA.1 ' Press to Set/memorise Button
IncButton var PORTA.2 ' Press to Increment Button
OnButton var PORTA.0 ' Press to Decrement Button
OffButton var PORTA.2 ' Press to Increment Button
H_butt VAR PORTA.2 'hour increase
M_butt VAR PORTA.0 'minutes increase
S_butt VAR PORTA.1 'set / memorise
Counter1 var word 'used to store the current time as a digit. Counts minutes from 0000 at midnight
Blue_on_Time var word 'stores the blue on time as a digit in minutes, eg 14:00hrs = 840
Blue_off_Time var word 'stores the blue off time as a digit in minutes, eg 14:00hrs = 840
White_on_Time var word 'stores the white on time as a digit in minutes, eg 14:00hrs = 840
White_off_Time var word 'stores the white off time as a digit in minutes, eg 14:00hrs = 840
white_delay_in var byte 'stores the white fade in pule in seconds
blue_delay_in VAR byte 'stores the blue fade in pule in seconds
white_delay_out var byte 'stores the white fade out pule in seconds
blue_delay_out VAR byte 'stores the blue fade out pule in seconds
W_Min var byte 'Min Light value - Whites
W_Max var byte 'Max Light value - Whites
B_Min var byte 'Min Light value
B_Max var byte 'Max Light value
Old_B_Max var byte
Old_W_Max var byte
W_PWM var word 'PWM Variables where the current output values are stored - Whites
B_PWM var word 'PWM Variables where the current output values are stored - Royal Blues
old_ss_blue var byte 'records the previous second in blue fade in
old_ss_white var byte 'records the previous second in white fade in
option var byte 'menu option, used to choose which menu option is required
Viv var byte 'used to select the channel the menu selection applies to
maxbright var byte 'general variable used to set the max brighness for each channel in menu option
fn var byte 'general variable to switch between channels in menu options
Hours var byte 'used in menu options to set hours for each channel
Minutes var byte 'used in menu options to set minutes for each channel
light var byte
Sumplighton Var word 'counter variable for sump on time
Sumplightoff Var Word 'counter vairable for sump off time
Sump_light Var PORTA.4 'sump light pin
sumponHR VAR byte 'sump light on Hour
sumponMN var byte 'sump light on Minutes
sumpoffHR var byte 'sump light off Hours
sumpoffMN var byte 'sump light off Minutes
daycount var byte
TimeH var byte 'variable to store Hours
TimeM var byte 'variable to store Minutes
SS VAR Byte 'variable to store Seconds
RTCsec var byte 'RTC Seconds
RTCMin var byte 'RTC Minutes
RTCHour var byte 'RTC Hours
SetMN var byte 'Used to set time Minutes
SetHR var byte 'Used to set time Hours
SetSS var byte 'Used to set time Seconds
SCLpin var PORTC.3 'RTC pin - clk
SDApin var PORTC.4 'RTC pin - data
CounterA var byte 'General purpose Variable
CounterB var byte 'General purpose Variable
CounterC var byte 'General purpose Variable
CounterD var byte 'General purpose Variable
FlashStar VAR BIT
Blue_Day_Cycle var word 'Store for which part of the blue day cycle we are in
White_Day_Cycle var word 'Store for which part of the white day cycle we are in
DAWN con 0 'Constants for the current running mode cycle for the lights
DAY con 1
DUSK con 2
NIGHT con 3
'*******************************************************************************
;Initialization
LCDOUT $FE,1:FLAGS=0:PAUSE 250:LCDOUT $FE,1:PAUSE 250 ' Initialize LCD
LCDOUT $FE,1
lcdout $FE,$C0," Firmware v1.07 "
pause 2000 'wait 2 seconds so they can see it
lcdout $FE,1 'Clear the screen
Gosub read_eprom 'read in presets for fade in durations and brighness
blue_delay_in = (((fadesetHR[0]*60)+fadesetMN[0])*60)/255 'takes hours and minutes, converts to minutes, then converts to seconds
white_delay_in = (((fadesetHR[1]/60)+fadesetMN[1])*60)/255 'takes hours and minutes, converts to minutes, then converts to seconds
blue_delay_out = (((fadeoutHR[0]/60)+fadeoutMN[0])*60)/255 'takes hours and minutes, converts to minutes, then converts to seconds
white_delay_out = (((fadeoutHR[1]/60)+fadeoutMN[1])*60)/255 'takes hours and minutes, converts to minutes, then converts to seconds
Option = 1 'sets the menu option default as 1 (set time)
daycount=0 'used in sumplight routine to check if gone passed midnight
Sumplightoff =1439
Sumplighton =1439 'sumplight - values used to match counter1 for on off times
setHR = 13 'initial time following programming or re-boot if RTC not battery backed up
setMN = 59
'convert initial time to BDC and write it to the DS1307
CounterA=SetMN
Gosub ConvertBCD
RTCMin=CounterB
CounterA=SetHR
Gosub ConvertBCD
RTCHour=CounterB
I2Cwrite SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour]
'*******************************************************************************
'************ Main Program Loop ***************
'*******************************************************************************
Main:
If SetButton=0 then 'if presed jump to the menu
goto mainmenu
endif
'*******************************************************************************
' check for manual override of the lights
If H_butt = 0 then ' if pressed then change state of varible to 1
Light=1
endif
If M_butt = 0 then ' if pressed then change state of varible back to 0
Light=0
endif
'*******************************************************************************
'clock routine
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
LCDOut $FE,$D4+15,#TimeH DIG 1,#TimeH DIG 0,":",#TimeM DIG 1,#TimeM DIG 0
'*******************************************************************************
' check to see if the sump light should be on or off
If daycount = 0 THEN ' by default daycount is 0
If Counter1 => sumplighton Then ' if the counter matched the sump light on time
high sump_light ' then make the pin high and
daycount = 1 ' set the day count to 1
ENDIF
ENDIF
IF daycount = 1 THEN ' if the daycount is 1 and
If Counter1 = sumplightoff Then ' conuter matches sump light off time
low sump_light ' then make the pin low and
daycount = 0 ' reset daycount back to 0
ENDIF
ENDIF
'*******************************************************************************
'Case Cycle logic
If Counter1 < Blue_on_Time then
Blue_day_cycle = NIGHT
endif
if counter1 > blue_on_time and Counter1 > blue_off_Time and B_PWM > B_Min then
Blue_day_cycle = DUSK
endif
if counter1 => blue_on_time and Counter1 < blue_off_Time and B_PWM < B_MAX then
Blue_day_cycle = DAWN
endif
If Counter1< White_on_Time then
White_day_cycle = NIGHT
endif
if counter1 > white_on_time and Counter1 > white_off_Time and W_PWM > W_Min then
White_day_cycle = DUSK
endif
if Counter1 => white_on_time and Counter1 < white_off_Time and W_PWM < W_MAX then
White_day_cycle = DAWN
endif
'*******************************************************************************
'BLUE daily cycle
select case Blue_Day_Cycle
case DAWN
lcdout $FE,$80+15,"DAWN "
if ss//blue_delay_in = 0 then
if ss != old_ss_blue then
B_PWM=B_PWM+1
old_ss_blue=ss
endif
endif
if B_PWM = b_max then
Blue_Day_Cycle = DAY
endif
case DAY
lcdout $FE,$80+15,"DAY "
if B_max < B_PWM then
B_PWM=B_PWM - 1
endif
if counter1 =blue_off_time then
Blue_day_cycle = DUSK
endif
CASE DUSK
lcdout $FE,$80+15,"DUSK "
if ss//blue_delay_out= 0 then
if ss != old_ss_blue then
B_PWM=B_PWM-1
old_ss_blue=ss
endif
endif
if B_PWM = B_MIN then
Blue_Day_Cycle = NIGHT
endif
case NIGHT
lcdout $FE,$80+15,"NIGHT"
B_PWM=B_min
end select
'*******************************************************************************
'WHITE daily cycle
select case White_Day_Cycle
case DAWN
lcdout $FE,$C0+15,"DAWN "
if ss//white_delay_in= 0 then
if ss != old_ss_white then
W_PWM = W_PWM+1
old_ss_white=ss
endif
endif
if W_PWM = W_max then
White_Day_Cycle = DAY
endif
case DAY
lcdout $FE,$C0+15,"DAY "
if W_max < W_PWM then
W_PWM=W_PWM - 1
endif
if counter1 =white_off_time then
White_day_cycle = DUSK
endif
CASE DUSK
lcdout $FE,$C0+15,"DUSK "
if ss//white_delay_out= 0 then
if ss != old_ss_white then
W_PWM=W_PWM-1
old_ss_white=ss
endif
endif
if W_PWM = W_min then
White_Day_Cycle = NIGHT
endif
case NIGHT
lcdout $FE,$C0+15,"NIGHT"
W_PWM=W_min
end select
'*******************************************************************************
'tidy up the display for the current percentage to remove stray zero's
If (B_PWM * 100)/255 = 100 then
lcdout $FE,$80,"BL ",$FE,$80+3,dec3 (B_PWM *100)/255,"%"
endif
If (B_PWM * 100)/255 =0 or (B_PWM * 100)/255 <10 then
lcdout $FE,$80,"BL ",$FE,$80+3,dec1 (B_PWM *100)/255,"% "
endif
if (B_PWM * 100)/255 >=10 and (B_PWM * 100)/255 <100 then
lcdout $FE,$80,"BL ",$FE,$80+3,dec2 (B_PWM *100)/255,"% "
endif
If (W_PWM*100)/255 >= 100 then
lcdout $FE,$C0,"WT ",$FE,$C0+3,dec3 (W_PWM *100)/255,"%"
endif
If (W_PWM * 100)/255 <=0 or (W_PWM * 100)/255 <10 then
lcdout $FE,$C0,"WT ",$FE,$C0+3,dec1 (W_PWM *100)/255,"% "
endif
if (W_PWM * 100)/255 >=10 AND (W_PWM * 100)/255 <100 then
lcdout $FE,$C0,"WT ",$FE,$C0+3,dec2 (W_PWM *100)/255,"% "
endif
'*******************************************************************************
'Get and display the temperature
OWOUT DQ, 1, [$CC, $44] ' Start temperature conversion
OWOUT DQ, 1, [$CC, $BE] ' Read the temperature
OWIN DQ, 0, [temperature.LOWBYTE, temperature.HIGHBYTE]
temperature = temperature */ 1600
lcdout $FE,$D4+0,"TEMP ",DEC(temperature / 100),$DF,"C"
'*******************************************************************************
'generate bar graph on LCD
; syntax- BARgraph Value, Row, Col, Width, Range, Style
@ BARgraph _B_PWM, 1, 8, 6, 255, lines
@ BARgraph _W_PWM, 2, 8, 6, 255, lines
GOTO Main
Darrels code seems to allow frequencies of 100hz which makes this ideal.... if it can be made to work
Bookmarks