pjc30943
Joined: 02 Dec 2005
|
|
Posted: 24 July 2008, 21:20 PM Post subject: Pulse detection inaccurate? |
|
|
EDIT: The first issue (now corrected) was caused by an obvious user error. However, a timing issue remains, explained below.
===================================
After switching over to the 1280n dev board, I'm using ISRs to measure the pulses of a 250Hz pulse train.
With an input pulse train [1/2ms state 0, several ms of state 1] this code usually correctly output a pulse of about 75us onto debugPin, correspondingto roughly 900 TMR5 counts.
But it also outputs incorrect 100-ish us pulse as well, arising from various random other incorrect counts.
LoopTogglePin's state is set at each call of the ISR, and correctly follows the inputs.
A logic analyzer trace is in the attachment. It's possible to see 'output' (LoopTogglePin) always matching the top-most 'thigh' pulses, and the 'debug' (debugPin) output suddenly having a longer (90us) output pulse, as opposed to the two correct neighboring, short 75us pulses (near the edges of the screen).
Any thoughts on why this does not work reliably?
| Code: | public const thighEncoderL as byte = D.0 'int0
public const loopTogglePin as byte = J.0
public const debugPin as byte = J.1
public thighEncoderLPulse as unsignedinteger
public thighAngleL as single
public timerStart as unsignedinteger
public timerEnd as unsignedinteger
dim newchange as boolean
sub main()
putpin thighEncoderL , zxInputTristate
putpin loopTogglePin, zxOutputLow
putpin debugPin, zxOutputLow
'set up TMR5 (encoders)
register.TCCR5A = bx0000_0000 'all 0s set the TMR to normal counter mode
register.TCCR5B = bx0000_0010 '_0xxx = prescaler, DON'T FORGET TO CHANGE TICK_P_S BELOW. 010 = /8, 011 = /64, 100 = /256, 101 = /1024
register.TIFR5 = bx0010_1111 'set bit0 to 1 to clear it.
'~~~~~~~~ INTERRUPTS ~~~~~~~~~
Register.EICRA = Bx0101_0101 '0101_0101 = any edge of INT0,1,2,3
Register.EICRB = Bx0101_0101 'any edge of INT4,5,6,7
Register.EIMSK = Bx0000_0001 'external interrupts 7..0 (corresponding bits of EIMSK)
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
allowChange = true
do
do until newchange = true
sleep 0.0
loop
newchange = false
putpin debugPin, 1
sleep csng(thighEncoderLPulse) / 1000000.0 'debug the measured TMR5 counts
putpin debugPin, 0
loop
end sub
ISR INT0()
'ISR for thighL joint encoder
if ( getpin(thighEncoderL) = 0 ) then
timerStart = register.TCNT5
putpin loopTogglePin, zxOutputHigh
else
timerEnd = register.TCNT5
putpin loopTogglePin, zxOutputLow
thighEncoderLPulse = timerEnd - timerStart
newchange = true
end if
End ISR
|
| Description: |
|
 Download |
| Filename: |
logic traces.GIF |
| Filesize: |
38.09 KB |
| Downloaded: |
287 Time(s) |
|
|
dkinzer Site Admin
Joined: 03 Sep 2005
Location: Portland, OR
|
|
Posted: 25 July 2008, 2:13 AM Post subject: Re: Pulse detection inaccurate? |
|
|
| pjc30943 wrote: | | Any thoughts on why this does not work reliably? | The deviation in pulse width is only 15uS or about 220 CPU cycles. It is quite likely that servicing the RTC interrupt is causing the variation. I would suggest the following code as an alternative for "echoing" the received pulse on the debugPin.
| Code: |
Dim sreg as Byte
sreg = DisableInt()
Call PutPin(debugPin, 1)
Call PulseOut(0, csng(thighEncoderLPulse) / 1E6, 0)
Call PutPin(debugPin, 0)
Call EnableInt(sreg)
| It it important to note that the resolution of PulseOut() is 1.085uS.
An alternate method to view the value thighEncoderPulse is to output the value serially (using ShiftOut()) or, perhaps, as two sequential outputs to an 8-bit port. Both of these methods would allow you to "see" the measured value of the input pulse using a logic analyzer.
|
|