PDA

View Full Version : using DS1307



Scampy
- 28th November 2013, 13:37
Following on from my previous threads, the current code for my aquarium controller has been running without issue for the past three days, and has been keeping time very well considering it uses a timer overflow rather than a dedicated time chip like the DS1307 (which the previous version used and kept issuing 10:10:10:10 as the time etc). My new code uses a variable to store a value based on minutes since midnight, and then logic statements are used to determine the phase of the lights (ramp up, on ramp down). This works really well, but as the code is using the internal timers to overflow, the main program loop must be less than the overflow timing, otherwise the clock looses time.

The alternative is to use a DS1307, and but still do the conversion into minutes since midnight as that has proven to be more reliable than doing direct comparison to matching time in Hrs and Min format. However I only really need the HH:MM segment of the time, and I know that the DS1307 has a long string of info stored that includes month, day, year etc. What would be the best way to write / read the DS1307 so that it only gives the hours and minutes and nothing else.

This way if I add features which would otherwise delay the cycle and cause the clock to loose time, with the reading of the DS1307 the counter would still be correct.

The idea is



Counter1 variable word

Read DS1307 to get hours and minutes
Counter1 = (Hours * 60) + minutes

Do logic of if on time >= counter1 then do something etc

Amoque
- 28th November 2013, 15:22
The DS1307 keeps each time "segment" in separate registers, you may read only those you need by standard I2C. From the data sheet, the registers you require are 01H and 02H - minutes and hours respectively. The difficulty is only that the values are stored in BCD format. You may work with them directly, but I find it more intuitive to convert them to decimal, so that every calculation may be done with decimal result.

Below is a snippet from my recent work that reads ALL the DS1337 registers (I am sure they are the same, but '37 is without battery backup) and decodes them to the Debug for verification. You may use the entire code segment or, change the REG_TIM variable to match the first register you require, then collect only two values (as [ MIN, HR]). Also, abbreviate the loop (LP).

SDA/ SCL = PIN DESIGNATIONS, RTC_ADD = ADDRESS, REG_TIM = BEGINNING REGISTER TO READ, REG_VAL[X] = BCD register value from chip.

I2CRead SDA, SCL, RTC_ADD, REG_TIM, [REG_VAL[0], REG_VAL[1], REG_VAL[2], REG_VAL[3], REG_VAL[4], REG_VAL[5], REG_VAL[6]]
FOR LP = 0 TO 6 ' For each register
D0 = (REG_VAL[LP] >> 4) * 10 ' Decode 10's digit
D1 = REG_VAL[LP] & %0001111 ' Blank 10's, get 1's
REG_VAL[LP] = D0 + D1 ' Write Decimal value to register
NEXT LP ' Next register

DEBUG "TIME:[", dec1 REG_VAL[3], "] ", dec2 REG_VAL[5], "/", dec2 REG_VAL[4], "/", dec2 REG_VAL[6], " ", dec2 REG_VAL[2], ":", dec2 REG_VAL[1], ":", dec2 REG_VAL[0], 10

Debug should print TIME:[DOW] MO/DAY/YR HR:MN:SC and each REG_VAL[X] should contain the decimal value of the segment indicated.

At this point, then... Multiply HR * 60 + MN. Of course I (elsewhere) set my clock to 24 hour mode - or also read the AM/PM bit and add 12 hours as required.

Scampy
- 28th November 2013, 15:35
Thanks for the info.

From a previous example I have:



I2CRead SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour,RTCWDay,RTCDay,RTCMonth,RTCY ear,RTCCtrl] ; read DS1307 chip


My question is would I need to read every bit or could I get away with



I2CRead SDApin,SCLpin,$D0,$00,[,RTCMin,RTCHour,,,,,] ; read DS1307 chip


How would I get it to ignore the first bit (rtcsec) accept the next two bits and ignore the rest... or doesn't it work that way ?

Amoque
- 28th November 2013, 15:51
You need not read any that you do not require.

