Help with a simple clock program

Post here to discuss programming with swordfish basic

Moderators: Chuckt, Garth, bitfogav

Post Reply
User avatar
odessa
I practically live here!
I practically live here!
Posts: 102
Joined: Thu Sep 09, 2010 6:06 am
Location: London

Help with a simple clock program

Post by odessa » Mon Mar 14, 2011 2:18 am

Hi Guys n Gals :)

Right .... I've been trying to get into Swordfish after using Proton and have been using the great code snippets from digital DIY to get to grips..

I was messing with the timer0 codes and decided to make a simple clock.

The problem I have is I am using two little sub routines to detect a button press to change hours and minutes. I need to delay the input or the hrs/minutes change way too fast. But !!!! if I add a small delay after the routine when you press and hold the button the timer stops working.

What n00b error am I making :lol: and is there a better way to delay a button press ? ( there is in proton, cant find one in Swordfish)

As usual any help greatly appreciated :)

Code: Select all

Device = 18F4520
Clock = 20

 
Dim
 mS As Word,
 count As Word,
 sec As Word,
 hr As Word,
 min As Word,    
TMR0ON As T0CON.7,    
T08BIT As T0CON.6,    
T0CS As T0CON.5,    
T0SE As T0CON.4,    
PSA As T0CON.3,    
TMR0IF As INTCON.2,    
TMR0 As TMR0L,    
TMR0IE As INTCON.5,    
TMR0_Event As Boolean


 

Interrupt TMR0_Interrupt()    
Save(0)                  // Backup system variables    
If TMR0IF = 1 Then       // Check if a TMR0 Interrupt occurred        
TMR0IF = 0           // Clear the interrupt        
Inc(mS, 1638)        // Increment the mS counter (scale of 1000)        
If mS >= 10000 Then  // Working with a scale of 1000, so this
count=count+1            
mS = mS - 10000  //  checks if 10mS has elapsed            
TMR0_Event = True        
EndIf    
EndIf                     
 Restore                  // Backup system variables
 
End Interrupt


Sub calctime()
If count=100 Then sec=sec+1
count=0
If sec=60 Then min=min+1
sec=0
If min=60 Then hr=hr+1
min=0
If hr=24 Then hr=0 
End If
End If
End If
End If
End Sub


Sub butaddmin()
If PORTA.4=0 Then min=min+1
delayms (100)
If min=60 Then min=0
End If
End If
End Sub


Sub hraddmin()
If PORTB.0=0 Then hr=hr+1
delayms (100)
If hr=24 Then hr=0
End If
End If
End Sub    




Sub TMR0_Initialize()
TMR0ON = 0               // Disable TMR0
T08BIT = 1               // Ensure TMR0 is working in 8 Bit mode
T0CS = 0                 // Ensure TMR increments from internal clock
T0SE = 0                 // Only used if external source is selected
PSA = 0                  // Ensure the Clock source uses the Prescaler
T0CON.0 = 0              // Set the Prescaler bits
T0CON.1 = 0              //
T0CON.2 = 1              //
TMR0 = 0                 // Clear the TMR0 register
TMR0IE = 1               // Enable TMR0 Interrupts
Enable(TMR0_Interrupt)   // Enable the TMR0 Interrupt Handler
TMR0ON = 1               // Enable TMR0 to increment
End Sub 




#option LCD_DATA = PORTD              // Assign the LCD connections
#option LCD_EN = PORTA.1                //
#option LCD_RS = PORTA.3
#option LCD_RW = PORTA.2                // // import LCD library...
Include "LCD.bas"
Include "convert.bas"
Input (PORTA.4)
Input (PORTB.0)
LCD.Cls
sec=0
hr=23
min=59
count=0



// Start Of Main Program...
mS = 0                       // Reset the mS counter
TMR0_Event = False           // Clear the TMR0 Event Flag
TMR0_Initialize              // Setup and enable tmr0
'Low(PORTB.0)                 // Make PORTB.0 and output and set it low 

