Hi all!
Tim,
> You want a simple first-order lowpass IIR filter. You can implement it
in one line of C:
> output = gain * (input - output);
Either there is some mistake in this, or I'm doing something wrong, but
I'm not getting any attenuation of high frequency components with this.
> A 20Hz cutoff is pretty high for a sampling rate of 50Hz -- you're not
> going to get much attenuation of your noise.
The sampling rate is 100Hz. I might lower the cutoff further. But the
previous implementation of this controller, done in the analog world, used
20 Hz with good results. But that was a third order filter.
> Keep in mind that as you lower the filter bandwidth you'll have to back
> off your pro****tional and integral gains to keep the loop stable.
I know. That's also why I don't want to lower the cutoff frequency too
much.
> You may also find that you need to use more than 16 bits in the filter
to
> maintain enough precision
That would be a problem, because in the programming language I'm using, I
only have 16 bit integers, and no carry bit.
> You may find some of the other articles on my website interesting:
> http://www.wescottdesign.com/articles.html.
I found the one about PID controllers particularly useful. I was limiting
the integral value after applying the gain. In the example you give in
that
article, the value is limited in the Istate, before applying gain, and
that
indeed has some advantages. So I will shamelessly copy that idea!
> And of course, if you want to get the full meal deal, check out my book.
> It puts the math back in, but I tried to keep it grounded in reality.
It sounds to me like there will be too much math for my taste! I'm pretty
allergic to that. As soon as there is more than one equation per page, or
any equation longer than 6 terms or so, I tend to put a book away! This is
also why I haven't found my way into DSP so far. I tried with a TMS320 kit
many years ago, and never got to do much with it. It was quite
frustrating,
because all explanations I could find used so much math that I couldn't
follow them.
Hardy,
> Yes - it's called a resistor and a capacitor. Put the capacitor to
> ground and the resistor in series. Voila and no programming - now
> that's such a great discovery that two components can do better than a
> pic.
You are right, but at this moment I'm driving along the road in the
opposite way! I have a functioning analog controller. The low pass filter
in it is active, third order, built around an op amp, and works great. But
I now want to digitize the whole thing, for some advantages this approach
gives, and also as an exercise!
I cannot just add the RC low pass filter, because the signal I need to
filter exists inside the PIC, and is needed inside the PIC. Putting it out
through a DAC, to filter it with an RC, and then again acquiring it
through
an ADC, would be rather inelegant!
Scott,
> That's pretty much the answer. You can choose ideal weightings
according
> to what your goals are, but a moving average is what things come down
to.
OK. I will "try to try"!
> One caveat is that unless you're a bit careful, using timer interrupts
> and the like to trigger your sampling, you could have a good deal of
> jitter in your sample rate, and the math behind the low pass filter can
> get pretty complicated.
I'm not using interrupts, but indeed I have some jitter because I'm
sampling the zero crossing inside a waiting loop. The loop is only two
instructions long, but that still gives a jitter of 4 microseconds. Not
much, but maybe noticeable.
The jitter caused by the distortion of my 50Hz signal is much larger than
that, anyway.
A related point is that I don't have a stable sampling frequency at all. A
sample is taken whenever a zero crossing happens (4 times per revolution
of
the machine). When the speed varies, the sampling will also happen at
uneven intervals. I'm aware that this can lead to weird feedback problems,
as all the control is tied to the same sampling, but I count on fixing any
instability by simply slowing down the control response. If I can get a
control action at up to 3Hz, it's good enough! More would be welcome, but
is not really necessary, given the large inertia of this machine.
> You'll still be "low pass", but you'll have problems
> characterizing the filter.
That's probably acceptable, since I don't need precision here.
> Another caveat is that you'll probably find yourself implementing the
> filter with integer math,
That's indeed the case.
> and if you're not used to that, you could get yourself in a bit of a
> mess.
I have been in that mess quite a few times! The worst was when I
implemented a sidereal clock, using a Basic Stamp, which also has only 16
bit integer math, and a VERY small data RAM (a total of 16 memory words of
16 bits each!). My software had to read and control a GPS receiver, read
out the time and the geographic longitude, synchronize to the
pulse-per-second, then calculate sidereal time and display it on a large
LED screen. All that with just integer math and 16 words of RAM! I got it
running, but it was a little extreme. As a collegue said, I had to stack
the bits sideways to make them fit. The code was not very legible, because
I had to re-use variables many times, for different purposes.
The low pass filter and PI controller in integer math should be child's
play compared to that! :-)
Vladimir,
> The PI function is a lowpass filter by itself.
Not exactly. It has some low pass action, but from a certain frequency up,
the PI will pass signals at constant amplitude while the LP will keep
rolling off. This is what lets the 420Hz disturbance in my system affect
the dump loads. Also, below a certain frequency the PI will keep
increasing
the gain while the LP does not. At DC the PI has infinite gain, and the LP
has finite gain. So, actually the two have a similar response only over a
rather narrow frequency range.
> Add an analog filter upfront
> the PIC comparator. That will reduce the interferrence without
> significantly degrading the performance of the loop.
I cannot! Yes, a LP filter of about 70Hz would nicely pass my 50Hz signal
and nicely reject my 420Hz disturbance, but it would also cause a rather
long delay and thus the PIC would not know the exact moment of a zero
crossing. And it needs to know that, to trigger the TRIACs at the right
moment! So, I must put my 50Hz signal into the PIC with a delay of no more
than perhaps 20us or so. I actually have a small RC low pass filter in
front of the PIC, to get rid of RF noise, but it doesn't help with the
420Hz signal imprinted on the 50Hz by the voltage regulator.
Jerry,
> I think that he counts some
> high-frequency oscillator during the interval between zero crossings to
> determine the period of his waveform, the result of each measurement
> being a number; a bunch of bits.
Exactly this is what I'm doing. The counter runs at 1MHz,
quartz-controlled, and is inside the PIC too. So, if the half wave of my
signal is as long as it should be, I get 10000 counts.
> Where should the capacitor go?
Precisely. It has nowhere to go, and that's why I landed here, looking for
info to finally get my feet wet with DSP!
> A simple low-pass filter might suffice.
At least it should help somewhat.
> The conventional symbols used
> for digital data streams are x[n] for the input data and y[n] for the
> result, where n is the number of the sample in the sequence.
Good to know. I didn't. And this is in part while it's so hard to get into
DSP by googling for things: Almost every text one can find assumes that
the
readers know such basics!
> A unity-gain first-order filter is y[n] = k*x[n] + (1-k)*y[n-1]. It is
> called an exponential averager; k is less than but close to 1.
OK. I tried it, and this indeed works, and attenuates the high frequency
signals! Thanks!
Now what has to be done to increase the order of this filter? As I stated
above, the active filter in my previous (analog) controller used a third
order filter, with good results.
> There is
> usually an adequate choice of k that will allow the multiplications to
> be accomplished with a ****ft and a subtraction.
I tried it on the PC, in BASIC, where I have the benefit of floating point
math. It seems that about 0.7 would be good for my application, but when
implementing this on the PIC, I might need to go to 0.5 for simplicity in
integer math. I think the response time this gives would still be
acceptable. But a higher order would be nice!
I suppose a higher order is obtained by cascading such filters, or is
there a more elegant way?
> I think your problem may be due in part to a (probably unwarranted)
> assumption that there are no even harmonics in your generated waveform.
Indeed I'm uncertain whether to sample at 100Hz, or just at 50Hz, using
full waves. The analog controller runs at 100Hz with good results, but of
course with its 20Hz 3rd order filter that doesn't mean much. It is
sampling at 100Hz only to reduce the ripple at the filter output.
> Even harmonics will cause alternate half cycles to have different
> periods. You should measure the period of an entire cycle by triggering
> on positive- or negative-going zero crossings, not both.
I can try that easily. Maybe it would be best to try with a running
average over the last two half cycles. This would cancel the effects of
even harmonics, and I still would have a new value 100 times per second,
although with an effective delay of 10ms.
And I also have to try a much wider range of gains than I'm trying now,
but the integer math is limiting me in that. I need to write a better PI
routine first!
Thanks to you all! I got good info and several ideas to try. More ideas
are welcome of course, as is an equation for a higher order low pass
filter!
Manfred
http://ludens.cl


|