Pulse detection inaccurate?

Discussion about the ZBasic language including the System Library. If you're not sure where to post your message, do it here. However, do not make test posts here; that's the purpose of the Sandbox.
Post Reply
pjc30943
Posts: 220
Joined: 01 December 2005, 18:45 PM

Pulse detection inaccurate?

Post by pjc30943 »

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: Select all

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

Attachments
logic traces.GIF
(38.09 KiB) Downloaded 2074 times
Paul
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Re: Pulse detection inaccurate?

Post by dkinzer »

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: Select all

  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.
- Don Kinzer
pjc30943
Posts: 220
Joined: 01 December 2005, 18:45 PM

Post by pjc30943 »

You are right, disabling interrupts did the trick; the pulses from DebugPin are now identical. Thanks Don.
Paul
Post Reply