DS1307: Incrementing time w/ NES controller

giuseppe

Member
Hey all again,

I am now at the point with my project that I need to write some basic "alarm clock functions". I would like to use the NES controller to increment hour and minutes. My plan was just to simply save a combination of bits (certain button presses), read this combination against possible outcomes, and jump to the code to react accordingly.

For my way, I wanted to use the combination %11011110 (down and A buttons are pressed) for incrementing the hour and %11011101 (down and B buttons are pressed) to increment the minutes. I will not decrement, just rollover the display back to zero by the use of code cases. After all this, write the new changed hour/minute on the DS1307 and then have it displayed.

I do manage to read the NES controller data just fine and the correct current time displays fine but I still cannot seem to get things incrementing (I am only trying the hours first). Here is my code for the incrementing part:

Code:
Read_NES_Controller:
pulsout neslatch,1		'latch the data into the NES controller's 4021
gosub Shiftin_LSB_Pre		'shift in the button data from the NES controller
let nesregister = var_in
'//Set Alarm 1
'//Set Alarm 2
'//Set ???????
'//Set Current Time
if nesregister = %11011110 then goto Set_Time_Hour'"down" and "A" are pressed
'if nesregister = %11011101 then goto Set_Time_Minute'"down" and "B" are pressed


Set_Time_Hour:
hi2cin 1,(minute,hour)	'obtain minute and hour information from DS1307

bcdtoascii hour,hourtens,hourones		'convert hour data to ascii
let hourtens    = hourtens - $30		'convert "hourtens" to decimal
let hourones    = hourones - $30		'convert "hourones" to decimal

if hour = $23 then goto Rollover	'if last hour of day is shown,roll up

select case hourones		'investigate hourones
	case < 9			'if ones place of hours is less than nine...
	 let hour = hour + 1    '...then add one to current hour
	case > 9			'if ones place of hours is more than nine...
	 let hour = hour + 6	'...then add six (hex remember?) to get "0"
endselect				'stop investigating
goto Done_Setting_Hour		'go to write to DS1307 new hour

Rollover:
let hour = $00			'hour was $23 so change to $00 (rollover)
goto Done_Setting_Hour		'go to write to DS1307 new hour

Done_Setting_Hour:
hi2cout 2,(hour)			'write to DS1307 new hour

loop
I am not worrying about optimization yet, I am just trying to see if I set time with the controller.
 

nick12ab

Senior Member
Code:
select case hourones		'investigate hourones
	case < 9			'if ones place of hours is less than nine...
	 let hour = hour + 1    '...then add one to current hour
	case > 9			'if ones place of hours is more than nine...
	 let hour = hour + 6	'...then add six (hex remember?) to get "0"
endselect				'stop investigating
This won't work because nothing will happen if the hourones = 9 and also hoursones should never be more than 9 so that second part won't work either.

You should first get the whole decimal number using Hippy's code, add one to that, then convert it back into BCD then send that to the DS1307.
 

giuseppe

Member
Code:
select case hourones		'investigate hourones
	case < 9			'if ones place of hours is less than nine...
	 let hour = hour + 1    '...then add one to current hour
	case > 9			'if ones place of hours is more than nine...
	 let hour = hour + 6	'...then add six (hex remember?) to get "0"
endselect				'stop investigating
This won't work because nothing will happen if the hourones = 9 and also hoursones should never be more than 9 so that second part won't work either.

You should first get the whole decimal number using Hippy's code, add one to that, then convert it back into BCD then send that to the DS1307.
Okay, I'll get back to ya when I try this out.
 

giuseppe

Member
Okay, revised code (and whole code for clarity):

Code:
'===============================================================================
'  EEPROM Data
'===============================================================================

'===============================================================================
'  Constants
'===============================================================================
symbol bits 	=     8	' number of bits
symbol MSBvalue   = 	128
' MSBvalue (=128 for 8 bits, 512 for 10 bits, 2048 for 12 bits)
symbol setsecond	=	$14	'set the current second here
symbol setminute	=	$45	'set the current minute here
symbol sethour	=	$20	'set the current hour here
symbol setday	=	$05	'set the current day here
symbol setdate	=	$01	'set the current data here
symbol setmonth	=	$03	'set the current month here
symbol setyear	=	$12	'set the current year here
symbol control	=	$10	'set the control here
symbol mode 	=	1	'MSB first, idle low
symbol ontime     =     30	'on time for one display digit
Symbol MINUS_6 	= 	$10000 - 6