main:

While 1=1   
 While TMR0_Event = False // Wait for 10mS to elapse    
 Wend                     //    
 TMR0_Event = False       // Reset the Event Flag
calctime
butaddmin
hraddmin


WriteAt(1,3, "Time: ",dectostr(hr,2), ":", dectostr(min,2), ":", dectostr(sec,2))
 
Wend                                     // Loop forever 
(\_/)
(='.')
(")-(")
This is a bunny, copy bunny into your signature to help him achieve world domination.

User avatar
odessa
I practically live here!
I practically live here!
Posts: 102
Joined: Thu Sep 09, 2010 6:06 am
Location: London

Re: Help with a simple clock program

Post by odessa » Mon Mar 14, 2011 5:03 am

Solved by snooping 'Uncle Brads' Code :)

Does this look ok ? Works a treat

Code: Select all

Device = 18F4520
Clock = 20
 
Dim
button_debounce As Word,
mS As Word,
count As Word,
sec As Word,
hr As Word,
min As Word,    
TMR0ON As T0CON.7,    
T08BIT As T0CON.6,    
T0CS As T0CON.5,    
T0SE As T0CON.4,    
PSA As T0CON.3,    
TMR0IF As INTCON.2,    
TMR0 As TMR0L,    
TMR0IE As INTCON.5,    
TMR0_Event As Boolean

Interrupt TMR0_Interrupt()    
Save(0)                  // Backup system variables    
If TMR0IF = 1 Then       // Check if a TMR0 Interrupt occurred        
TMR0IF = 0           // Clear the interrupt        
Inc(mS, 1638)        // Increment the mS counter (scale of 1000)        
If mS >= 10000 Then  // Working with a scale of 1000, so this
count=count+1            
mS = mS - 10000  //  checks if 10mS has elapsed            
TMR0_Event = True        
EndIf    
EndIf                     
Restore                  // Backup system variables
 
End Interrupt

Sub calctime()
If count=100 Then sec=sec+1
count=0
If sec=60 Then min=min+1
sec=0
If min=60 Then hr=hr+1
min=0
If hr=24 Then hr=0 
End If
End If
End If
End If
End Sub

Sub addmin()
If PORTA.4=0 And button_debounce <> 0 Then Dec(button_debounce)
EndIf 
If button_debounce=0 Then min=min+1
button_debounce=50
End If
If min=60 Then min=0
End If
End Sub


Sub addhr()
If PORTB.0=0 And button_debounce <> 0 Then Dec(button_debounce)
EndIf 
If button_debounce=0 Then hr=hr+1 
button_debounce=50
End If
If hr=24 Then hr=0
End If
End Sub  

Sub TMR0_Initialize()
TMR0ON = 0               // Disable TMR0
T08BIT = 1               // Ensure TMR0 is working in 8 Bit mode
T0CS = 0                 // Ensure TMR increments from internal clock
T0SE = 0                 // Only used if external source is selected
PSA = 0                  // Ensure the Clock source uses the Prescaler
T0CON.0 = 0              // Set the Prescaler bits
T0CON.1 = 0              //
T0CON.2 = 1              //
TMR0 = 0                 // Clear the TMR0 register
TMR0IE = 1               // Enable TMR0 Interrupts
Enable(TMR0_Interrupt)   // Enable the TMR0 Interrupt Handler
TMR0ON = 1               // Enable TMR0 to increment
End Sub 

#option LCD_DATA = PORTD              // Assign the LCD connections
#option LCD_EN = PORTA.1                //
#option LCD_RS = PORTA.3
#option LCD_RW = PORTA.2                // // import LCD library...
Include "LCD.bas"
Include "convert.bas"
Input (PORTA.4)
Input (PORTB.0)
LCD.Cls
sec=0
hr=16
min=48
count=0
button_debounce=50

// Start Of Main Program...
mS = 0                       // Reset the mS counter
TMR0_Event = False           // Clear the TMR0 Event Flag
TMR0_Initialize              // Setup and enable tmr0