I2CRead SDApin,SCLpin,$D0,$01,[,RTCMin, RTCHour] ; read DS1307 chip

Will begin reading at register $01 (note change I made to your code) and collect two registers in the variables (RTCMin, RTCHour) you provided. Like that you have BCD minutes and hours.

Also, remove the leading comma in the variable list as: [RTCMin, RTCHour]

Scampy
- 28th November 2013, 16:05
Cheers - Between our replies I found that I could do as you suggested, although I didn't know about the $01 address part. I assume where I had $00 the is the RTCSec bit, so using the $01 tells the code to read from the second bit (RTCMIN) ?

Thanks for your help

Amoque
- 28th November 2013, 16:14
Yes, but understand only that where you use the word "bit" is actually a byte. $00 is "%00000000", $01: "%00000000" ... like that. It is how you can read and write the AM/PM bit and read Status bits to verify the clock is running:

IF RTCHour.6 = 0 then 24H mode enabled.

Enjoy...

Scampy
- 28th November 2013, 17:01
Hi,

Thanks for your help... The following code works fine for just hours and minutes.

Posted here for reference should anyone else need this.

18F4520 - running with a 20mhz crystal - 4x20 LCD




ASM
__CONFIG _CONFIG1H, _OSC_HSPLL_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

DEFINE OSC 48 ; config settings 18F4580, 20mhz crystal
ADCON1 = $0F
clear

RTCMin var byte ' Minutes
RTCHour var byte ' Hours
RTCCtrl var byte ' Control

SCLpin var PORTC.3 ' RTC pin - clk
SDApin var PORTC.4 ' RTC pin - data

Hours var byte
Minutes var byte

CounterA var byte ' General purpose Variable
CounterB var byte ' General purpose Variable
CounterC var byte ' General purpose Variable
CounterD var byte ' General purpose Variable

SetMN var byte ' Minutes
SetHR var byte ' Hours


'analog settings

ADCON0 = 0 'Set ADCON0
ADCON1 = %00001111 'Set D i/o
CMCON = 7 'Disable Comparators

PR2 = 249
'************************************************* ***************
'Port settings

CCP1CON = %00001100 '
CCP2CON = %00001100 '
TRISA = %11101111 'set PORTA as all output apart from 0,1,2
TRISB = %00000011
TRISD = %00000011 'set PORTB as all output apart from 0&1
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

setHR = 12
setMN = 01

' Save Minutes
' ------------
CounterA=SetMN
Gosub ConvertBCD
RTCMin=CounterB
'
' Save Seconds
' ------------
CounterA=SetHR
Gosub ConvertBCD
RTCHour=CounterB

I2cwrite SDApin,SCLpin,$D0,$01,[RTCMin,RTCHour] ; read DS1307 chip

main:
I2CREAD SDApin,SCLpin,$D0,$01,[RTCMin,RTCHour] ; read DS1307 chip

LCDOut $FE,$80
If RTCHour.6=1 then

CounterA=(RTCHour>>4)&$01 ' Work-Out 12 or 24 hour Display for Hours
else
CounterA=(RTCHour>>4)&$03
endif
CounterA=CounterA*10+(RTCHour&$0F) ' Display Hours appropriately for 12 or 24 hour Mode
If RTCHour.6=1 then
LCDOut $FE,$D4,#CounterA
else
LCDOut $FE,$D4,#CounterA Dig 1,#CounterA Dig 0
endif
LCDOut ":",#(RTCMin>>4)&$0F,#RTCMin&$0F," "

Goto main
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



It's all rough and ready... now to convert the Hours and minutes into the value for a counter and try this in my next version of aquarium lighting :)

Thanks for your contribution - steep learning curve but I'm getting there :)

Scampy
- 28th November 2013, 18:14
OK, whilst the RTC is working fine with just reading and writing RTCHours and RTCMin, I'm having issues converting the time into minutes so I can use the variable Counter1 to store that value which is then used in the logic within my code to trigger case statements.