'===============================================================================
'  Variables
'===============================================================================
symbol nesregister=	b0	'holds what second it is
symbol minute	=	b1	'holds what minute it is
symbol hour		=	b2	'holds what hours it is
symbol day		=	b3	'holds what day it is
symbol date		=	b4	'holds what date it is
symbol month	=	b5	'holds what month it is
symbol year		=	b6	'holds what year it is
symbol counter    =     b7	'variable used during loop
symbol hourtens   =     b8	'holds tens place of the hour
symbol hourones	=	b9	'holds ones place of the hour
symbol minutetens =     b10	'holds tens place of the minute
symbol minuteones	=     b11	'holds ones place of the minute
symbol var_out    =     w6	'data variable used during shiftout
symbol mask	      =     w7 	'bit masking variable
symbol var_in	=     w8
symbol temp		=     b16

'===============================================================================
'  Pin Declarations
'===============================================================================
'Inputs:
symbol nesdata = pinc.6

'Outputs:
symbol latch   = c.0	'latch pin for 74HC595
symbol sdata   = c.1	'serial data to feed into 74HC595(output pin for shiftout)
symbol sclk    = c.2	'clock for 74HC595 (output pin)

symbol neslatch= c.5
symbol nesclk  = c.7

symbol digit1  = b.0	'control pin for the hour's tens place
symbol digit2  = b.1	'control pin for the hour's ones place
symbol digit3  = b.2	'control pin for the minute's tens place
symbol digit4  = b.3	'control pin for the minute's ones place

'===============================================================================
'  Initialization
'===============================================================================
#picaxe 20x2     'place directive here
setfreq m64    'run internal oscillator @ 32MHz

#rem
Note:This portion of the program is only needed to program the current time and
     date. Uncomment this code for a fresh DS1307. If the DS1307 under test
     already has current time preloaded, leave the bottom code commented.
#endrem

Set_Time:
'hi2csetup i2cmaster,%11010000,i2cslow,i2cbyte	'paramters set,18M2 is master
'hi2cout 0,(setsecond,setminute,sethour,setday,setdate,setmonth,setyear,control)

'===============================================================================
'  Main
'===============================================================================
Read_Time: 
do

hi2csetup i2cmaster,%11010000,i2cslow_64,i2cbyte   'paramters set,18M2 is master
hi2cin 1,(minute,hour)		'obtain minute and hour information from DS1307
gosub Convert_Time_BCD_2_DEC		'convert hour and minute data to decimal
gosub Convert_Time_DEC_2_DISPLAY	'convert hour and minute data to display

Display_Time:
shiftout sclk,sdata,mode,(hourtens)		'display tens place of the minute
pulsout latch,1					'latch data out to display
low digit1						'turn on tens place of the hour
pause ontime					'pause a little
input digit1					'turn off tens place of the hour

shiftout sclk,sdata,mode,(hourones)		'display ones place of the hour
pulsout latch,1					'latch data out to display
low digit2						'turn on ones place of the hour
pause ontime					'pause a little
input digit2					'turn off ones place of the hour

shiftout sclk,sdata,mode,(minutetens)	'display tens place of the minute
pulsout latch,1					'latch data out to display
low digit3						'turn on tens place of the minute
pause ontime					'pause a little
input digit3					'turn off tens place of the minute

shiftout sclk,sdata,mode,(minuteones)	'display ones place of the minute
pulsout latch,1					'latch data out to display
low digit4						'turn on ones place of the minute
pause ontime					'pause a little
input digit4					'turn off ones place of the minute

Read_NES_Controller:
pulsout neslatch,1		'latch the data into the NES controller's 4021
gosub Shiftin_LSB_Pre		'shift in the button data from the NES controller
let nesregister = var_in	'load nesregister from subroutine
'//Set Alarm 1
'//Set Alarm 2
'//Set ???????
'//Set Current Time
if nesregister = %11011110 then goto Set_Time_Hour'"down" and "A" are pressed
'if nesregister = %11011101 then goto Set_Time_Minute'"down" and "B" are pressed

Set_Time_Hour:
hi2cin 1,(minute,hour)		'obtain minute and hour information from DS1307
gosub Convert_Time_BCD_2_DEC	'convert hour and minute data to decimal

if hour = 23 then			'hour is 23?
	let hour = 0		'if so then reset to zero
else 					'if not...
	let hour = hour + 1	'...then increment it by one
endif					'done deciding

Convert_Hour_DEC_2_BCD:
let hourtens = hour /  10     	'grab the tens place of the hour
let hourones = hour // 10		'grab the ones place of the hour
let hourtens = hourtens * 16		'shift tens place of hour to upper 4 bits
let hour = hourtens OR hourones	'OR hourtens w/ hournes; now hour in BCD

hi2cout 2,(hour)			'write to DS1307 new hour

loop

'===============================================================================
'  Sub-Routines
'===============================================================================
' ***** Shiftin LSB first, Data Pre-Clock *****
' Shift in the data LSB first into variable var_in 
' Read data before sending clock pulse 
' Using clock output pin sclk
' Using data input pin serdata 
Shiftin_LSB_Pre:
	let var_in = 0
	for counter = 1 to bits			' number of bits
		var_in = var_in / 2 		' shift right as LSB first	
		if nesdata = 0 then skipLSBPre
		var_in = var_in + MSBValue	' set MSB bit if serdata = 1
