alt.fan.frank.mccoyShow header Prev. Next
Re: Ping Frank! C code enclosed. S.F.P.I.A
Frank McCoy (mccoyf@millcomm.com) 2004/07/21 17:44

In alt.fan.frank.mccoy Öldman© <b@ld.is.best> wrote:

>Are you familiar with the term "moving window averaging"?
>
Quite familiar; having done similar things named "impossible" on the
old PTS with just one counter that worked somewhat like you described.
Of course, Windows complicated things a bit by being asynchronous; and
you having several free-running counters (as I see it).

>Our RPM counters need to run two different sample rates,
>the first at 100 RPM and up - the second for 100 RPM and
>down. The sample rate needs to be higher for the lower
>RPM values to sense 'stall' on the motor under test.
>The data is used to plot torque curves and stall happens
>within 2 seconds from approx. 1200 RPM when load reaches
>critical. We found a LOT of 'jitter' in our values due to
>low sample rate and clock speed of the PLC presently used.
>The 'work around' was to accumulate counts then average.
>This issue was never fully resolved - I think partly due
>to the programers level of expertize and partly due to
>the clock speed of the PLC.
>
If done *right* then the low speed becomes an *advantage* not a
disadvantage; and can make for greater accuracy.  The trick is to
count both clock-ticks and rpm pulses close to the limit of the time
you have; the lower-frequency of the two being used as the thing-timed
and methods used to ensure it's accuracy; while the faster-counting
tick is used to measure the slower; then dividing the two.

In a Windows environment, this often means doing a "no no" and halting
interrupts while the start of a tick is found and measured then
allowing them once the faster counter's position is known; then
repeating the process at the end of an interval.  For true accuracy,
both counters should be free-running; NOT stopped and restarted; with
each successive measurement taking in the difference from the previous
count.  If a high-frequency and fairly accurate clock-counter is
available, then the overall accuracy can be quite good, even measuring
only single snapshots.  By doing things like running averages, even
more accuracy can be obtained; gaining somewhere around half the
totals averaged times the original.

That's: If one interval gives you accuracy of plus or minus ten
counts, then averaging ten intervals will give you an accuracy of
about plus or minus two counts for a single interval, or plus or minus
about 20 counts for the total:  A five to one improvement.  (Yeah, I
know ... It *should* work out to a ten-to-one improvement; but rarely
does.)

One trick many people often miss is scaling:
You scale the larger number to fit the smaller, or the smaller number
to fit the larger, until you get maximum accuracy for your upcoming
division; then adjusting the result back to compensate once the
division is done.  If using floating-point, this isn't so important;
but when sticking to straight digits for speed, it can make enormous
differences in the accuracy.  Oftentimes using floating-point for
divides takes up more time between measurements than you have
available.

>I proposed that the program be set up to accumulate counts
>for X clock cycles as a 'snap shot' then average as many of
>these 'snap shots' as practical due to jiffy timer to
>obtain readings quickly enough. This worked well for the
>higher RPM values but not for the low end (not enough plot
>points to draw the curve properly).
>
>Possible that you know a better way?
>Is there a way to 'split' clock cycles (jiffies) with
>software? Can we 'roll our own' timer somehow?
>
Generally, on a Windows System, the system clock is the best you've
got ... and it sucks rocks royally!  I've used it though; and it does
work.  Better, is if you can have an independent timer.

Seems to me, I remember Windows (and DOS) having available either one
or two timers on board the PC, that were (supposedly) available to the
programmer; and LEFT so.  The problem being: Some *other* programmer
running a program on the PC might well have decided he/she needed them
already ... and thus interfering with your usage.   ;-{

Best would be a free-running and readable clock on the hardware
itself, if possible.  The higher the frequency of the counter, and the
longer the counter length, the better.  Otherwise, we're stuck with
the system clock.   ;-{

>This issue will determine whether we keep using the
>present unit or 'upgrade' the hardware!

The only problem I see with doing this, is running tests on the actual
hardware so I could see what results I got when taking measurements.
The actual programming itself seems to be a minimal design problem.

On the program itself:
Um ... First, I'd need the "defines" or *.h files.

Mostly (I assume) because of the missing *.h files,
Compiling the source gives me the following errors:

Error counter.c 21: Undefined structure 'clock'
Error counter.c 21: Size of structure or array not known
Error counter.c 22: Undefined structure 'sensors'
Error counter.c 22: Size of structure or array not known
Error counter.c 23: Undefined structure 'scale_vals'
Error counter.c 23: Size of structure or array not known
Error counter.c 29: Unable to open include file 'filename.h'
Error counter.c 31: Unable to open include file 'database.h'
Error counter.c 32: Unable to open include file 'iohw.h'
Error counter.c 33: Unable to open include file 'primitiv.h'
Error counter.c 34: Unable to open include file 'protocol.h'
Error counter.c 35: Unable to open include file 'rtc.h'
Error counter.c 36: Unable to open include file 'serial.h'
Error counter.c 74: Undefined symbol 'com1' in function main
Warning counter.c 74: Non-portable pointer conversion in function main
Warning counter.c 75: Non-portable pointer conversion in function main
Error counter.c 82: Undefined symbol 'TRUE' in function main
Warning counter.c 84: Possibly incorrect assignment in function main
Warning counter.c 86: Possible use of 'timeout' before definition in
function main
Error counter.c 91: Undefined symbol 'IO_SYSTEM' in function main
Error counter.c 92: Undefined symbol 'MODBUS' in function main
Error counter.c 92: Undefined symbol 'INPROGRESS' in function main
Error counter.c 98: Undefined symbol 'BEGINDATA' in function main
Error counter.c 98: Undefined symbol 'BEGINAOUT' in function main
Error counter.c 107: Undefined symbol 'ENDDATA' in function main
Error counter.c 128: Undefined symbol 'rpm' in function main
Error counter.c 128: Undefined symbol 'STOPPED' in function main
Error counter.c 156: Undefined symbol 'OPEN' in function init_scale
Error counter.c 158: Undefined symbol 'flow' in function init_scale
Error counter.c 158: Too many error or warning messages in function
init_scale
*** 25 errors in Compile ***

        Available memory 396496

--
    _____
     /  '               / ™
  ,-/-, __  __.  ____  /_
 (_/   / (_(_/|_/ / <_/ <_

Follow-ups:12345678910111213
Next Prev. Article List         Favorite