main:

While 1=1   
While TMR0_Event = False // Wait for 10mS to elapse    
Wend                     //    
TMR0_Event = False       // Reset the Event Flag
addmin
addhr
calctime
WriteAt(1,3, "Time: ",DecToStr(hr,2), ":", DecToStr(min,2), ":", DecToStr(sec,2))
'writeat(2,1, "Debounce: ",dectostr(button_debounce,2)) // display to see debounce in action 
Wend   // Loop forever 
(\_/)
(='.')
(")-(")
This is a bunny, copy bunny into your signature to help him achieve world domination.

User avatar
brad
Site Admin
Site Admin
Posts: 2576
Joined: Fri Mar 26, 2010 10:30 pm

Re: Help with a simple clock program

Post by brad » Mon Mar 14, 2011 8:51 am

Glad I could help!

You could also make it a little simpler instead of doing this:

Code: Select all

If PORTA.4=0 And button_debounce <> 0 Then Dec(button_debounce)
EndIf
If button_debounce=0 Then min=min+1
button_debounce=50
End If
You could do this:

Code: Select all

If PORTA.4=0 And button_debounce <> 0 Then 
     Dec(button_debounce)
Elseif PORTA.4 = 1 and button_debounce = 0 then
     button_debounce=50
     min=min+1
End If

User avatar
odessa
I practically live here!
I practically live here!
Posts: 102
Joined: Thu Sep 09, 2010 6:06 am
Location: London

Re: Help with a simple clock program

Post by odessa » Tue Mar 15, 2011 10:05 pm

Hi brad,

Thx for that little tip, always good to see things done more efficiently.

With regards to the timer code above am I right in thinking that the ms count is increasing 1.628 ms so 10000 / 1.628 = 6142.5

Therefore it takes 6142.5 * 1.628 = 9.99999 to get to 10ms

I am just wanting to really understand it and would like to know I've got the right end of the stick :D

Thx

Jay
(\_/)
(='.')
(")-(")
This is a bunny, copy bunny into your signature to help him achieve world domination.

User avatar
brad
Site Admin
Site Admin
Posts: 2576
Joined: Fri Mar 26, 2010 10:30 pm

Re: Help with a simple clock program

Post by brad » Thu Mar 17, 2011 7:57 pm

Hmm, I'm not sure about that.

why do you think it takes 1.628ms?

User avatar
bitfogav
Moderator
Moderator
Posts: 908
Joined: Sun Mar 28, 2010 9:03 pm
Location: United Kingdom
Contact:

Re: Help with a simple clock program

Post by bitfogav » Thu Mar 17, 2011 8:50 pm

I think you mean 1.638ms, as thats what you are scaling your (mS) counter to in your interrupt routine.

So your timer (TMR0) = 1.638mS, so every time the timer (TMR0) reaches 255, and rolls over to 0. then 1.638mS has elapsed. In your interrupt routine your (mS) is Incrementing by 1638, when it reaches over 10000 then 10ms has elapsed. So your timer (TMR0) needs to reach 255, and rolls over to 0 about 7 times for every 10ms.

Code: Select all

Interrupt TMR0_Interrupt()    
Save(0)                  // Backup system variables    
If TMR0IF = 1 Then       // Check if a TMR0 Interrupt occurred        
TMR0IF = 0           // Clear the interrupt        
Inc(mS, 1638)        // Increment the mS counter (scale of 1000)        
If mS >= 10000 Then  // Working with a scale of 1000, so this
count=count+1            
mS = mS - 10000  //  checks if 10mS has elapsed            
TMR0_Event = True        
EndIf    
EndIf                     
Restore                  // Backup system variables

User avatar
odessa
I practically live here!
I practically live here!
Posts: 102
Joined: Thu Sep 09, 2010 6:06 am
Location: London

Re: Help with a simple clock program

Post by odessa » Thu Mar 17, 2011 9:57 pm

yes sorry 1638 .... typo :lol:

