PDA

View Full Version : PWM measurement


kneedown
09-03-07, 09:59 AM
My IsopodX application reads analogue and PWM inputs. For the PWM inputs I have used the following example code:

TA2 ACTIVE-HIGH SET-PWM-IN BEGIN TA2 CHK-PWM-IN ?DUP UNTIL

My problem is that if the PWM input is permanently low (i.e. there is no signal) then the code waits forever to see a rising edge and hangs the program. How can I detect whether there is a signal or not to avoid this problem?

RMDumse
09-03-07, 02:06 PM
The idea behind IsoMax(TM) is to avoid loops that capture the program counter. By using a BEGIN UNTIL loop, you waste ALL the processors power checking to see if the end of pulse has come yet. It can do nothing else but continuously look for that to happen.

So how can we get past that? Well, we need a different programming style. We need to occassionally check for the pulse to end without completely taking up the processor. How? Put the task into the background, and set how often it runs. So make a thread that checks the result, and schedule it to run on a periodic basis.

See the SRF04 code example. But it is older and goes directly to the timer registers, where we want to use the SET and CHK-PWM features.


VARIABLE TA2-READING
VARIABLE TA2-READING-AGE

: TA2-PWM?
TA2 CHK-PWM-IN
DUP
IF
TA2-READING !
TA2 SET-PWM-IN ( Reset for next time
0 TA2-READING-AGE !
ELSE
TA2-READING-AGE 1+!
THEN
;

TA2 SET-PWM-IN ( Set going very first time

EVERY 50000 CYCLES SCHEDULE-RUNS TA2-PWM?


Now, whenever you check TA2-READING, it will have the latest pulse width read in it. In TA2-READING-AGE will be the tick counts since it was last read.

Hope that helps.

kneedown
09-05-07, 12:05 PM
Many thanks - your code does the job. I modified it slightly by including it in a state machine rather than using the schedule-runs instruction.

One other (slightly odd) question - when using the timer pins to read PWM do the pins themselves produce any output? I can't imagine why they would but I seem to be getting some interference at my signal sources and wondered whether this might be a cause.

RMDumse
09-05-07, 02:20 PM
when using the timer pins to read PWM do the pins themselves produce any output?

Not that I know of. Can't think of anything unless there's a direction setup issue. You might want to be sure the pins you are using are configured as inputs before using the xxx-PWM-IN words. For instance, read them with ON? and then just DROP the result.

I don't have time right now to explore this, unless you can give me a more definite indication there is a problem, and to do so I'd need your code, but here's what I'd do if I wanted to find out. I'd disconnect the input signal, and put a logic probe on the line. I'd use a reasonable pull up, say 1K, and try to exercise the port. Then I'd switch it to be a pull down, and try again. If I didn't get any pulses detected on the pin by the logic probe, I'd say there's no problem, and no problem is the result I'd expect.

But, stranger things have happened.

If you find something more definitive, let me know.

kneedown
09-12-07, 09:38 AM
Thanks again for your help. I've found that decreasing the number of cycles between samples has improved the readability of my data.

I'm presently measuring signal frequency by measuring both high and low pulse width (sending the same signal to two timer pins) then adding these measurements together to get the period and taking the reciprocal. I've been doing the calculation in a spreadsheet rather than in the IsopodX to save processor time.

Am I missing any better way to get the signal frequency?

RMDumse
09-14-07, 03:23 PM
A more accurate frequency measurement can be had, but it depends on what extremes you are willing to go to, and the range of the highest frequency you're trying to measure. Also, I suppose, how much of the processor you are willing to dedicate to the task.

Have you considered external hardware? If you divide the incoming frequency with a single flip flop you can read the resultant frequency by reading just one side; just high, or just low, for instance. (But you'd miss every other pulse.)

Also, if you use interrupts, and even high level interrupts might work for this if your frequencies are fairly low, you could start measuring the low, and interrupt on the edge, then restart (continue really by chaning the control register) the measurement until next edge.

Just a couple ideas that seem to apply to your question.