For example 14:00 hrs would equate to 840 minutes as the counter is reset to 00:00 at midnight. 14 * 60 = 840. 14:01 would thus be 841 etc

I've tried the following



If RTCHour.6=1 then

CounterA=(RTCHour>>4)&$01 ' Work-Out 12 or 24 hour Display for Hours
else
CounterA=(RTCHour>>4)&$03
endif
CounterA=CounterA*10+(RTCHour&$0F) ' Display Hours appropriately for 12 or 24 hour Mode
If RTCHour.6=0 then
LCDOut $FE,$D4,#CounterA
else
LCDOut $FE,$D4,#CounterA Dig 1,#CounterA Dig 0
endif
LCDOut ":",#(RTCMin>>4)&$0F,#RTCMin&$0F," "
MM=(RTCMin>>4)&$0F+RTCMin&$0F
Counter1 = (counterA*60)+MM


But using this 13:57 gives a value of 784, when it should be 837.... anyone have any suggestions ?

Scampy
- 28th November 2013, 22:00
OK guys I need some help here.

Here is the main part of the code which uses the timer overflow to generate the time, and from that derive the value for Counter1, which is then used to trigger the case statements and ramp up the lights, etc - This works. The percentages for the PWM are shown on the LCD and the case (Night, Dawn, Day and Dusk) all change depending on the logic.



'************************************************* ******************************
'clock routine

ClockLoop: IF intcon.2=0 THEN ClockLoop 'Poll for TMRO overflow
INTCON.2=0 'Clear TMRO overflow flag
HzTimer=HzTimer-$1000 'decrement timer count

IF HzTimer < $1000 THEN
IF Col=10 THEN 'update time'
SS=SS+1

IF SS=60 THEN ' minute
SS=0
MM=MM+1
IF MM=60 THEN ' hour
MM=0
HH=HH+1
IF HH=24 THEN HH=0
ENDIF
counter1 = (HH*60)+MM
ENDIF
ENDIF
Col=Col+1

HzTimer=HzTimer+$7A12 'Add 0.5 seconds to count
ELSE

ENDIF
if Col=11 then
Col=1
endif

LCDOut $FE,$D4,#HH DIG 1,#HH DIG 0,":",#MM DIG 1,#MM DIG 0

'************************************************* ******************************
'check what part of the cycle

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

'************************************************* ******************************
'*** Do BLUE daily cycle

select case Blue_Day_Cycle

case DAWN
lcdout $FE,$80+13,"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+13,"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+13,"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+13,"NIGHT"
B_PWM=B_min
end select

'************************************************* ******************************
'*** Do WHITE daily cycle

select case White_Day_Cycle

case DAWN
lcdout $FE,$C0+13,"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+13,"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+13,"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+13,"NIGHT"
W_PWM=W_min
end select

'************************************************* ******************************
'do the business of sending pulse to drivers

hpwm 1,W_PWM,200
hpwm 2,B_PWM,200

'************************************************* ******************************
'tidy up the display for the current percentage to remove stray zero's

If (B_PWM * 100)/255 = 100 then
lcdout $FE,$80,"BLUES ",dec3 (B_PWM *100)/255,"%"
endif

If (B_PWM * 100)/255 =0 or (B_PWM * 100)/255 <10 then
lcdout $FE,$80,"BLUES ",dec1 (B_PWM *100)/255,"% "
endif

if (B_PWM * 100)/255 >=10 and (B_PWM * 100)/255 <100 then
lcdout $FE,$80,"BLUES ",dec2 (B_PWM *100)/255,"% "
endif

If (W_PWM*100)/255 >= 100 then
lcdout $FE,$C0,"WHITES ",dec3 (W_PWM *100)/255,"%"
endif

