PDA

View Full Version : RTC - Strange readings



Scampy
- 28th November 2015, 17:26
Hi guys, I'm running a DS1307 and have experienced some strange jumps in time that has been replicated by a friend using his own development board. When the system is first powered up the clock displays the default time of 14:00, and runs ok until 15:59. When it rolls over to 16:00 it actually jumps to 08:00 and then continues to run Ok displaying 08:01, 08:02 etc. If after power up I set the time to 15:59 using the option in the menu it correctly displays 16:00 16:01 etc without issue. Equally, when it is powered up, displays 14:00 and trips to 08:00, if left to run on for 8 hours, it correctly displays 16:00 when the time has elapsed.

Here's are the time variables



;----[Variables/Aliases - Time]------------------------------------------

RTCSec var byte ' Seconds
RTCMin var byte ' Minutes
RTCHour var byte ' Hours
RTCWDay var byte ' Weekday
RTCDay var byte ' Day
RTCMonth var byte ' Months
RTCYear var byte ' Year
RTCCtrl var byte ' Control
SetTime var byte ' 12/24 Hour Clock
SetSec var byte ' Seconds
SetMin var byte ' Minutes
SetHour var byte ' Hours

TimeOut var word ' Variable for SetUp Menu Time-Out
TimeH var byte ' Variable to store current hour for comparison to drop temp time
TimeM var Byte ' Variable to store current minutes for comparison to drop temp time


And then I have this initial setting



RTCSec=0
RTCMin=0
RTCHour=14

I2CWrite SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour,RTCWDay,RTCDay,RTCMonth,RTCY ear,RTCCtrl]


And then this is the section in the main loop that reads the chip and displays the time



I2CRead SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour,RTCWDay,RTCDay,RTCMonth,RTCY ear,RTCCtrl] ; read DS1307 chip
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,$c0+11,#CounterA
else
LCDOut $FE,$c0+11,#CounterA Dig 1,#CounterA Dig 0
endif
LCDOut ":",#(RTCMin>>4)&$0F,#RTCMin&$0F

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


And finally here's the section that deals with manually setting the time from the menu



time:

LCDOUT $FE,1
LCDOUT $FE,2,"Set Time"

inp3:

IF H_butt = 0 THEN GOSUB IncHours
IF M_butt = 0 THEN GOSUB IncMinutes
SetHour=Hours
SetMin=Minutes

LCDOUT $FE,$C0,#SetHour DIG 1,#SetHour DIG 0,":",#SetMin DIG 1,#SetMin DIG 0
pause 200
If S_butt = 0 then
pause 250
goto savetime
endif
goto inp3


savetime:
' Save 12/24 Hours to BCD DS1307's Format
' ---------------------------------------
CounterA=SetHour
If SetTime=1 then
If CounterA>12 then CounterA=CounterA-12
If CounterA=0 then CounterA=12
endif
Gosub ConvertBCD
RTCHour=CounterB
' Save the Hours Value
If SetTime=1 then
RTCHour.6=1
' Save the 12 Hour Mode Flag
If SetHour=>12 then RTCHour.5=1
' Save the 'PM' Flag
endif
'
' Save Minutes
' ------------
CounterA=SetMin
Gosub ConvertBCD
RTCMin=CounterB

CounterA=SetSec
Gosub ConvertBCD
RTCSec=CounterB

I2CWrite SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour,RTCWDay,RTCDay,RTCMonth,RTCY ear,RTCCtrl]

goto mainmenu


I'm at a loss ? - any suggestions

SUNFLOWER
- 29th November 2015, 02:33
I use DS1307 a lot and it must be super reliable for years, otherwise concentrator sunlight could start fires or melt rocks. I have not read your code but have experience strange RTC behavior and have found solutions. Dirty power on/off/on can corrupt time. That was solved with BAT85 diode and 0.1 uF cap. See schematic (lower left) at http://www.harbornet.com/sunflower/PCB.jpg.

The clock is read about 10 times per second. And the time is reset once per day at solar noon when azimuth is due south. Only once in four years the clock indicated an accidental reset or read error. Then the code was updated for error trapping to set flags for ground protection. Now the clock is read twice per main loop and if the time is different it is read twice again. Also if the time does not change in little more than one second then RTC fail is flagged. The RTC has since been 100% for 6 years -- zero fails and zero flags.

Search for "Get_Time:" in this code http://www.harbornet.com/sunflower/PCB.pbp

--Doug

Art
- 29th November 2015, 12:21
Hi, Having a DS1307 with square wave output, you can be pretty sure if pin 7 will flash an LED at 1Hz it’s working,
then only a battery backup to retain the time that was set, and to not cause any shorts.

It’s been a while since I used a DS1307, but I’d start by assuming the chips are ok. Is the other board running same or similar code?
One way to go about finding the problem might be to make a throw away copy of the program that for every signal from pin 7 of the DS1307,
displays the time, increments the time, writes it to the chip, reads it back, and displays it again.

