View Full Version : Pulse width variation
kneedown
10-27-08, 08:37 AM
I'm feeding a steady square wave signal to TA2 at just under +3 v max on an IsopodX but the measured pulse width varies significantly according to what value I put in the line EVERY XXXXX CYCLES SCHEDULE-RUNS ...
Surely the pulse width measurement should be constant regardless of the interrupt rate or am I missing something here?
RMDumse
10-27-08, 08:53 AM
When done correctly, for the same pulse width input you should get very nearly the same number each time.
Two things come to mind, with a common root. First, you must do a SET-PWM-IN to initialize the timer for capture. If you do it once in initialization, and not in every background scan, CHK-PWM-IN will return varying values after the first good reading.
When you do the SET-PWM-IN, each time you do CHK-PWM-IN you will get zeros until the first time the cycle completes, then you will get a valid time. Continuing to read past this first valid reading will return varying values.
So check for 0's, and only use first valid return before repeating SET-PWM-IN and again eliminating 0's.
Done this way, your result should be independent of the background rate.
kneedown
10-27-08, 09:05 AM
Thanks for such a rapid response!
I have:
TA2 ACTIVE-HIGH SET-PWM-IN
to initialise and then get the readings using:
: TA2-PWM?
TA2 CHK-PWM-IN
DUP
IF
RPMHIGH C! \ pulse width high
TA2 SET-PWM-IN
0 TA2-READING-AGE C!
ELSE
30 RPMHIGH C!
TA2-READING-AGE 1 + TA2-READING-AGE C!
THEN
; EEWORD
It seems to me that this meets the requirements that you laid out?
RMDumse
10-27-08, 09:26 AM
I agree, most of the code you show, and certainly the ordering of the code looks good, with some problems as noted below.
One thing bothers me though. Why all the C!'s? On a 16-bit processor, it is much more natural to use !'s as opposed to C!'s unless you specifically need a character store. So you are only saving 8-bits of the result, rather than the full 16.
Also just a style comment TA2-READING-AGE 1+! will increment a location. I think what you had, lacking any sort of fetch, was probably wrong.
TA2-READING-AGE 1 + TA2-READING-AGE C!
This adds one to the address, and stores half the result back into the variable.
Oh another thing. You do a DUP IF which copies the result and the IF branch consumes the copy if non-zero. But if it is zero, the ELSE branch does not DROP the unwanted 0 copy, so there's a stack imbalance.
kneedown
10-27-08, 09:42 AM
Thanks - I'll address the issues that you raised.
kneedown
10-27-08, 11:09 AM
I've corrected the items that you pointed out in your earlier response but I still get the pulse width variation problem. Using exactly the same input code but changing only the CYCLES number I get the following:
CYCLES Pulse width mS
2500 2.4
25000 3.9
33000 2.3
45000 3.8
50000 8.6
The pulse width is repeatable for a given CYCLES value.
I can't see any particular pattern here. My oscope shows the actual input signal pulse width as 0.28 mS though I am not sure of the calibration accuracy of the oscope. I'd value your comments.
RMDumse
10-27-08, 02:07 PM
i agree, there's an odd pattern, if any, here.
How do you know the MS decimal place in the printout? I'm concerted if perhaps you are read out might have a bug in it.
Are you printing out the raw value from the capture? to be sure of what the result of the CHK-PWM-IN is getting?
Oh wait. Why are you storing into RPMHIGH if CHK-PWM-IN is zero?
30 RPMHIGH C!
This will overwrite a good reading, once it is capture, before another new reading is taken. Note that as soon as one value is captured, you should leave it alone until you have another new value to replace it.
kneedown
10-28-08, 04:51 AM
The plot thickens...
I amended the word that reads the pwm to erase the line storing to RPMHIGH as you suggested and to output the time and measured value to the terminal thus:
: TA2-PWM?
TA2 CHK-PWM-IN
DUP
IF
RPMHIGH ! \ pulse width high
TA2 SET-PWM-IN
0 TA2-READING-AGE !
TCFTICKS @ .
RPMHIGH @ .
0D . \ helps format the output when copied into Excel
ELSE
DUMMY ! \ drops the unwanted zero copy from stack
TA2-READING-AGE @ 1 + TA2-READING-AGE !
THEN
; EEWORD
This word is called by a state machine so an attempt is made to get the pulse width every time the machine chain runs. When I operate a switch, PB2 is grounded and then the value in RPMHIGH is sent via SCI1 to a memory card - this is also in the machine chain but I guess everything slows down a bit when writing to the memory card.
For this investigation I took the terminal output measured values of time and pulse width and in Excel converted HEX to DEC and then x 0.4/1000 to get the value in mS.
The measured values still show the pulse width variation at different values of CYCLES. I have also found another intriguing anomaly - my program autostarts and I have a manual switch that grounds PB2 in order to start sending captured measured values of pulse width to a memory card via the SCI1. I noticed that when PB2 is grounded the measured pulse width values step change upwards although on the oscope the pwm pin signal doesn't change at all. When the switch is operated again the measured values step change back down to their previous values? Help!
kneedown
10-28-08, 06:53 AM
After studying my output further I see that the output stream shows values varying from a low but constant value up to the high and varying values that I quoted in an earlier post. The low, constant value is in fact very close to the oscope measured input signal pulse width and does not change with CYCLES. I had neglected these low values because I had assumed that they represented zero readings.
If these low values are indeed the true pulse width measurement I am at a loss to know why am I seeing lots of very high values thrown in?
RMDumse
10-28-08, 02:26 PM
Generally, when you read the CHK-PWM-IN over again after one successful read, and not reset it with the SET-PWM-IN action, that's when you get odd readings with patterns of multiples. Of course then your periodic rate will come into play. For instance, if you read something that is 2.4mS long, and you are doing the background every 10 mS (50000 cycles) you may get multiples of 2.4, 4.8, 7.2 and 9.6, however, you can also wrap around the next cycle too, and get 1.8, 3.2, and so on.
The real mystery here is why, if a result passes the non-zero test, and you take the IF path, why doesn't it reset and start over fresh? Usually someone forgets to reset the timer check, and gets invallid numbers. But it looks like you do reset it. Unless there's some odd timing issue where another edge comes in before the TA2 SET-PWM-IN comes on. Even that makes very little sense.
The first non-zero value for the pulse width should be read and captured, and not changed until another CHK or SET is done. Another CHK would give the odd multiples.
You should try this by hand, without anything running in the background, to convince youself it works.
Do a
TA2 SET-PWM-IN TA2 CHK-PWM-IN . TA2 CHK-PWM-IN .
on a single line. You should probably see a 0 for the first print, and because the delay of the print, the second time should get your first single pulse captuer (assuming pulses are continuously arriving around 5mS). A third print might be some multiple, or rather a wild value, because if you're typing by hand, many pulses will probably go by.
Please try that and report the result. Maybe we can narrow things down if we get some additional data on what's going on.
kneedown
10-29-08, 08:22 AM
I carried out the test you suggested and get the following output (decimal):
2137 21280
2137 21283
2137 21282
2137 17505
0 17505
2137 21281
0 21282
0 17506
0 21280
0 21280
0 17506
0 17507
0 17506
2137 17507
2137 21281
2137 21280
0 14387
0 17507
0 17506
2137 21281
2137 21281
The first reading and second reading are a factor of almost 10 different and the lower readings are a factor of about 3 larger than the actual input signal pulse width.
After reading another thread I though it worth ensuring that my input signal was good so I made pin TA3 an output with pulse width 0.3 mS and 50% duty cycle and fed the output straight into pin TA2. This is the output (mS) that I got as pulse width readings from TA2:
0.9
1.8
0.2996
0.2996
0.8996
0.2996
0.2996
0.2996
0.8996
1.2
0.2996
0.2996
0.8996
0.8996
0.2996
0.2996
0.8996
1.2
0.2996
So we seem to be seeing the correct pulse width (0.3 mS) a lot of the time but with x3 and x4 values appearing too.
Now for comparison here is an output based on my own (i.e. external) input signal:
0.3488
0.3488
1.1072
1.5168
1.168
0.7588
1.4564
0.3488
0.3488
1.1072
1.5168
0.3488
0.3488
1.1076
0.3488
0.3488
1.168
Once again we seem to have the correct pulse width (0.3488) some of the time but with x~3 and x~4 factor variations too.
Does any of this shed any more light on the problem?
kneedown
10-29-08, 10:08 AM
I noticed that the erroneous measurements always occur immediately after a zero measurement (I did this by examining the value of TA2-READING-AGE). So I tried adding TA2 SET-PWM-IN within the ELSE part of the code. The idea being that if a zero measurement has been detected, the present pulse measurement will be abandoned and the pulse width measurement restarted.
This appears to do the trick in that all of the output was then simply the correct pulse width value with no dodgy values. I need to think about this a bit more in case I'm doing something stupid - perhaps you would point out any problem you might see with what I've done.
RMDumse
10-29-08, 02:44 PM
Boy, this sure looks like a classic case of "something else going on" if I've ever seen one. It's like the problem we're working on is not the problem at all. I run into these often when helping people debug problems. The reason it is not solving is because the problem isn't what we're looking at.
For instance, maybe there's another piece of software working on another timer, and it accidentally has a TA2 in it which was supposed to be edited to TA0 and missed. Something unaccounted for like that may be going on here.
Before the test where you output a pulse on another timer pin (I started working on that last night here to suggest before you went ahead and did it) I was beginning to think you had noise in your ground line, and you weren't getting the edges into the timer when you thought you were.
But pulses coming from one timer should make it to the other timer without fail, so I am wondering what else is going on you haven't told me about.
You see, once a timer captures a value after a SET-PWM-IN, nothing should release it until the first CHK-PWM-IN. Almost seems when you show me those 3x values something else is hitting your timer when you don't expect it. So I'm beginning to conclude the problem is something else in your code is running and twinkling the timer in some way.
I feel fairly confident you should have captured the correct time or a zero with the:
TA2 SET-PWM-IN TA2 CHK-PWM-IN .
line, and if you captured a zero, then the next TA2 CHK-PWM-IN . should have given the right value.
Either that, or, the pulse isn't what you think it is (such as noise on the ground so only every third pulse registers for instance).
Another very unlikely thing might be a short on the board of TA2 to some other signal, or something bizarre like that, but that again would be very rare.
Were you SCRUB's and reset with no other program in memory when you ran those tests? Because if there was something looking in on TA2 in the background while you were trying that line in the foreground, you could get results like you've shown.
RMDumse
10-29-08, 04:08 PM
Let me show you some simple basics that may help convince you the examples work. I'll go back to as simple and direct use of the language commans as possible. Look at the below captured session. I have physically jumpered TA0 over to TA2 on an IsoPodX(TM) to allow pulsing out on TA0 and measuring it on TA2. The width of the pulse is just a delay which is an accidental, or arbitrary, value, depending on how long it takes the interpreter to translate the actions in the line. None the less, if it is consistent, we can tell if we are getting a reasonable reading or not.
IsoMax V0.82
HEX OK
TA0 OFF OK ( Make TA0 low
TA2 SET-PWM-IN OK ( Set up TA2
TA0 ON TA0 OFF OK ( Pulse
TA2 CHK-PWM-IN . 1FFF OK ( Time based on interpretation taken to do pulse
Okay, so it gives an arbitrary 1FFF for an answer. That value will very between version of the code, and be longer if there are additional defintiions to sort through, and turning on the background task would slow the foreground task, etc. But let's just see if we repeat the same test we get approximately the same number.
TA2 SET-PWM-IN OK ( Repeat give same
TA0 ON TA0 OFF OK
TA2 CHK-PWM-IN . 1FFF OK
OK
TA2 SET-PWM-IN OK ( Repeat give same
TA0 ON TA0 OFF OK
TA2 CHK-PWM-IN . 1FFF OK
So normal use, looks fine and repeatable. We got the same count of the pulse width for three tests.
What happens if you call CHK-PWM-IN before there is at least one pulse?
TA2 SET-PWM-IN OK ( Set up TA2
TA2 CHK-PWM-IN . 0 OK ( Chk before pulse is 0
TA2 CHK-PWM-IN . 0 OK
TA2 CHK-PWM-IN . 0 OK
TA2 CHK-PWM-IN . 0 OK
TA2 CHK-PWM-IN . 0 OK
TA0 ON TA0 OFF OK ( Pulse
TA2 CHK-PWM-IN . 1FFF OK
TA2 CHK-PWM-IN . 1FFF OK
TA2 CHK-PWM-IN . 1FFF OK
TA2 CHK-PWM-IN . 1FFF OK
TA2 CHK-PWM-IN . 1FFF OK
Reads after SET and before pulse always return zeros as advertised.
Reads following pulse stay the same...at least once unless there is a new pulse, which will disturb the reading as you will see in the immediate follow on below.
TA0 ON TA0 OFF OK ( Pulse
TA2 CHK-PWM-IN . -4729 OK
TA2 CHK-PWM-IN . -4729 OK
TA2 CHK-PWM-IN . -4729 OK
TA2 CHK-PWM-IN . -4729 OK
TA2 CHK-PWM-IN . -4729 OK
OK
TA0 ON TA0 OFF OK ( Pulse
TA2 CHK-PWM-IN . -272A OK
TA2 CHK-PWM-IN . -272A OK
TA2 CHK-PWM-IN . -272A OK
TA2 CHK-PWM-IN . -272A OK
TA2 CHK-PWM-IN . -272A OK
So let's just verify that "at least once" concept, that if we do a SET and a pulse, the next time we do a CHK we get the time from that first pulse, and not from some later pulse.
TA2 SET-PWM-IN OK
TA0 ON TA0 OFF OK ( Pulse
TA0 ON TA0 OFF OK ( Pulse w/o SET
TA0 ON TA0 OFF OK ( Pulse w/o SET
TA0 ON TA0 OFF OK ( Pulse w/o SET
TA2 CHK-PWM-IN . 1FFF OK ( Still holding 1st
TA2 CHK-PWM-IN . 1FFF OK
TA0 ON TA0 OFF OK ( Pulse w/o SET
TA2 CHK-PWM-IN . 3F2F OK ( Now holding diff.
TA2 CHK-PWM-IN . 3F2F OK
There it is, the first pulse width was captured and held until the first CHK. But after the first CHK, any other pulse and CHK will be possibly erroneous.
So used correctly, CHK-PWM-IN will return zeros after a SET-PWM-IN, until it returns a different value after a pulse.
Since the hand operated examples all work here, I suspect they will work as you've used them as well...unless something else is going on, twittling with TA2 settings. You didn't use TA2 as a chip select for the streamed memory or such, that might be interfering with it's pulse width measurement tasks?
kneedown
10-30-08, 09:09 AM
Many thanks for your help with this. I understand your concern that the problem lies in my code or maybe is a result of hardware issues such as a poor ground etc. I shall of course keep investigating these aspects and will let you know if I identify the culprit. So far as the code is concerned there are no obvious occurrences of misuse of TA2 which might cause the problems (I searched the code for "TA2" to find all occurrences).
I won't be able to give your latest post the attention it deserves for a few days as I'll be away. However I am grateful for your help.
kneedown
11-05-08, 10:22 AM
OK I understand what you've demonstrated in your last post.
The effect of repeated CHK-PWM-IN without a SET-PWM-IN after each CHK is clear but what is the effect of using SET-PWM-IN if a SET-PWM-IN is already in force and no CHK-PWM-IN has been performed? In this situation a SET-PWM-IN is being issued when either a pulse is awaited, is being measured or has completed measurement but the result hasn't been accessed by a CHK-PWM-IN.
Does a repeated SET-PWM-IN have any affect?
RMDumse
11-05-08, 10:53 AM
A repeated SET-PWM-IN just reinitializes the timer for capture. So it will wipe out anything captured, and set things back ready to do a capture.
Basically doing it often enough will prevent you from ever actually getting a result, so it can be over done.
But I hope you are picking up what I was trying to say about "not the whole story". Because what you showed for results could not have happened if what you showed was all that was going on. Again, I'm worried about a loose ground, or, some other code twittling the timer, or something of that nature.
You see, over the years, I've come to conclude our customers as a whole are pretty smart. If it was a simple problem, they'd fix it themselves. But if it doesn't fix easily, they're probably working on the wrong problem.
I can only see the problem through what you report. But you report things according to what you think the problem is. And if that were indeed the problem, you would have already fixed it. So I find myself most helpful when I suggest backing up and taking a broader view of the problem.
So what I've tried to do above is use SET-PWM-IN and CHK-PWM-IN with the absolute least amount of frills or programming possible, so you can restore your faith in the words and be less in doubt they do what they do.
But it looks like you are using them correctly in your code, so that's why I say the problem we're working on is not the problem. That's my best sense of what's going on, given the reports I'm working with.
vBulletin v3.0.7, Copyright ©2000-2012, Jelsoft Enterprises Ltd.