SkipLSBPre:
		pulsout nesclk,1 			' pulse clock to get next data bit
	next counter
	return
	
Convert_Time_BCD_2_DEC:
let hour = hour / 16 * MINUS_6 + hour
let hourtens = hour dig 1
let hourones = hour dig 0

let minute = minute / 16 * MINUS_6 + minute
let minutetens = minute dig 1
let minuteones = minute dig 0
return

Convert_Time_DEC_2_DISPLAY:
lookup hourtens ,(63,6,91,79,102,109,125,39,127,103),hourtens
lookup hourones ,(63,6,91,79,102,109,125,39,127,103),hourones
lookup minutetens ,(63,6,91,79,102,109,125,39,127,103),minutetens
lookup minuteones ,(63,6,91,79,102,109,125,39,127,103),minuteones
return
 

giuseppe

Member
I fixed some more and it works nice but are there any problems with it or things that can get improved in the setting time area?

Code:
'===============================================================================
'  EEPROM Data
'===============================================================================

'===============================================================================
'  Constants
'===============================================================================
symbol bits 	=     8	' number of bits
symbol MSBvalue   = 	128
' MSBvalue (=128 for 8 bits, 512 for 10 bits, 2048 for 12 bits)
symbol setsecond	=	$14	'set the current second here
symbol setminute	=	$45	'set the current minute here
symbol sethour	=	$20	'set the current hour here
symbol setday	=	$05	'set the current day here
symbol setdate	=	$01	'set the current data here
symbol setmonth	=	$03	'set the current month here
symbol setyear	=	$12	'set the current year here
symbol control	=	$10	'set the control here
symbol mode 	=	1	'MSB first, idle low
symbol ontime     =     30	'on time for one display digit
Symbol MINUS_6 	= 	$10000 - 6

'===============================================================================
'  Variables
'===============================================================================
symbol nesregister=	b0	'holds what second it is
symbol minute	=	b1	'holds what minute it is
symbol hour		=	b2	'holds what hours it is
symbol day		=	b3	'holds what day it is
symbol date		=	b4	'holds what date it is
symbol month	=	b5	'holds what month it is
symbol year		=	b6	'holds what year it is
symbol counter    =     b7	'variable used during loop
symbol hourtens   =     b8	'holds tens place of the hour
symbol hourones	=	b9	'holds ones place of the hour
symbol minutetens =     b10	'holds tens place of the minute
symbol minuteones	=     b11	'holds ones place of the minute
symbol var_out    =     w6	'data variable used during shiftout
symbol mask	      =     w7 	'bit masking variable
symbol var_in	=     w8
symbol temp		=     b16

'===============================================================================
'  Pin Declarations
'===============================================================================
'Inputs:
symbol nesdata = pinc.6

'Outputs:
symbol latch   = c.0	'latch pin for 74HC595
symbol sdata   = c.1	'serial data to feed into 74HC595(output pin for shiftout)
symbol sclk    = c.2	'clock for 74HC595 (output pin)

symbol neslatch= c.5
symbol nesclk  = c.7

symbol digit1  = b.0	'control pin for the hour's tens place
symbol digit2  = b.1	'control pin for the hour's ones place
symbol digit3  = b.2	'control pin for the minute's tens place
symbol digit4  = b.3	'control pin for the minute's ones place

'===============================================================================
'  Initialization
'===============================================================================
#picaxe 20x2     'place directive here
setfreq m64    'run internal oscillator @ 32MHz

#rem
Note:This portion of the program is only needed to program the current time and
     date. Uncomment this code for a fresh DS1307. If the DS1307 under test
     already has current time preloaded, leave the bottom code commented.
#endrem

Set_Time:
'hi2csetup i2cmaster,%11010000,i2cslow,i2cbyte	'paramters set,18M2 is master
'hi2cout 0,(setsecond,setminute,sethour,setday,setdate,setmonth,setyear,control)

'===============================================================================
'  Main
'===============================================================================
Read_Time: 
do

hi2csetup i2cmaster,%11010000,i2cslow_64,i2cbyte   'paramters set,18M2 is master
hi2cin 1,(minute,hour)		'obtain minute and hour information from DS1307
gosub Convert_Time_BCD_2_DEC		'convert hour and minute data to decimal
gosub Convert_Time_DEC_2_DISPLAY	'convert hour and minute data to display

Display_Time:
shiftout sclk,sdata,mode,(hourtens)		'display tens place of the minute
pulsout latch,1					'latch data out to display
low digit1						'turn on tens place of the hour
pause ontime					'pause a little
input digit1					'turn off tens place of the hour