If (W_PWM * 100)/255 <=0 or (W_PWM * 100)/255 <10 then
lcdout $FE,$C0,"WHITES ",dec1 (W_PWM *100)/255,"% "
endif

if (W_PWM * 100)/255 >=10 AND (W_PWM * 100)/255 <100 then
lcdout $FE,$C0,"WHITES ",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+11,"TEMP ",DEC(temperature / 100),$DF,"C"


GOTO Main



So all I did was to add in a few new variables for the RTC - and modify the line to display the counter to reflect the change of variables. This also works to a fashion, in that the time is displayed correctly and when the logic is met the case changes from NIGHT to DAWN at the correct set time. However the LEDs do not ramp up, and the values for Whites and Blues remain at zero percent. I've done nothing else to the code, certainly not with the case statements or the logic behind them.



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 light=1 then ' If the variable is 1 then output full PWM to lights
hpwm 1,255,200
hpwm 2,255,200
endif
If light=0 then ' If the variable is low then set value to 0 an turn off the lights
hpwm 1,0,200
hpwm 2,0,200
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,$01,[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)
timeM=(timeM &$07)*10
timeM=timeM+(RTCMin&$0F) 'convert the BCD format of the mins register and store in variable timeM

Counter1 = (TimeH *60)+ TimeM

LCDOut $FE,$D4,#TimeH DIG 1,#TimeH DIG 0,":",#TimeM DIG 1,#TimeM DIG 0

'************************************************* ******************************
'check what part of the cycle

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

'************************************************* ******************************
'*** Do BLUE daily cycle

select case Blue_Day_Cycle

case DAWN
lcdout $FE,$80+13,"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+13,"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+13,"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+13,"NIGHT"
B_PWM=B_min
end select

'************************************************* ******************************
'*** Do WHITE daily cycle

select case White_Day_Cycle

case DAWN
lcdout $FE,$C0+13,"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+13,"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+13,"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+13,"NIGHT"
W_PWM=W_min
end select

'************************************************* ******************************
'do the business of sending pulse to drivers

hpwm 1,W_PWM,200
hpwm 2,B_PWM,200

'************************************************* ******************************
'tidy up the display for the current percentage to remove stray zero's

If (B_PWM * 100)/255 = 100 then
lcdout $FE,$80,"BLUES ",dec3 (B_PWM *100)/255,"%"
endif

If (B_PWM * 100)/255 =0 or (B_PWM * 100)/255 <10 then
lcdout $FE,$80,"BLUES ",dec1 (B_PWM *100)/255,"% "
endif

if (B_PWM * 100)/255 >=10 and (B_PWM * 100)/255 <100 then
lcdout $FE,$80,"BLUES ",dec2 (B_PWM *100)/255,"% "
endif

If (W_PWM*100)/255 >= 100 then
lcdout $FE,$C0,"WHITES ",dec3 (W_PWM *100)/255,"%"
endif

If (W_PWM * 100)/255 <=0 or (W_PWM * 100)/255 <10 then
lcdout $FE,$C0,"WHITES ",dec1 (W_PWM *100)/255,"% "
endif

if (W_PWM * 100)/255 >=10 AND (W_PWM * 100)/255 <100 then
lcdout $FE,$C0,"WHITES ",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+11,"TEMP ",DEC(temperature / 100),$DF,"C"


GOTO Main



The strange thing is, I have a diagnostics option so on the press of a button I can scroll through all the main variables so I can check that they match what's expected. These are all showing correct values, especially those for the fade in and fade out.

I'm using the HPWM pins on the PIC (18f4520) which are on port C.1 and C.2. But whilst if there was a conflict of hardware that prevented the LEDs lighting, I would still of expected the LCD to show the increase in PWM values given by the fact the variables have values.

Comments please

Scampy
- 28th November 2013, 23:41
This has got me stumped....



'************************************************* ******************************
'clock routine

'ClockLoop: IF intcon.2=0 THEN ClockLoop 'Poll for TMRO overflow
'INTCON.2=0 'Clear TMRO overflow flag
'HzTimer=HzTimer-$1000 'decrement timer count

