Pulse Width Measurement Example?
DavidGreg
Posts: 38
Page 204 of the "Propeller Manual" says that the CTR registers can be used for measuring pulse widths. Is there an example available showing how to do this?
Comments
Since you haven't got any way to synchronise to this edge except to wait for it, this more or less ties up the cog until the measurement is made, i.e. it isn't much better than measuring the pulse width using only software.
The resolution is better using the counters, but the latency requirements (the time available between the pulse ending and the software acting on it) are just as strict.
I'd be really pleased if someone would correct me and tell me there's a way to capture sysclk or some other counter value on a pin transition.
It's possible to capture CNT in less than 100ns from a pin transition using assembly language. The same thing works in Spin, but slower (WAITPEQ, then X := CNT).
Using the counter this way will yeild an exact measurement (even in spin)·so long as the code has enough time to execute in the respective on/off periods.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Propeller Applications Engineer
Parallax, Inc.
Post Edited (Paul Baker (Parallax)) : 6/24/2008 11:52:28 PM GMT
Post Edited (DavidGreg) : 6/25/2008 2:38:05 AM GMT
mask := %0110 'pins 1 and 2
state := INA & mask
port := 0
When waitpne returns, XOR (INA & mask)·with state to see which bit(s) changed.
Given the fact that you're doing a servo pulse width with only millisecond precision, this should be no problem in SPIN.
[noparse][[/noparse]code]
repeat
· state := INA & mask
· waitpne(state, mask, 0)
· result := (INA & mask ^ state) & state ' result will have 1's where bit changed and previous state was 1
· if result & %0010
··· pulsewidth[noparse][[/noparse]1] := phsa
··· phsa~
· if result & %0100
··· pulsewidth[noparse][[/noparse]2] := phsb
··· phsb~
[noparse][[/noparse]/code]
somebody hit me over the head if there are errors here, but this is the general idea.
·
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Post Edited (Ken Peterson) : 6/25/2008 3:21:45 PM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Propeller Applications Engineer
Parallax, Inc.
I misspoke in my above post - I want to calculate the pulse-width in integer micro-seconds, as would be used as an input to the Servo32v3 object.
I want to read the pulses from a "standard" RC receiver (is there such a thing?). From what I can tell using Google, RC receivers use a sort of round robin schedule for controlling the servos. So maybe I could assume that the individual pins are never on at the same time, in which case it might be possible to determine the pulse width from multiple inputs with a single counter?
I suppose I could try to scope the output from one of my receivers, but I'm concerned that not all receivers would be the same. Perhaps someone out there would be able to shed light on whether RC receivers tend to be consistent.
-David
UPDATE -
This code works great for a single channel.
Post Edited (DavidGreg) : 6/26/2008 1:33:24 AM GMT
Well, it appears as tho assuming that the pulses are never active at the same time works for at least one RC servo (in this case, a Great Planes Electrifly 4 Channel).
I've attached my code for reading the pulses. It works for my purposes, but I think with a small amount of work it would make a nice generic object that would be useful in many projects. The part I'm missing is how to pass arrays. I'd like to pass an array of longs containing pin numbers (and its length perhaps?) in to my object and be able to pass out an array of the servo pulse widths in microseconds.
However, I haven't had much luck with passing arrays. The propeller manual doesn't seem to help and I can't find any info on the forum either. Any suggestions (array passing or otherwise) would be appreciated.
-David
http://forums.parallax.com/showthread.php?p=734261