Go to Post If there is anything I have learned from ChiefDelphi, it's to never underestimate the coding genius that is Brandon Martus. - Amanda Morrison [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 24-10-2006, 17:10
Josh Siegel's Avatar
Josh Siegel Josh Siegel is offline
lurker
#0448 (Crandroids)
 
Join Date: Nov 2003
Rookie Year: 2003
Location: Bloomfield Hills, Michigan
Posts: 67
Josh Siegel will become famous soon enough
Send a message via AIM to Josh Siegel Send a message via MSN to Josh Siegel
Help needed timing a pulse (2004 Robovation)

Hi everyone,
I have been reading about CCP pins and interrupts, and am at a complete loss as to what the -simplest- way of timing an input pulse is. Here are the specifics of my application:
-The signal varies from 1mS to 36.99mS
-There is a 65mS low signal between pulses
-I am currently using, essentially, the default code (added sensor capture and filtering for sonar, but the framework is the same).
-It would be best if lag during capture could be avoided (so that the proc. doesn't wait for a signal when it could be filtering, etc.)
-I will, obviously, need access to the up-to-date value as stored in a variable.
-My PWM generator specifies down to 10uS readability; 100uS would be fine for my purposes.
-The signal is 0V or 5V, through a sensor powered by the analog pins.

Now, I know interrupts can be used like the sonar code, tracking rising and falling edges of the square wave. I also gather that CCP can do this with one pin, and appears like it will not lag the program.

How can I impliment something like this? What code do I need to add to the default code? What pins do I use?

Thank you,
Josh
  #2   Spotlight this post!  
Unread 24-10-2006, 22:45
Kevin Sevcik's Avatar
Kevin Sevcik Kevin Sevcik is offline
(Insert witty comment here)
FRC #0057 (The Leopards)
Team Role: Mentor
 
Join Date: Jun 2001
Rookie Year: 1998
Location: Houston, Texas
Posts: 3,745
Kevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond repute
Send a message via AIM to Kevin Sevcik Send a message via Yahoo to Kevin Sevcik
Re: Help needed timing a pulse (2004 Robovation)

Yes, you can use a single CCP module to do this, but it would still create an interrupt you'd have to service, and you'd have to constantly change the mode of the CCP module. So you may not actually gain anything. You could also use 2 CCP modules with a lighter interrupt service rountine, or no interrupt service routine and some educated guessing if your data is valid. In fact, you could also use just one interrupt in the same fashion you'd use just one CCP module. Sadly, I see no real way of doing this without some amount of interrupts. Unless you're fine with making an (very well) educated guess about the validity of your data.

Sooo..... The question would be exactly how much help you're looking for. All the info you actually need is in the data sheet, pages 149-151. And in the Edu-bot programming reference, to put the PWM outs into USER_CCP mode. If you want, I can whip out very rough pseudo code for the scenarios about so you can see the differences.
__________________
The difficult we do today; the impossible we do tomorrow. Miracles by appointment only.

Lone Star Regional Troubleshooter
  #3   Spotlight this post!  
Unread 24-10-2006, 23:11
Josh Siegel's Avatar
Josh Siegel Josh Siegel is offline
lurker
#0448 (Crandroids)
 
Join Date: Nov 2003
Rookie Year: 2003
Location: Bloomfield Hills, Michigan
Posts: 67
Josh Siegel will become famous soon enough
Send a message via AIM to Josh Siegel Send a message via MSN to Josh Siegel
Re: Help needed timing a pulse (2004 Robovation)

Thanks for the reply, Kevin -
I have nothing against interrupts per-se. I simply haven't used them, so I'm a bit apprehensive about trying. Will they accomplish what I need, without undue amounts of lag?
If you could provide a skeleton code that I can work from, that would be wonderful. I see how to set them up in the software, but their use is a bit beyond me. The overflow/preloading make sense in theory, but I am not positive on how the values for each are derived, or how I can convert the values into a usable time (mS, uS) that may be accessed like a variable.
How does Kevin Watson do this in his infrared receiver code? It looked like he might have some usable way of measuring a pulse width.
  #4   Spotlight this post!  
Unread 25-10-2006, 02:25
yongkimleng yongkimleng is offline
deus ex programmeur
AKA: James Yong
FTC #0747
Team Role: Mentor
 
Join Date: Aug 2006
Rookie Year: 2004
Location: Singapore, West
Posts: 134
yongkimleng is a jewel in the roughyongkimleng is a jewel in the roughyongkimleng is a jewel in the rough
Send a message via MSN to yongkimleng
Re: Help needed timing a pulse (2004 Robovation)

Quote:
Originally Posted by Josh Siegel
Hi everyone,
I have been reading about CCP pins and interrupts, and am at a complete loss as to what the -simplest- way of timing an input pulse is. Here are the specifics of my application:
-The signal varies from 1mS to 36.99mS
-There is a 65mS low signal between pulses
-I am currently using, essentially, the default code (added sensor capture and filtering for sonar, but the framework is the same).
-It would be best if lag during capture could be avoided (so that the proc. doesn't wait for a signal when it could be filtering, etc.)
-I will, obviously, need access to the up-to-date value as stored in a variable.
-My PWM generator specifies down to 10uS readability; 100uS would be fine for my purposes.
-The signal is 0V or 5V, through a sensor powered by the analog pins.

Now, I know interrupts can be used like the sonar code, tracking rising and falling edges of the square wave. I also gather that CCP can do this with one pin, and appears like it will not lag the program.

How can I impliment something like this? What code do I need to add to the default code? What pins do I use?

Thank you,
Josh
Not really a fan of CCP I am.. well, assuming you know the key registers, try the following:
1. find an available timer, 8 or 16 bit, and init it to count such that it counts to max within ur 37ms. Or around that time. Do not set timer overflow to activate an interrupt. Do not start the timer running.
2. take one of ur interrupt pins and set it to activate on to-high and to-low transitions. in the interrupt, read back the pin to differentiate between to-high and to-low events.
3. during to-high event, init timer to 0 and start the timer.
4. during to-low event, stop the timer and copy the 16it value to a 16bit variable
5. now let the pulses come in, have the output printf-ed and see if anything goes wrong..

this is fully pulse-activated interrupt based so you go about doing ur normal routines leaving this to run by its own , reading the 16bit variable to check for the last pulse recorded.

edit: about disabling interrupts when modifying values.. in this scenario u probably wont need to. But you may want to avoid reading the 16bit variable while it is in the midst of being updated... I'm not sure if 16 bit read/write are single instruction (but longer clocks) or multi instruction. Probably multi I guess.. get someone to verify this.
__________________
| jamesyong.net |
FVC2007, FTC2008

Last edited by yongkimleng : 25-10-2006 at 03:01.
  #5   Spotlight this post!  
Unread 25-10-2006, 02:42
Mr. Lim Mr. Lim is offline
Registered User
AKA: Mr. Lim
no team
Team Role: Leadership
 
Join Date: Jan 2004
Rookie Year: 1998
Location: Toronto, Ontario
Posts: 1,125
Mr. Lim has a reputation beyond reputeMr. Lim has a reputation beyond reputeMr. Lim has a reputation beyond reputeMr. Lim has a reputation beyond reputeMr. Lim has a reputation beyond reputeMr. Lim has a reputation beyond reputeMr. Lim has a reputation beyond reputeMr. Lim has a reputation beyond reputeMr. Lim has a reputation beyond reputeMr. Lim has a reputation beyond reputeMr. Lim has a reputation beyond repute
Re: Help needed timing a pulse (2004 Robovation)

Quote:
Originally Posted by Josh Siegel
how I can convert the values into a usable time (mS, uS) that may be accessed like a variable.
How does Kevin Watson do this in his infrared receiver code? It looked like he might have some usable way of measuring a pulse width.
That's exactly what I would look at. Kevin Watson's IR receiver code. Specifically the routines for identifying which of the two beacons is being detected. They each produced a different pulse width signal.

In a nutshell:

Set up a timer to increment at whatever resolution you need measure your pulse width at.

Start timer.

Interrupt on each falling edge (or rising, or both depending on what you want).

Service the interrupt by checking your timer variable, and reset your timer variable to 0.

Lather, Rinse, Repeat...

For interrupts, this is a pretty good first project. Just be sure to disable your interrupts temporarily when you modify variables that are modified by other interrupt service routines. In the above example, you'll want to disable interrupts whenever you increment or reset your timer variable, then re-enable them right after.
  #6   Spotlight this post!  
Unread 25-10-2006, 12:11
Kevin Sevcik's Avatar
Kevin Sevcik Kevin Sevcik is offline
(Insert witty comment here)
FRC #0057 (The Leopards)
Team Role: Mentor
 
Join Date: Jun 2001
Rookie Year: 1998
Location: Houston, Texas
Posts: 3,745
Kevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond repute
Send a message via AIM to Kevin Sevcik Send a message via Yahoo to Kevin Sevcik
Re: Help needed timing a pulse (2004 Robovation)

So, like others have suggested, I'd look at Kevin's code. But I'd specifically look at the 2005 frc_interrupts.zip file. That's a really good interrupt handler, AND it shows you how to set up the timers. As far as actualy implementation:

Use an 1:8 prescale on a 16-bit Timer, anything else is too short. Start the timer, leave it running, it'll save you the bother of starting and stopping it needlessly. Disable the Timer's Interrupt, you don't need it.

Use one of the KBI interrupts, handled by Int_3_Handler through Int_6_Handler. These interrupt on rise and fall. The value passed by the Int Handler function tells you what the state of the pin is.

On the rising edge, when the value passed is 1, clear the timer. If it's in 16-bit Read Mode, write 0 to TMRxH THEN write 0 to TMRxL.

On the falling edge, when the value passed is 0, read TMRxL to a temp variable, read TMRxH to your actual 16-bit variable, shift 8 bits to the left, and add your temp variable. You're done.

Stopping the timer is pointless, you have to clear it no matter what, so just clear it at the start and you're fine.

Your program should copy the value of the variable this routine saves to to a new variable and work with the new variable, as the routine might change the value halfway through your computation otherwise. I'm pretty sure you don't have to disable interrupts while in the interrupt handler itself in this case.

Using the CCPs is a good bit more complicated, but you'll get a much more accurate time measure, as the CCP handles saving the Timer value the instant the of the edge trigger, without the delay of entering the interrupt routine, etc.
__________________
The difficult we do today; the impossible we do tomorrow. Miracles by appointment only.

Lone Star Regional Troubleshooter
  #7   Spotlight this post!  
Unread 25-10-2006, 13:51
yongkimleng yongkimleng is offline
deus ex programmeur
AKA: James Yong
FTC #0747
Team Role: Mentor
 
Join Date: Aug 2006
Rookie Year: 2004
Location: Singapore, West
Posts: 134
yongkimleng is a jewel in the roughyongkimleng is a jewel in the roughyongkimleng is a jewel in the rough
Send a message via MSN to yongkimleng
Re: Help needed timing a pulse (2004 Robovation)

Quote:
Originally Posted by Kevin Sevcik
So, like others have suggested, I'd look at Kevin's code. But I'd specifically look at the 2005 frc_interrupts.zip file. That's a really good interrupt handler, AND it shows you how to set up the timers. As far as actualy implementation:

Use an 1:8 prescale on a 16-bit Timer, anything else is too short. Start the timer, leave it running, it'll save you the bother of starting and stopping it needlessly. Disable the Timer's Interrupt, you don't need it.

Use one of the KBI interrupts, handled by Int_3_Handler through Int_6_Handler. These interrupt on rise and fall. The value passed by the Int Handler function tells you what the state of the pin is.

On the rising edge, when the value passed is 1, clear the timer. If it's in 16-bit Read Mode, write 0 to TMRxH THEN write 0 to TMRxL.

On the falling edge, when the value passed is 0, read TMRxL to a temp variable, read TMRxH to your actual 16-bit variable, shift 8 bits to the left, and add your temp variable. You're done.

Stopping the timer is pointless, you have to clear it no matter what, so just clear it at the start and you're fine.

Your program should copy the value of the variable this routine saves to to a new variable and work with the new variable, as the routine might change the value halfway through your computation otherwise. I'm pretty sure you don't have to disable interrupts while in the interrupt handler itself in this case.

Using the CCPs is a good bit more complicated, but you'll get a much more accurate time measure, as the CCP handles saving the Timer value the instant the of the edge trigger, without the delay of entering the interrupt routine, etc.
May I ask, is there a possibility where during the copy of the first 8 bits, the value is something like 255, and when it proceeds to copy the next 8 its, it increments by 1 (due to the overflow of the first 8 bits when the timer ticks a few more times) before it gets copied, resulting in a larger value than expected?..
__________________
| jamesyong.net |
FVC2007, FTC2008
  #8   Spotlight this post!  
Unread 25-10-2006, 14:45
Kevin Sevcik's Avatar
Kevin Sevcik Kevin Sevcik is offline
(Insert witty comment here)
FRC #0057 (The Leopards)
Team Role: Mentor
 
Join Date: Jun 2001
Rookie Year: 1998
Location: Houston, Texas
Posts: 3,745
Kevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond repute
Send a message via AIM to Kevin Sevcik Send a message via Yahoo to Kevin Sevcik
Re: Help needed timing a pulse (2004 Robovation)

Quote:
Originally Posted by yongkimleng
May I ask, is there a possibility where during the copy of the first 8 bits, the value is something like 255, and when it proceeds to copy the next 8 its, it increments by 1 (due to the overflow of the first 8 bits when the timer ticks a few more times) before it gets copied, resulting in a larger value than expected?..
That would be why you'd prefer having the timer in 16-bit read mode. In this mode, when TMRxL is read, TMRxH is instantly copied to a buffer, which can be read without fear of this problem. Writing is reversed. you write to TMRxH, which is stored to a buffer, then wrtie to TMRxL, which write that value and copies the buffer to the timer at the exact same time.
__________________
The difficult we do today; the impossible we do tomorrow. Miracles by appointment only.

Lone Star Regional Troubleshooter
  #9   Spotlight this post!  
Unread 25-10-2006, 21:47
Qbranch Qbranch is offline
wow college goes fast.
AKA: Alex
FRC #1024 (Kil-A-Bytes)
Team Role: Alumni
 
Join Date: Apr 2006
Rookie Year: 2006
Location: Indianapolis
Posts: 1,174
Qbranch has a reputation beyond reputeQbranch has a reputation beyond reputeQbranch has a reputation beyond reputeQbranch has a reputation beyond reputeQbranch has a reputation beyond reputeQbranch has a reputation beyond reputeQbranch has a reputation beyond reputeQbranch has a reputation beyond reputeQbranch has a reputation beyond reputeQbranch has a reputation beyond reputeQbranch has a reputation beyond repute
Re: Help needed timing a pulse (2004 Robovation)

Quote:
Originally Posted by yongkimleng
Not really a fan of CCP I am.. well, assuming you know the key registers,
quick p.s.: once you really get to know them, you really start to love em

by the way... if you all examine the assembly code for the add function in C++ you'll find that you don't need to reset the timer to zero all the time.... also remember that the hardware add done by the timer works the same way...

have fun. ccp's rock my socks. craziest thing i've done with em is step motor control ~15KHz on the 8722, rate and positional(with accel/decel) control and simultaneous + independent axis motion.

-Q
__________________
Electrical Engineer Illini
1024 | Programmer '06, '07, '08 | Driver '08
  #10   Spotlight this post!  
Unread 26-10-2006, 05:09
yongkimleng yongkimleng is offline
deus ex programmeur
AKA: James Yong
FTC #0747
Team Role: Mentor
 
Join Date: Aug 2006
Rookie Year: 2004
Location: Singapore, West
Posts: 134
yongkimleng is a jewel in the roughyongkimleng is a jewel in the roughyongkimleng is a jewel in the rough
Send a message via MSN to yongkimleng
Re: Help needed timing a pulse (2004 Robovation)

Quote:
Originally Posted by Kevin Sevcik
That would be why you'd prefer having the timer in 16-bit read mode. In this mode, when TMRxL is read, TMRxH is instantly copied to a buffer, which can be read without fear of this problem. Writing is reversed. you write to TMRxH, which is stored to a buffer, then wrtie to TMRxL, which write that value and copies the buffer to the timer at the exact same time.
okay thanks, thats much clearer now.. I'd probably missed it when reading the datasheets
__________________
| jamesyong.net |
FVC2007, FTC2008
  #11   Spotlight this post!  
Unread 26-10-2006, 05:13
yongkimleng yongkimleng is offline
deus ex programmeur
AKA: James Yong
FTC #0747
Team Role: Mentor
 
Join Date: Aug 2006
Rookie Year: 2004
Location: Singapore, West
Posts: 134
yongkimleng is a jewel in the roughyongkimleng is a jewel in the roughyongkimleng is a jewel in the rough
Send a message via MSN to yongkimleng
Re: Help needed timing a pulse (2004 Robovation)

Quote:
Originally Posted by Qbranch
quick p.s.: once you really get to know them, you really start to love em

by the way... if you all examine the assembly code for the add function in C++ you'll find that you don't need to reset the timer to zero all the time.... also remember that the hardware add done by the timer works the same way...

have fun. ccp's rock my socks. craziest thing i've done with em is step motor control ~15KHz on the 8722, rate and positional(with accel/decel) control and simultaneous + independent axis motion.

-Q
Haha I'm an idiot at ASM.. yet to learn it :/ What do you mean by the hardware add function works the same way as... ???

I'm still figuring how to use CCP to do a read of 8 PWM inputs simultaneously w/o causing much cpu load too
__________________
| jamesyong.net |
FVC2007, FTC2008
  #12   Spotlight this post!  
Unread 26-10-2006, 14:51
Qbranch Qbranch is offline
wow college goes fast.
AKA: Alex
FRC #1024 (Kil-A-Bytes)
Team Role: Alumni
 
Join Date: Apr 2006
Rookie Year: 2006
Location: Indianapolis
Posts: 1,174
Qbranch has a reputation beyond reputeQbranch has a reputation beyond reputeQbranch has a reputation beyond reputeQbranch has a reputation beyond reputeQbranch has a reputation beyond reputeQbranch has a reputation beyond reputeQbranch has a reputation beyond reputeQbranch has a reputation beyond reputeQbranch has a reputation beyond reputeQbranch has a reputation beyond reputeQbranch has a reputation beyond repute
Re: Help needed timing a pulse (2004 Robovation)

Quote:
Originally Posted by yongkimleng
Haha I'm an idiot at ASM.. yet to learn it :/ What do you mean by the hardware add function works the same way as... ???

the adds roll over to zero.....

let's for instance take an unsigned integer, 0xFFFF. when we add 0x0001, and perform the "ADD" instruction, the ALU takes the value of the first digit and starts bit shifting, starting the carry to the next digit. but... we don't have any more bits!

so what basically happens in hardware is:

0xFFFF & 0x0000 //clear already filled digits since we're moving up a place
0x0001 << 0x0005 //working register now 0x0000 with a 1 hanging off to the left

and in the end, we're left with 0x0000!

i think now you understand why you never have to stop+reset the timer.

-Q
__________________
Electrical Engineer Illini
1024 | Programmer '06, '07, '08 | Driver '08

Last edited by Qbranch : 26-10-2006 at 15:02.
  #13   Spotlight this post!  
Unread 27-10-2006, 01:23
yongkimleng yongkimleng is offline
deus ex programmeur
AKA: James Yong
FTC #0747
Team Role: Mentor
 
Join Date: Aug 2006
Rookie Year: 2004
Location: Singapore, West
Posts: 134
yongkimleng is a jewel in the roughyongkimleng is a jewel in the roughyongkimleng is a jewel in the rough
Send a message via MSN to yongkimleng
Re: Help needed timing a pulse (2004 Robovation)

Quote:
Originally Posted by Qbranch
the adds roll over to zero.....

let's for instance take an unsigned integer, 0xFFFF. when we add 0x0001, and perform the "ADD" instruction, the ALU takes the value of the first digit and starts bit shifting, starting the carry to the next digit. but... we don't have any more bits!

so what basically happens in hardware is:

0xFFFF & 0x0000 //clear already filled digits since we're moving up a place
0x0001 << 0x0005 //working register now 0x0000 with a 1 hanging off to the left

and in the end, we're left with 0x0000!

i think now you understand why you never have to stop+reset the timer.

-Q
oh... think there was a miscommunication here, I thought my idea was to start the timer on a high pulse, and every time on a high pulse it has to reset the timer. Due to timing differences between the timer and the actual pulse, it may not overflow to a nice 0x0000 at the start of a high pulse.
After kevin's post then I realised that you need not stop/start the timer because you can do a reliable 16bit read, so you'd only do a reset-to-zero on a high pulse and a 16bit read on a low pulse
__________________
| jamesyong.net |
FVC2007, FTC2008
  #14   Spotlight this post!  
Unread 29-10-2006, 12:05
Josh Siegel's Avatar
Josh Siegel Josh Siegel is offline
lurker
#0448 (Crandroids)
 
Join Date: Nov 2003
Rookie Year: 2003
Location: Bloomfield Hills, Michigan
Posts: 67
Josh Siegel will become famous soon enough
Send a message via AIM to Josh Siegel Send a message via MSN to Josh Siegel
Re: Help needed timing a pulse (2004 Robovation)

Thanks guys,
I think I understand the concept now!
I wrote some code that (should) work, but doesn't. It reads random values, even if the sensor is still. I can understand how it might read the same error each time, but if the pulse is right, it shouldn't vary every loop, should it? So I guess, I'm trying to figure out of it's something to do with my wiring, or something in the program itself. I don't have access to an oscilliscope to check it, sadly.
Here's the code:
From interrupts.c
Code:
void Initialize_Timer_1(void)  
{
	TMR1L = TMR1H = 0x00;		           	// LSB-TMR1 (read/write) = MSB-TMR1 (read/write) = 0
	T1CONbits.T1CKPS0 = T1CONbits.T1CKPS1 = 1;	// 1,1: 1:8 prescaler (clock=1.25MHz/each tick=800ns)
	T1CONbits.T1OSCEN = 0;	                        // 0  : timer 1 oscillator disabled
	T1CONbits.TMR1CS = 0;	                        // 0  : use the internal clock
	T1CONbits.RD16 = 1;                             // 1  : timer 1 register operations are done in one 16-bit access							
	IPR1bits.TMR1IP = 0;				// 0  : timer 1 overflow interrupt is low priority (leave at 0 on IFI controllers)
	PIR1bits.TMR1IF = 0;				// 0  : timer 1 overflow hasn't happened (set to 0 before enabling the interrupt)
	PIE1bits.TMR1IE = 0;				// 0  : disable timer 1 interrupt on overflow (i.e., a transition from FFFF->0)
	T1CONbits.TMR1ON = 1;				// 1  : timer 1 is enabled (running)
}
............................................................................................
void Int_6_Handler(unsigned char RB7_State)
{
if (RB7_State == 1) {//Clear the timer on the rising edge.
	TMR1L = 0x00; // LSB-TMR1
	TMR1H = 0x00; // MSB-TMR1
}
if (RB7_State == 0) {//Read the timer on the falling edge
	Timer1_Buffer = TMR1L; //Read LSB to 8 bit
	Timer1_Instant = TMR1H; //Read MSB to 16 bit
	Timer1_Instant <<=8; //Shift MSB 8 bits
	Timer1_Instant += Timer1_Buffer; //Append LSB
	//Now convert this into another value (degrees) based upon time.
	//With the 8:1 prescale, a value of 1 on the timer = 800nS.
	//1000nS = 1uS
	//1000uS = 1mS
	//10000nS = .01mS
	//800nS = .008mS = 1 "click"
	//# clicks * .008 = mS
	//(mS - 1)*10 = degrees
	//((Clicks * .008) - 1) * 10 = degrees
	//1mS to 36.99mS (0-360 degrees, 1mS offset)
	Timer1_Readable = ((Timer1_Instant * .008) - 1) * 10; //Copy to the reader variable, after processing the value (converting to degrees).
}
}
The logic seems OK, I think...

Timer1_Readable is an extern variable declared in interrupts.h. I am using a simple printf of an int from my user_routines.

Could it be that the timer is not resetting as it should? I'm going to look for a pattern now...
  #15   Spotlight this post!  
Unread 29-10-2006, 13:35
yongkimleng yongkimleng is offline
deus ex programmeur
AKA: James Yong
FTC #0747
Team Role: Mentor
 
Join Date: Aug 2006
Rookie Year: 2004
Location: Singapore, West
Posts: 134
yongkimleng is a jewel in the roughyongkimleng is a jewel in the roughyongkimleng is a jewel in the rough
Send a message via MSN to yongkimleng
Re: Help needed timing a pulse (2004 Robovation)

Quote:
Originally Posted by Josh Siegel
Thanks guys,
I think I understand the concept now!
I wrote some code that (should) work, but doesn't. It reads random values, even if the sensor is still. I can understand how it might read the same error each time, but if the pulse is right, it shouldn't vary every loop, should it? So I guess, I'm trying to figure out of it's something to do with my wiring, or something in the program itself. I don't have access to an oscilliscope to check it, sadly.
Here's the code:
From interrupts.c
Code:
void Initialize_Timer_1(void)  
{
	TMR1L = TMR1H = 0x00;		           	// LSB-TMR1 (read/write) = MSB-TMR1 (read/write) = 0
	T1CONbits.T1CKPS0 = T1CONbits.T1CKPS1 = 1;	// 1,1: 1:8 prescaler (clock=1.25MHz/each tick=800ns)
	T1CONbits.T1OSCEN = 0;	                        // 0  : timer 1 oscillator disabled
	T1CONbits.TMR1CS = 0;	                        // 0  : use the internal clock
	T1CONbits.RD16 = 1;                             // 1  : timer 1 register operations are done in one 16-bit access							
	IPR1bits.TMR1IP = 0;				// 0  : timer 1 overflow interrupt is low priority (leave at 0 on IFI controllers)
	PIR1bits.TMR1IF = 0;				// 0  : timer 1 overflow hasn't happened (set to 0 before enabling the interrupt)
	PIE1bits.TMR1IE = 0;				// 0  : disable timer 1 interrupt on overflow (i.e., a transition from FFFF->0)
	T1CONbits.TMR1ON = 1;				// 1  : timer 1 is enabled (running)
}
............................................................................................
void Int_6_Handler(unsigned char RB7_State)
{
if (RB7_State == 1) {//Clear the timer on the rising edge.
	TMR1L = 0x00; // LSB-TMR1
	TMR1H = 0x00; // MSB-TMR1
}
if (RB7_State == 0) {//Read the timer on the falling edge
	Timer1_Buffer = TMR1L; //Read LSB to 8 bit
	Timer1_Instant = TMR1H; //Read MSB to 16 bit
	Timer1_Instant <<=8; //Shift MSB 8 bits
	Timer1_Instant += Timer1_Buffer; //Append LSB
	//Now convert this into another value (degrees) based upon time.
	//With the 8:1 prescale, a value of 1 on the timer = 800nS.
	//1000nS = 1uS
	//1000uS = 1mS
	//10000nS = .01mS
	//800nS = .008mS = 1 "click"
	//# clicks * .008 = mS
	//(mS - 1)*10 = degrees
	//((Clicks * .008) - 1) * 10 = degrees
	//1mS to 36.99mS (0-360 degrees, 1mS offset)
	Timer1_Readable = ((Timer1_Instant * .008) - 1) * 10; //Copy to the reader variable, after processing the value (converting to degrees).
}
}
The logic seems OK, I think...

Timer1_Readable is an extern variable declared in interrupts.h. I am using a simple printf of an int from my user_routines.

Could it be that the timer is not resetting as it should? I'm going to look for a pattern now...
ehh 2 points:
1. get a signal generator/constant pulse source to test, if possible
2. Timer1_Readable is declared as what? Try to avoid things like multiplying by 0.008 .. you may need to define Timer1_Readable as a float or single..
As much as possible when it comes to complex calculations, I'd use a lookup table to speed things up and increase reliability
__________________
| jamesyong.net |
FVC2007, FTC2008
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
HELP-URGENT PROGRAMMING HELP NEEDED Rohith Surampudi Lego Mindstorm Discussion 1 24-03-2006 23:05
Please Help: Programming the Robovation Kit wmurphy Robotics Education and Curriculum 14 08-12-2004 12:57
robovation KIT help Mirza95vx Technical Discussion 2 03-12-2004 15:08
2004 WPI EBOT Competition (using Robovation robots) ahecht Off-Season Events 3 04-11-2004 21:25
PUlse counting junkyarddawg Technical Discussion 1 31-01-2002 15:33


All times are GMT -5. The time now is 02:06.

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