'IF HzTimer < $1000 THEN
'IF Col=10 THEN 'update time'
'SS=SS+1

'IF SS=60 THEN ' minute
'SS=0
'MM=MM+1
'IF MM=60 THEN ' hour
'MM=0
'HH=HH+1
'IF HH=24 THEN HH=0
'ENDIF
'counter1 = (HH*60)+MM
'ENDIF
'ENDIF
'Col=Col+1

'HzTimer=HzTimer+$7A12 'Add 0.5 seconds to count
'ELSE

'ENDIF
'if Col=11 then
'Col=1
'endif

'LCDOut $FE,$D4,#HH DIG 1,#HH DIG 0,":",#MM DIG 1,#MM DIG 0

I2CREAD SDApin,SCLpin,$D0,$01,[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)
timeM=(timeM &$07)*10
timeM=timeM+(RTCMin&$0F) 'convert the BCD format of the mins register and store in variable timeM

Counter1 = (TimeH *60)+ TimeM

LCDOut $FE,$D4,#TimeH DIG 1,#TimeH DIG 0,":",#TimeM DIG 1,#TimeM DIG 0


If I comment out everything in red and uncomment everything in green, the code works, in that at 14:00 hrs (Counter1 = 840) the case statement changes from NIGHT to DAWN and the brightness percentage increases and the LEDs start to brighten. If I uncomment everything in red and comment out everything in green, the case changes from NIGHT to DAWN at 14:00 hrs, Counter1 = 840 but the brightness remains at zero and the LEDs remain off.

Like I said, I could understand it if the brightness changed on the LCD but the LEDs remained off as this could point to a port config issue. But for it simply to ignore the values in the case statement and not work at all Its baffling and beyond me !

richard
- 29th November 2013, 05:13
you need to put the rtc seconds into your ss var , so the leds can ramp up/down

Scampy
- 29th November 2013, 08:01
Doh !!!

I obviously had spent too long looking at this screen...... that's obvious now you've pointed that out... All working now

Thanks Richard

richard
- 29th November 2013, 11:04
I hope your screen isn't green like your prev post , I nearly went blind trying to read your red and green sections

cheers richard

Amoque
- 29th November 2013, 13:11
It appears even fish have something to be thankful for on Thanksgiving!

As a younger man I kept tropical varieties and had the greatest joy from watching their antics. Reading through your code I imagine a very cool arrangement for lighting that simulates a cycle much more natural than my own habit of turning off the lights at bed time! I can hardly wait for version "2" of your software that incorporates the calendar for seasonal adjustments of daylight hours. Perhaps you think this will not happen, but I think it will - sometime. I recall that keeping fish compelled me always to "futz" with this and improve on that to make their environment more natural and realistic; I think your project shows you are the same? In fact, have you not also thought of the sensors that measure Ph and the devices (Peltier?) that might control heat and cool? Then there is dissolved oxygen, clarity, water level, feeding...

Congratulations on both the completed project and mastering the skills... I find nothing more satisfying than creation by my own hand; perhaps you are the same in this too?

Art
- 1st December 2013, 00:41
Another option, depending on real natural light available, is to have the pic learn the
real daylight cycle so you never have to set the clock.
This is what some solar controllers with auto night light output do to figure out when
to turn night lights on and off.
They are designed to use on remote toilet blocks and such, and would not be subject
to getting thrown off too much by the home lights being turned on and off.

SUNFLOWER
- 2nd December 2013, 02:23
I wrote a program for 18F4620 that reads time and date from DS1370 and then calculates sun position for users latitude, see Get_Path:

Code = http://www.harbornet.com/sunflower/PCB.pbp
Schematic = http://www.harbornet.com/sunflower/PCB.jpg

Time = number of minutes since midnight.

Art
- 2nd December 2013, 10:01
That's commendable.