Go to Post I betcha the FIRST officials in the know come in here from time to time and either gasp and think of how to make next year's clue harder or fall off their chair laughing. - Sparks333 [more]
Home
Go Back   Chief Delphi > Technical > Programming
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Closed Thread
Thread Tools Rate Thread Display Modes
  #1   Spotlight this post!  
Unread 09-05-2005, 21:03
psquared psquared is offline
Registered User
no team
Team Role: Programmer
 
Join Date: Jan 2005
Rookie Year: 2005
Location: Chantilly
Posts: 34
psquared is an unknown quantity at this point
Using Timers

I was wondering how i would go about setting up a timer in the program. I would like a way of using a very accurate timer that can be initiated miliseconds apart. I don't want to do a loop timer and guess how long has passed based on how long it takes a loop to pass. I need a really fast and accurate timer that can notify me when a certain number of miliseconds have passed to execute a command. If you have any code suggestions as to how I can get started or any links to resources they would be greatly appreciated. And to clarify I am referring to programming the robot controller using MPLab. Thanks.
  #2   Spotlight this post!  
Unread 09-05-2005, 21:32
Mark McLeod's Avatar
Mark McLeod Mark McLeod is online now
Just Itinerant
AKA: Hey dad...Father...MARK
FRC #0358 (Robotic Eagles)
Team Role: Engineer
 
Join Date: Mar 2003
Rookie Year: 2002
Location: Hauppauge, Long Island, NY
Posts: 8,723
Mark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond repute
Re: Using Timers