shiftout sclk,sdata,mode,(hourones)		'display ones place of the hour
pulsout latch,1					'latch data out to display
low digit2						'turn on ones place of the hour
pause ontime					'pause a little
input digit2					'turn off ones place of the hour

shiftout sclk,sdata,mode,(minutetens)	'display tens place of the minute
pulsout latch,1					'latch data out to display
low digit3						'turn on tens place of the minute
pause ontime					'pause a little
input digit3					'turn off tens place of the minute

shiftout sclk,sdata,mode,(minuteones)	'display ones place of the minute
pulsout latch,1					'latch data out to display
low digit4						'turn on ones place of the minute
pause ontime					'pause a little
input digit4					'turn off ones place of the minute

Read_NES_Controller:
pulsout neslatch,1		'latch the data into the NES controller's 4021
gosub Shiftin_LSB_Pre		'shift in the button data from the NES controller
let nesregister = var_in	'load nesregister from subroutine
'//Set Alarm 1
'//Set Alarm 2
'//Set ???????
'//Set Current Time
if nesregister = %11011101 then goto Set_Time_Hour'"down" and "A" are pressed
if nesregister = %11011110 then goto Set_Time_Minute'"down" and "B" are pressed
goto Done

Set_Time_Hour:
pause 1000				'"debounce" time
hi2cin 1,(minute,hour)		'obtain minute and hour information from DS1307
gosub Convert_Time_BCD_2_DEC	'convert hour and minute data to decimal

if hour = 23 then			'hour is 23?
	let hour = 0		'if so then reset to zero
else 					'if not...
	let hour = hour + 1	'...then increment it by one
endif					'done deciding

Convert_Hour_DEC_2_BCD:
let hourtens = hour /  10     	'grab the tens place of the hour
let hourones = hour // 10		'grab the ones place of the hour
let hourtens = hourtens * 16		'shift tens place of hour to upper 4 bits
let hour = hourtens OR hourones	'OR hourtens w/ hourones; hour is in BCD

hi2cout 2,(hour)			'write to DS1307 new hour

Set_Time_Minute:
pause 1000				'"debounce" time
hi2cin 1,(minute,hour)		'obtain minute and hour information from DS1307
gosub Convert_Time_BCD_2_DEC	'convert hour and minute data to decimal

if minute = 59 then		'minute is 59?
	let minute = 0		'if so then reset to zero
else 					'if not...
	let minute = minute + 1	'...then increment it by one
endif					'done deciding

Convert_Minute_DEC_2_BCD:
let minutetens = minute /  10     	'grab the tens place of the minute
let minuteones = minute // 10		'grab the ones place of the minute
let minutetens = minutetens * 16	'shift tens place of hour to upper 4 bits
let minute = minutetens OR minuteones'OR minutetens w/ minuteones; minute is in BCD

hi2cout 1,(minute)			'write to DS1307 new hour
goto Done

Done:

loop

'===============================================================================
'  Sub-Routines
'===============================================================================
' ***** Shiftin LSB first, Data Pre-Clock *****
' Shift in the data LSB first into variable var_in 
' Read data before sending clock pulse 
' Using clock output pin sclk
' Using data input pin serdata 
Shiftin_LSB_Pre:
	let var_in = 0
	for counter = 1 to bits			' number of bits
		var_in = var_in / 2 		' shift right as LSB first	
		if nesdata = 0 then skipLSBPre
		var_in = var_in + MSBValue	' set MSB bit if serdata = 1
SkipLSBPre:
		pulsout nesclk,1 			' pulse clock to get next data bit
	next counter
	return
	
Convert_Time_BCD_2_DEC:
let hour = hour / 16 * MINUS_6 + hour
let hourtens = hour dig 1
let hourones = hour dig 0

let minute = minute / 16 * MINUS_6 + minute
let minutetens = minute dig 1
let minuteones = minute dig 0
return

Convert_Time_DEC_2_DISPLAY:
lookup hourtens ,(63,6,91,79,102,109,125,39,127,103),hourtens
lookup hourones ,(63,6,91,79,102,109,125,39,127,103),hourones
lookup minutetens ,(63,6,91,79,102,109,125,39,127,103),minutetens
lookup minuteones ,(63,6,91,79,102,109,125,39,127,103),minuteones
return
 

giuseppe

Member
I fixed some more and it works nice but are there any problems with it or things that can get improved in the setting time area?

Last clock I built I used IR to set the device, a $1 device from Dollar Tree. Here is the code, take anything you can use: http://www.picaxeforum.co.uk/entry.php?63-AXE133Y-Evolution-with-20X2-for-Display-12-hour-Clock-amp-Temperature

- Ray
Nice, I could use the AM/PM indicator code. I appreciate it!
 
Top