Scampy
- 29th November 2015, 12:49
Thanks guys for your comments.

I still haven't got to the bottom as to why the display jumps to 08:00 when turning 16:00 when powered up, but won't do it when the time is set manually to something like 15:58.

I've browsed through my other snippets of code for RTC and came up with this.



DB0 var byte[8]
CMCON = %00000111 ' Comparators = off
gosub write_1307
read_1307: ' Read time Secs,Mins,Hours,Day,Date,Month,Year,Control
I2CREAD SDA,SCL,$D1,$00,[STR DB0\8] ' Read 8 bytes from DS1307

lcdout $fe,1,"Time=",hex2 DB0[2],":",hex2 DB0[1],":",hex2 DB0[0] 'bit 0=sec, bit 1=min, bit 2=hrs
lcdout $fe,$c0,"Date=",hex2 DB0[4],":",hex2 DB0[5],":",hex2 db0[6] 'bit 4=day, bit 5=month, bit 6=year
goto read_1307
end

Write_1307: ' Set time & date to 19:00:00 14th Feb 201
I2CWRITE SDA,SCL,$D0,$00,[$00,$00,$19,$7,$14,$2,$10,$90] ' Write to DS1307
pause 10
RETURN ' Sec Min Hr Day D M Y Control


This worked a treat and seems a better way than having all the BCD conversion code that other examples used, and I've used in my current project. However I want to be able to use variables to set the time so I tried substituting [$00,$00,$19,$7,$14,$2,$10,$90] for [RTCSec,RTCMin,RTCHour,RTCDay,RTCMonth,RTCYear,$90] and then have the following to set the hrs and mins and copy them to the RTC variables



LCDOUT $FE,1
LCDOUT $FE,2,"Set Time"

inp3:

IF H_butt = 0 THEN GOSUB IncHours
IF M_butt = 0 THEN GOSUB IncMinutes
SetHour=Hours
SetMin=Minutes

LCDOUT $FE,$C0,#SetHour DIG 1,#SetHour DIG 0,":",#SetMin DIG 1,#SetMin DIG 0
pause 200
If S_butt = 0 then
pause 250
goto savetime
endif
goto inp3


savetime:


RTCmin = setmin
rtchour = sethour
gosub Write_1307


Write_1307: ' Secs,Mins,Hours,Day,Date,Month,Year,Control
I2CWrite SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour,RTCDay,RTCMonth,RTCYear,$90]
pause 10
RETURN


The original example has the following to read the DS1307 and display the second and 1st bytes for the time



I2CREAD SDApin,SCLpin,$D1,$00,[STR DB0\8] ' Read 8 bytes from DS1307 Secs,Mins,Hours,Day,Date,Month,Year,Control

LCDOut $FE,$c0+11,hex2 DB0[2],":",hex2 DB0[1]


This worked fine when the values for the time and date etc were stored a $10,$30 etc, but when I used the RTChour and RTCmin variables the LCD displays 0A:1E when RTCHour=10 and RTCMin=30 for example. I'm sure it's a classic noob error, but for the life of me I can't see what I need to do to store the values for these variables in the I2Cwrite statement, and then read them back and display them correctly on the screen.

SUNFLOWER
- 29th November 2015, 20:25
Perhaps this will help. Note input time number in hex --

hserin [hex2 wb1]


Clock_set:

GOSUB GET_TIME

hserout [ "0 second ",hex sec,13,10]
hserout [ "1 minute ",hex minute,13,10]
hserout [ "2 hour ",hex hour,13,10]
hserout [ "3 day ",hex day,13,10]
hserout [ "4 date ",hex date,13,10]
hserout [ "5 month ",hex month,13,10]
hserout [ "6 year ",hex year,13,10]
hserout [ "7 reset ",13,10]
hserout [ "8 exit ",13,10]
hserin [dec1 wb]

IF wb = 7 THEN reset
if wb > 7 then keypad

hserout [10,13,DEC wb," value? "]
hserin [hex2 wb1]
HSEROUT [13,10,10]

I2Cwrite datapin, clockpin, $d0, wb, [wb1] ' Set Clock
goto clock_set

RESET:
FOR smooth = 7 TO 0 ' Clear Clock DS1307 clock reset and start crystal
I2Cwrite datapin, clockpin, $d0, smooth, [0] ' Run when backup battery replacement
NEXT

SUNFLOWER
- 29th November 2015, 22:37
rtchour = sethour

If sethour is 12 noon then rtchour must be a hex value that creates the digits 12

Scampy
- 30th November 2015, 07:30
Just an update.

Seems that the issue was caused by the interrup driven coms - The code checks the Usart to see if anything is received in the buffer, and as the RX pin was left floating it seems that this was picking up noise etc and causing it to trip / fall over. I tied this to +5 via a 27k resistor and it works fine on both easypic5 and PCB