I was following the Timer0 guide on digital DIY.

I downloaded the Pic timer calc and set the prescale to 1:32, the freq to 20mhz and it shows the timer period as 1632

If I increase the timer offset to 1 it shows 1638.4

Whats the timer offset for as its not mentioned in the tutorial ?

Also they say re using the calc to make sure the 'internal check box is ticked' .... there isn't one I can see ?

Many Thx

Jay
(\_/)
(='.')
(")-(")
This is a bunny, copy bunny into your signature to help him achieve world domination.

User avatar
bitfogav
Moderator
Moderator
Posts: 908
Joined: Sun Mar 28, 2010 9:03 pm
Location: United Kingdom
Contact:

Re: Help with a simple clock program

Post by bitfogav » Thu Mar 17, 2011 11:20 pm

odessa wrote:yes sorry 1638 .... typo :lol:

I was following the Timer0 guide on digital DIY.
Oh yes I see the tutorial here:
http://digital-diy.com/Swordfish-Compil ... -tmr0.html
odessa wrote:Whats the timer offset for as its not mentioned in the tutorial ?
I think its to fine tune your timer (TMR0)
odessa wrote:Also they say re using the calc to make sure the 'internal check box is ticked' .... there isn't one I can see ?
I think thats a question for Graham or you could ask Graham the question on the tutorial page on digital-diy.com :)

User avatar
odessa
I practically live here!
I practically live here!
Posts: 102
Joined: Thu Sep 09, 2010 6:06 am
Location: London

Re: Help with a simple clock program

Post by odessa » Fri Mar 18, 2011 12:42 am

Hi Gav,

Thx for the reply.

Whats confusing me is what the timer is actually working at. If it works at ( scaled at 1000 as in code ) 1638 then at 6 cycles its 9828 and at 7 its 11466
The code is set to ms>=10000 ... so does it roll over at exactly that or 11466 ?

I ask as the code I've written seems to work very accurately as a clock ... but if every supposed 10ms it was actually 11.4ms then I wouldn't have thought it would be that accurate over time

Jay
(\_/)
(='.')
(")-(")
This is a bunny, copy bunny into your signature to help him achieve world domination.

User avatar
brad
Site Admin
Site Admin
Posts: 2576
Joined: Fri Mar 26, 2010 10:30 pm

Re: Help with a simple clock program

Post by brad » Fri Mar 18, 2011 10:15 pm

I have to say that I am learning something here because interrupts is one thing that I actually haven't really ever used!

User avatar
bitfogav
Moderator
Moderator
Posts: 908
Joined: Sun Mar 28, 2010 9:03 pm
Location: United Kingdom
Contact:

Re: Help with a simple clock program

Post by bitfogav » Sat Mar 19, 2011 9:40 pm

Jay.

I hope the answer from Graham as cleared up the question for you, I just wanted to make sure I had it correct before answering your question above, But as always Graham as answered the question better than I could. :)

Link can be found here with Grahams answer:
http://digital-diy.com/forum/swordfish- ... html#p8328

User avatar
odessa
I practically live here!
I practically live here!
Posts: 102
Joined: Thu Sep 09, 2010 6:06 am
Location: London

Re: Help with a simple clock program

Post by odessa » Sun Mar 20, 2011 2:31 am

Hi Gav,

Yes I did read it and it does make complete sense now. What confused me was the ms count ... but once I understood the count was carried over it clicked ... so it is a very accurate method :D

Thanks for posting it, I read the thread and thought .... hang on that sounds familiar :lol:

Cheers

Jay
(\_/)
(='.')
(")-(")
This is a bunny, copy bunny into your signature to help him achieve world domination.

User avatar
bitfogav
Moderator
Moderator
Posts: 908
Joined: Sun Mar 28, 2010 9:03 pm
Location: United Kingdom
Contact:

Re: Help with a simple clock program

Post by bitfogav » Sun Mar 20, 2011 3:19 am

No worries Jay

Hope you have fun with your clock project! :)

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest