PDA

View Full Version : Setting the time in rtc with buttons



supermoose
24-12-2012, 11:00
I have a ds1391 rtc, a 28x2 and a serial lcd. I have a program that can read the time and show it on the lcd but I can't figure out how to set the time with some buttons. I want to have one button to advance the hours and another to advance the minutes.

Can anyone help me with this??

Here is my code it it helps


hspisetup spimode01, spimedium

main:

low 6 ;seconds
hspiout ($01)
hspiin (b0)
high 6
pause 5


bcdtoascii b0,b1,b2



low 6 ;mins
hspiout ($02)
hspiin (b3)
high 6
pause 5

bcdtoascii b3,b4,b5

low 6 ;hours
hspiout ($03)
hspiin (b6)
high 6

bcdtoascii b6,b7,b8

low 6 ;milliseconds
hspiout ($00)
hspiin (b9)
high 6

bcdtoascii b9,b10,b11


serout 7 ,T9600_8,($FE,$47,3,1) ;set screen to 2 blocks in
serout 7 ,T9600_8,(b7,b8)
serout 7 ,T9600_8,(":")
serout 7 ,T9600_8,(b4,b5)
serout 7 ,T9600_8,(":")
serout 7 ,T9600_8,(b1,b2)
serout 7 ,T9600_8,(":")
serout 7 ,T9600_8,(b10,b11)


Thanks for any help.

westaust55
24-12-2012, 11:10
Welcome to the PICAXE forum.

While I do not have a solution to hand this topic has been discussed before if you were to do a forum search.
In this thread there is a part solution provided by forum member mrburnette at post 9: http://www.picaxeforum.co.uk/showthread.php?20436-Real-Time-Clock-in-PICAXE-hardware

Noted that your clock is SPI based (not i2c) but it is the concept on what to do that counts.

The DS1391 datasheet can be found here: http://datasheets.maximintegrated.com/en/ds/DS1390-DS1394.pdf
The register values are still BCD encoded so the concept needs to be to read in the data from the RTC, convert to decimal values, make the adjustments, convert back to BCD and then write back to the RTC.

TAMeyer
25-12-2012, 00:39
SM:

I am working on the same concept as you.
The code attached presents one manner in which this can be done. That is using pushbuttons like those found on an alarm clock.

The code runs fine in the simulator as far as selecting a time, and storing it to local EEPROM.

It lacks:
proper commenting
polished commands for the LCD
commands to write the info to the clock.

But as “westaust55” said, it is the concept you are after.

Good Luck and Merry Christmas,

Terry



{

#rem
{
V5
V4 CleanUp
V3 Switched to 14M2
V2 Renamed pushbuttons
V2 Removed "marks" references to LED
V1 Basic mish mash


The pgm allows an user to set the time in a picaxe project
just as they would with an alarm clock


Three pushbuttons (PB)

Up arrow
Down arrow
Round button for set routine

#endrem

#Picaxe 14M2

SETFREQ M16


}

EEPROM 08,(0,0) 'Write "0" into the Hours default EEPROM address
EEPROM 09,(0,0) 'Write "0" into the Mins default EEPROM address
EEPROM 10,(0,0) 'Write "0" into the Secs default EEPROM address

SYMBOL PB_UP = PINC.2
SYMBOL PB_DN = PINC.1
SYMBOL SetButton = PINC.0

SYMBOL LCD = C.4

Symbol SCL = PINB.3
Symbol SDA = PINB.4

Symbol ProgPrompt = B1 'Reused VAR, Acts as a type of flag if a button is
'held down too long
Symbol Thresh = B2 'Threshhold for ProgPrompt


SYMBOL hours = B10
SYMBOL mins = B11
SYMBOL secs = B12




'LET dirsc = %00000000

Let ProgPrompt = 0
Let Hours = 0
Let Mins = 0
Let Secs = 0




Main:



Gosub ShouldTimeBeSet



Goto Main

'--------------------------------------------------------------------------------------------------
{
ShouldTimeBeSet:

Do
If SetButton = 1 THEN Inc ProgPrompt : EndIf
If ProgPrompt > Thresh THEN GoSub SetTime
Pause 100
Loop While SetButton = 1
Return
}
'--------------------------------------------------------------------------------------------------
SetTime:
{

Gosub SetHours
Gosub SetMins
Gosub SetSecs
Gosub SettingDone
}
End

'--------------------------------------------------------------------------------------------------
SetHours:
{ GoSub ReleaseSetButton

Let Hours = 0

Do
If PB_UP = 1 Then Inc Hours : EndIf
If Hours > 23 Then Let Hours = 0 : EndIf


If PB_DN = 1 Then Dec Hours : EndIf
If Hours = 255 Then Let Hours = 23 : EndIf

SerOut LCD,T9600_16,("Hours = ",#hours) ; transmit value to serial LCD
SerOut LCD,T9600_16,("Press Set When Done") ; transmit value to serial LCD

Loop While SetButton = 0

Write 08,Hours
Pause 60
Return
}
'--------------------------------------------------------------------------------------------------
SetMins:
{ GoSub ReleaseSetButton

Let Mins = 0

Do
If PB_UP = 1 Then Inc Mins : EndIf
If Mins > 59 Then Let Mins = 0 : EndIf


If PB_DN = 1 Then Dec Mins : EndIf
If Mins = 255 Then Let Mins = 59 : EndIf

SerOut LCD,T9600_16,("Mins = ",#Mins)
SerOut LCD,T9600_16,("Press Set When Done") ; transmit value to serial LCD


Loop While SetButton = 0

Write 09,Mins
Pause 60

Return
}
'--------------------------------------------------------------------------------------------------
SetSecs:
{ GoSub ReleaseSetButton

Let Secs = 0

Do
If PB_UP = 1 Then Inc Secs : EndIf
If Secs > 59 Then Let Secs = 0 : EndIf


If PB_DN = 1 Then Dec Secs : EndIf
If Secs = 255 Then Let Secs = 59 : EndIf

SerOut LCD,T9600_16,("Secs = ",#Secs)
SerOut LCD,T9600_16,("Press Set When Done") ; transmit value to serial LCD

Loop While SetButton = 0

Write 10,Secs
Pause 60

Return
}
'--------------------------------------------------------------------------------------------------

'--------------------------------------------------------------------------------------------------
'--------------------------------------------------------------------------------------------------
ReleaseSetButton: 'Is the user holding the button too long?
{ Let ProgPrompt = 0
Do
If SetButton = 1 Then Inc ProgPrompt : EndIf
If ProgPrompt > Thresh Then Gosub DisplayReleaseWarning

Loop While SetButton = 1
Let ProgPrompt = 0
Return
}
'--------------------------------------------------------------------------------------------------
DisplayReleaseWarning:

SerOut LCD,T9600_16,("Release the Set",13)' transmit value to serial LCD
SerOut LCD,T9600_16,("button to continue")


Return
'--------------------------------------------------------------------------------------------------
SettingDone:
GoSub ReleaseSetButton


SerOut LCD,T9600_16,("Time = ",#hours,":",#mins,":",#Secs,13,10) 'transmit value to serial LCD

pause 20000
Return

'--------------------------------------------------------------------------------------------------

doggington
06-01-2013, 17:00
Hi guys
Have been trawling the forum to find the code posted above to help in a project posted under "using DS1307 with picaxe 18m2".

I think I can adapt it to make it work in my project but a couple of questions...
if I want to add. Date month and year do I pick any EEPROM say 1,2,3, or 11,12,13, ( I note in the comment line "Default eeprom address" ) is this set by some standard or by whoever is programming?).
I am guessing I could use similar lines as in the settime or sethours part to add in a series of event times ( i need 5 or 6 in 24hrs).
having set the time and date etc using the code does the rtc(ds1307) take over or have I missed something?
sorry if this is mundane or stupid but my programming knowledge is very limited, I generally have to find code already written and then try to make it work for me.
many thanks

nick12ab
06-01-2013, 17:10
if I want to add. Date month and year do I pick any EEPROM say 1,2,3, or 11,12,13, ( I note in the comment line "Default eeprom address" ) is this set by some standard or by whoever is programming?).it is set by the programmer.


I am guessing I could use similar lines as in the settime or sethours part to add in a series of event times ( i need 5 or 6 in 24hrs).
having set the time and date etc using the code does the rtc(ds1307) take over or have I missed something?The DS1307 takes over with the time and date, but it won't do your events.

oracacle
06-01-2013, 17:22
how many button are you going to use, i have just built a clock that makes use of 2 botton, but only cycles the time, date, month and year upwards and displays it on 4x 7 segment displays. this code does work on my clock. hope it can of help.

the code takes into account leap years, so it can be programmed on the 29 of feb too
i cant answer you question as i have never used the clock module.

this is a sup-proccedure and is called from the main programme.


setmins:
gosub show
if porta pin0 = 1 then ;check for user incrementing mins
let mins = mins + 1 ;increment mins if needed
if mins > 59 then ;check for overflow
let mins = 0 ;reset in case of overflow
endif
let mten= mins /10 ;set variables for display
let munit = mins //10
let hten = hour /10
let hunit = hour //10
gosub look
endif
if porta pin1 = 0 then goto setmins ;check for user input, continue to hours
pause 150

sethours:
gosub show
if porta pin0 = 1 then ;check for user input
let hour = hour + 1 ;add 1 hour
if hour > 23 then ;check for overflow
let hour = 0 ;reset if overflow occours
end if
let hten = hour /10 ;set variables for display
let hunit = hour //10
let mten= mins /10
let munit = mins //10
gosub look
endif
if porta pin1 = 0 then goto sethours ;check for iser input
pause 150
gosub lookday
let tempbyte = 40 ;set variable to remove deciaml place

setdays:
gosub show
if porta pin0 = 1 then ;check for user input
let days = days + 1 ;add 1 day
if days > 6 then ;check for over flow
let days = 0 ;reset if overflow occours
end if
gosub lookday
end if
if porta pin1 = 0 then setdays ;check for user input
let days = days + 1 ;correct for writing to DS1307
pause 150

let hten = 2
let hunit = 0
let mten = year/10
let munit = year//10
gosub look

setyear:
gosub show
if porta pin0 = 1 then
let year = year + 1
if year > 99 then
let year = 00
end if
let hten = 2
let hunit = 0
let mten = year/10
let munit = year//10
gosub look
end if

if porta pin1 = 0 then goto setyear

'put date variable into display variables
let hten = date/10
let hunit = date//10

let mten = month/10
let munit = month //10
gosub look
gosub show
let tempbyte = 0

setmonth:
gosub show
if porta pin0 = 1 then
let month = month + 1
if month > 12 then
let month = 1
end if
let mten = month /10
let munit = month //10
let hten= date /10
let hunit = date //10
gosub look
endif
if porta pin1 = 0 then goto setmonth
pause 150

setdate:
gosub show
if porta pin0 = 1 then
let date = date + 1
let tempbyte = month -1 ;correct month for lookup table
lookup tempbyte, (31,28,31,30,31,30,31,31,30,31,30,31),tempbyte ;lookup days in each month
if month = 2 then ;check for feburary
#rem
research showed the all leap years when divided by 4 were whole numbers, as the picaxe can not make use
of deicimal place, shifting the decimal place by multipling by 10 and finding the remainder of divideing
the result by 4 the piacxe can use a simple if statement to dtermine leap years and thus how many days
in the second month
#endrem
let tempyear = year *10 ;x10
let tempyear = tempyear//4 ;find remainder of dividing by 4
if tempyear = 0 then ;if the answer is 0, then its a leap year
tempbyte = 29 ;set number of day to 29
end if
end if
if date > tempbyte then
let date = 1
end if


let hten= date /10
let hunit = date //10
let mten = month /10
let munit = month //10
gosub look
endif
if porta pin1 = 0 then goto setdate
pause 150

write_time:
gosub bcd 'goto sub procedure
i2cslave %11010000, i2cslow,i2cbyte
writei2c 0, (secs,mins,hour,days,date,month,year,$10) 'write data to clock
pause 1000 'wait while data is writen

reset

doggington
06-01-2013, 17:31
Thanks for that!
I have managed to get the picaxe to react to various times set in the program. So now want to set those times with the buttons once that is done the whole thing becomes autonomous.
buttons havn't arrived yet though.

doggington
06-01-2013, 17:43
sorry oracacle your reply was posted in between mine.
thank you, I was planning 3 buttons Set, Up and Down. I usually manage to go too far when setting times etc!!
when the buttons arrive I will try your code. Setting for leap year makes it even more autonamous.