IFI published a white paper last year on how to implement timers
http://www.ifirobotics.com/docs/time...004-jan-14.pdf
When the timer rolls over an interrupt is triggered, code execution is interrupted, and you can either perform your action (if it's VERY short), or set a flag your regular code can check whenever it's convenient to execute your special command.
__________________
"Rationality is our distinguishing characteristic - it's what sets us apart from the beasts." - Aristotle
  #3   Spotlight this post!  
Unread 10-05-2005, 10:17
Mark Pettit's Avatar
Mark Pettit Mark Pettit is offline
Addict
FRC #0991 (The Dukes)
Team Role: Coach
 
Join Date: Dec 2002
Rookie Year: 2001
Location: Phoenix, Arizona
Posts: 177
Mark Pettit is a name known to allMark Pettit is a name known to allMark Pettit is a name known to allMark Pettit is a name known to allMark Pettit is a name known to allMark Pettit is a name known to all
Re: Using Timers

Are you limited to programming a timer?
Hardware solutions such as the one found HERE might be an option.
Sorry if I'm way off base.
__________________
Mark Pettit
Team #991 - The Dukes
Brophy College Preparatory
Phoenix, Arizona, USA
THE DUKES: Humans Competing In The Unlimited Class
  #4   Spotlight this post!  
Unread 10-05-2005, 18:38
CyberWolf_22's Avatar
CyberWolf_22 CyberWolf_22 is offline
Programming and Electrical Mentor
AKA: Allen Gregory
FRC #2587 (Afrobots)
Team Role: Mentor
 
Join Date: Jan 2003
Rookie Year: 2003
Location: Houston, Texas
Posts: 227
CyberWolf_22 is just really niceCyberWolf_22 is just really niceCyberWolf_22 is just really niceCyberWolf_22 is just really nice
Re: Using Timers

Kevin Watson also has very good examples of setting up timers using the robot controller. These can be found at kevin.org/frc I have used his examples and have had success using timers for the past two years. They are very well commented and very helpful.
__________________
  #5   Spotlight this post!  
Unread 26-01-2006, 10:11
tribotec_ca88's Avatar
tribotec_ca88 tribotec_ca88 is offline
FIRST-a-holic
AKA: Camila Fitzgibbon
FRC #1382 (Tribotec Team)
Team Role: Student
 
Join Date: Jan 2004
Rookie Year: 2004
Location: São José dos Campos, Brazil
Posts: 194
tribotec_ca88 is just really nicetribotec_ca88 is just really nicetribotec_ca88 is just really nicetribotec_ca88 is just really nicetribotec_ca88 is just really nice
Send a message via ICQ to tribotec_ca88 Send a message via MSN to tribotec_ca88 Send a message via Yahoo to tribotec_ca88
Re: Using Timers

I'm not too familiar with working with interrupt-driven timers so here's a question for those of you more experienced programmers... I'm simply detailing the steps i took to set up a timer, so someone please correct me if i took a wrong turn.

OK I was thinking about using an interrupt-driven timer (Timer1 - as indicated in the PIC datasheet - to be more specific) used to keep track of time intervals during the Autonomous period.

The first thing I did was initialize it under User_Initialization (user_routines.c) with the following configurations:

T1CONbits.T1CKPS0 = 1; // 1:8 Prescale (clock=1.25MHz/each tick=800ns)
T1CONbits.T1CKPS1 = 1;


T1CONbits.TMR1CS = 0; // = 0 Timer uses internal clock
TMR1H = 0x85; // Sets most significant byte
TMRIL = 0xED; // Sets least significant byte
T1CONbits.TMR1ON = 1; // Turns on Timer1

IPR1bits.TMR1IP = 0; // Sets Timer1 as low priority
PIE1bits.TMR1IE = 1; // Enables Timer1 overflow interrupt
INTCONbits.GIEL = 1; // Enables low priority interruptions


Inside the InterruptHandlerLow () function i've got the following IF loop set up:

if (PIR1bits.TMR1IF) // In other words, has Timer1 overflowed?
{
PIR1bits.TMRI1F = 0; // Resets Timer1
timer1_flag = 1; // Variable used as a flag
}


All righty, the one thing i need to know is where exactly should i call the InterruptHandlerLow () function from? Inside the while (autonomous_mode) loop in user_routines_fast?? That way I was thinking of calling my team's customized autonomous function (known as Autonomous() in this case) from inside the while (autonomous_mode), transferring the value of timer1_flag through parameters, and using that value afterwards inside my Autonomous() function...
Example:

while (autonomous_mode) /* DO NOT CHANGE! */
{
if (statusflag.NEW_SPI_DATA) /* 26.2ms loop area */
{
Getdata(&rxdata);

Autonomous((int)timer1_flag);
Generate_Pwms(pwm13,pwm14,pwm15,pwm16);
Putdata(&txdata);
}
}

OK would this by any chance work at all, or have i totally lost it lol ? Any help at all would be greatly appreciated!!!
__________________
1382 Tribotec Team - Brazil
-----------------------------------------------
2005 NJ Regional GM Industrial Design Award
2005 NJ Regional Website Excellence Award
2004 NJ Regional Semifinalists
-----------------------------------------------
  #6   Spotlight this post!  
Unread 26-01-2006, 13:38
Eldarion's Avatar
Eldarion Eldarion is offline
Electrical Engineer / Computer Geek
AKA: Eldarion Telcontar
no team (Teamless Orphan)
Team Role: Alumni
 
Join Date: Nov 2005
Rookie Year: 2005
Location: Númenor
Posts: 558
Eldarion has a reputation beyond reputeEldarion has a reputation beyond reputeEldarion has a reputation beyond reputeEldarion has a reputation beyond reputeEldarion has a reputation beyond reputeEldarion has a reputation beyond reputeEldarion has a reputation beyond reputeEldarion has a reputation beyond reputeEldarion has a reputation beyond reputeEldarion has a reputation beyond reputeEldarion has a reputation beyond repute
Send a message via AIM to Eldarion Send a message via Yahoo to Eldarion
Re: Using Timers

Quote:
Originally Posted by tribotec_ca88
I'm not too familiar with working with interrupt-driven timers so here's a question for those of you more experienced programmers... I'm simply detailing the steps i took to set up a timer, so someone please correct me if i took a wrong turn.

OK I was thinking about using an interrupt-driven timer (Timer1 - as indicated in the PIC datasheet - to be more specific) used to keep track of time intervals during the Autonomous period.

The first thing I did was initialize it under User_Initialization (user_routines.c) with the following configurations:

T1CONbits.T1CKPS0 = 1; // 1:8 Prescale (clock=1.25MHz/each tick=800ns)
T1CONbits.T1CKPS1 = 1;


T1CONbits.TMR1CS = 0; // = 0 Timer uses internal clock
TMR1H = 0x85; // Sets most significant byte
TMRIL = 0xED; // Sets least significant byte
T1CONbits.TMR1ON = 1; // Turns on Timer1

IPR1bits.TMR1IP = 0; // Sets Timer1 as low priority
PIE1bits.TMR1IE = 1; // Enables Timer1 overflow interrupt
INTCONbits.GIEL = 1; // Enables low priority interruptions


Inside the InterruptHandlerLow () function i've got the following IF loop set up:

if (PIR1bits.TMR1IF) // In other words, has Timer1 overflowed?
{
PIR1bits.TMRI1F = 0; // Resets Timer1
timer1_flag = 1; // Variable used as a flag
}


All righty, the one thing i need to know is where exactly should i call the InterruptHandlerLow () function from? Inside the while (autonomous_mode) loop in user_routines_fast?? That way I was thinking of calling my team's customized autonomous function (known as Autonomous() in this case) from inside the while (autonomous_mode), transferring the value of timer1_flag through parameters, and using that value afterwards inside my Autonomous() function...
Example:

while (autonomous_mode) /* DO NOT CHANGE! */
{
if (statusflag.NEW_SPI_DATA) /* 26.2ms loop area */
{
Getdata(&rxdata);

Autonomous((int)timer1_flag);
Generate_Pwms(pwm13,pwm14,pwm15,pwm16);
Putdata(&txdata);
}
}

OK would this by any chance work at all, or have i totally lost it lol ? Any help at all would be greatly appreciated!!!
InterruptHandlerLow () is a system function; I.E. when an interrupt is set, this function is immediately called by IFI's interrupt handler. You do not need to call it from anywhere in your code.
__________________
CMUCam not working? Tracks sporadically? Try this instead: http://www.falconir.com!
PM me for more information if you are interested (it's open source!).

Want the FIRST Email blasts? See here: http://www.chiefdelphi.com/forums/sh...ad.php?t=50809

"The harder the conflict, the more glorious the triumph. What we obtain too cheaply, we esteem too lightly; it is dearness only that gives everything its value."
-- Thomas Paine

If it's falling apart it's a mechanical problem. If it's spewing smoke it's a electrical problem.
If it's rampaging around destroying things it's a programming problem.

"All technology is run on 'Magic Smoke' contained within the device. As everyone knows, whenever the magic smoke is released, the device ceases to function."
-- Anonymous

I currently speak: English, some German, Verilog, x86 and 8051 Assembler, C, C++, VB, VB.NET, ASP, PHP, HTML, UNIX and SQL
  #7   Spotlight this post!  
Unread 26-01-2006, 14:18
dcbrown dcbrown is offline
Registered User
AKA: Bud
no team
Team Role: Mentor
 
Join Date: Jan 2005
Rookie Year: 2005
Location: Hollis,NH
Posts: 236
dcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud of
Re: Using Timers

Quote:
Originally Posted by tribotec_ca88
Inside the InterruptHandlerLow () function i've got the following IF loop set up:

if (PIR1bits.TMR1IF) // In other words, has Timer1 overflowed?
{
PIR1bits.TMRI1F = 0; // Resets Timer1
timer1_flag = 1; // Variable used as a flag
}

I'd suggest re-reading the PIC18F manual on TMR1 and looking over Kevin's code, you're close. At least from my experience.

In the ISR for the timer you'll need to reset the value in the timer. The timer, once enabled simply counts up to 0xFFFF and upon overflowing back to 0x0000 sets the TMR1F flag indicating overflow. It sets the flag whether interrupts are enabled or not. If interrupts are enabled for this timer, then the ISR is invoked. The timer however continues to get clocked and continues to count (0x0001, 0x0002, ... etc.) until it overflows again and another interrupt will be generated since the timer is still enabled. However in this case the time interval between the 1st interrupt and 2nd is however long it takes to count from 0 to FFFF vs the first time when it counted from 0x85ED to 0xFFFF. If you want a one shot interrupt, then you should disable the timer (T1CONbits.TMR1ON = 0) in the ISR.

If you want a periodic interrupt, then you'll need to reset the value in the timer to count from. For example, something like:


// timer continued to run on after it raised the interrupt
// latency is amount of count, save last latency in drift
timer1_drift.lo = TMR1L; // 16bit mode, read L -> latches H for reading
timer1_drift.hi = TMR1H;


// NOTE:
// Drift can be larger than 256 instructions if, for example,
// the timer interrupt is raised just after we test for it in
// the ISR and then spend a lot of time in the ADC or later
// interrupts - or high priority interrupt occurs - or ...
// So, do int arithmatic to compensate for drift.
timer1_drift.wrd += (0x85ED-13); // reload counter with desired value

// Note:
// Ideally we also add in a handful of cycles it takes to get from reading
// the timer above to resetting it here. Not many cycles but we can
// easily figure them out by looking at assembler and adjusting 0x85ED
// accordingly. I counted 13 cycles to be subtracted last time I checked

TMR1H = timer1_drift.hi;
TMR1L = timer1_drift.lo;
T1CON = 0x85; // reset prescaler, lost at TMR1L write time.

NOTE: The above logic might be wrong, it is mostly a copy of our sysclock routine which has a 1:1 prescaler vs this 1:8 prescaler. Therefore the (-13) cycles is not correct and should be adjusted as required.

Its also best to check that both the interrupt is enabled AND the interrupt flag is set:

if (PIR1bits.TMR1IF && PIE1bits.TMR1IE) ...

Regards,
DCBrown

Last edited by dcbrown : 26-01-2006 at 14:21.
  #8   Spotlight this post!  
Unread 30-01-2006, 07:09
tribotec_ca88's Avatar
tribotec_ca88 tribotec_ca88 is offline
FIRST-a-holic
AKA: Camila Fitzgibbon
FRC #1382 (Tribotec Team)
Team Role: Student
 
Join Date: Jan 2004
Rookie Year: 2004
Location: São José dos Campos, Brazil
Posts: 194
tribotec_ca88 is just really nicetribotec_ca88 is just really nicetribotec_ca88 is just really nicetribotec_ca88 is just really nicetribotec_ca88 is just really nice
Send a message via ICQ to tribotec_ca88 Send a message via MSN to tribotec_ca88 Send a message via Yahoo to tribotec_ca88
Re: Using Timers

I've included timers.h in all c files i'm using timers in...and this is what i ended up writing to initialize Timer1:

T1CONbits.T1CKPS0 = 1; // 1:8 Prescale (clock=1.25MHz/each tick=800ns)
T1CONbits.T1CKPS1 = 1;

T1CONbits.TMR1CS = 0; // Internal clock
TMR1H = 0x85; // Timer1's most significant byte
TMRIL = 0xED; // Timer1's least significant byte
T1CONbits.TMR1ON = 1; // Timer1 set as on
IPR1bits.TMR1IP = 0; // Sets interrupt as low priority
PIR1bits.TMR1IF = 0; // Overflow flag
PIE1bits.TMR1IE = 1; // Timer1 interrupt
INTCONbits.GIEL = 1; // Low priority interrupts OK


but for some reason i still get a few errors related to the TMR1H and TMR1L variables stating:

C:\NossoCodigo\Code_26Jan\user_routines.c:168:Erro r [1105] symbol 'TMRIL' has not been defined
C:\NossoCodigo\Code_26Jan\user_routines.c:168:Erro r [1101] lvalue required

I understand they haven't been defined but where exactly would I define them (and as what?!) ?

thanks, any help at all would be greatly appreciated!!
__________________
1382 Tribotec Team - Brazil
-----------------------------------------------
2005 NJ Regional GM Industrial Design Award
2005 NJ Regional Website Excellence Award
2004 NJ Regional Semifinalists
-----------------------------------------------
  #9   Spotlight this post!  
Unread 30-01-2006, 08:42
DanDon's Avatar
DanDon DanDon is offline
ohhh MY god
AKA: Dan Hoizner
FRC #0375 (The Robotic Plague)
Team Role: Mentor
 
Join Date: Jan 2005
Rookie Year: 2004
Location: Staten Island, NY
Posts: 1,432
DanDon has a reputation beyond reputeDanDon has a reputation beyond reputeDanDon has a reputation beyond reputeDanDon has a reputation beyond reputeDanDon has a reputation beyond reputeDanDon has a reputation beyond reputeDanDon has a reputation beyond reputeDanDon has a reputation beyond reputeDanDon has a reputation beyond reputeDanDon has a reputation beyond reputeDanDon has a reputation beyond repute
Send a message via ICQ to DanDon Send a message via AIM to DanDon Send a message via MSN to DanDon
Re: Using Timers

Quote:
Originally Posted by tribotec_ca88
I've included timers.h in all c files i'm using timers in...and this is what i ended up writing to initialize Timer1:

T1CONbits.T1CKPS0 = 1; // 1:8 Prescale (clock=1.25MHz/each tick=800ns)
T1CONbits.T1CKPS1 = 1;

T1CONbits.TMR1CS = 0; // Internal clock
TMR1H = 0x85; // Timer1's most significant byte
TMRIL = 0xED; // Timer1's least significant byte
T1CONbits.TMR1ON = 1; // Timer1 set as on
IPR1bits.TMR1IP = 0; // Sets interrupt as low priority
PIR1bits.TMR1IF = 0; // Overflow flag
PIE1bits.TMR1IE = 1; // Timer1 interrupt
INTCONbits.GIEL = 1; // Low priority interrupts OK


but for some reason i still get a few errors related to the TMR1H and TMR1L variables stating:

C:\NossoCodigo\Code_26Jan\user_routines.c:168:Erro r [1105] symbol 'TMRIL' has not been defined
C:\NossoCodigo\Code_26Jan\user_routines.c:168:Erro r [1101] lvalue required

I understand they haven't been defined but where exactly would I define them (and as what?!) ?

thanks, any help at all would be greatly appreciated!!
it looks like you're using "TMRIL" instead of "TMR1L"?

sorry if I'm mistaken,
__________________
  #10   Spotlight this post!  
Unread 30-01-2006, 10:29
tribotec_ca88's Avatar
tribotec_ca88 tribotec_ca88 is offline
FIRST-a-holic
AKA: Camila Fitzgibbon
FRC #1382 (Tribotec Team)
Team Role: Student
 
Join Date: Jan 2004
Rookie Year: 2004
Location: São José dos Campos, Brazil
Posts: 194
tribotec_ca88 is just really nicetribotec_ca88 is just really nicetribotec_ca88 is just really nicetribotec_ca88 is just really nicetribotec_ca88 is just really nice
Send a message via ICQ to tribotec_ca88 Send a message via MSN to tribotec_ca88 Send a message via Yahoo to tribotec_ca88
Re: Using Timers

Quote:
Originally Posted by dhoizner
it looks like you're using "TMRIL" instead of "TMR1L"?

sorry if I'm mistaken,
lol so very true...
thanks for the heads up!
__________________
1382 Tribotec Team - Brazil
-----------------------------------------------
2005 NJ Regional GM Industrial Design Award
2005 NJ Regional Website Excellence Award
2004 NJ Regional Semifinalists
-----------------------------------------------
Closed Thread


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Timers MarkVH Programming 1 13-02-2005 11:30
Timers ? Gal Longin Programming 5 12-02-2005 06:15
Securing interrupt-driven timers Orborde Programming 3 10-02-2005 15:52
How do you program timers? roberthan Programming 5 04-02-2004 02:18
What type of timers for autonomous? thoughtful Programming 1 09-12-2003 02:28


All times are GMT -5. The time now is 10:56.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi