Skip to content

Commit d38c2cc

Browse files
committed
FIR filter correction.
1 parent c7817ec commit d38c2cc

File tree

1 file changed

+49
-56
lines changed

1 file changed

+49
-56
lines changed

arduino/stdafx.h

Lines changed: 49 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -172,59 +172,28 @@ class Signals {
172172

173173
/*
174174
175-
FIR Filter Design on Arduino.
176-
177-
To use it, first create the filter with the desired coefficients:
175+
IIR Filter Design on Arduino.
178176
179-
const float h[] = {0.25, 0.25, 0.25, 0.25};
180-
Signals::FIR f(h, sizeof(h)/sizeof(*h));
177+
This filter can be written as (a0 is assumed to be 0):
181178
182-
Now filter the current ref value!
179+
y[n] = b0*x[n] + b1*x[n - 1] + ... + bP*x[n - P]
180+
- a1*y[n - 1] + a2*y[n - 2] + ... + aQ*y[n - Q]
183181
184-
float fref = f.filter(ref);
182+
or in the z domain:
185183
186-
*/
187-
class FIR
188-
{
189-
float * h;
190-
float * x;
191-
unsigned int size;
192-
unsigned int iteration;
184+
H(z) = b0 + b1*z^-1 + ... + bP*z^-P
185+
-----------------------------
186+
1 + a1*z^-1 + ... + aQ*z^-Q
193187
194-
public:
195-
FIR(const float * h, const unsigned int size)
196-
{
197-
this->h = new float[size];
198-
memcpy(this->h, h, size*sizeof(float));
199-
this->size = size;
200-
this->x = new float[size];
201-
202-
for (unsigned int i = 0; i < size; i++)
203-
this->x[i] = 0.0;
204-
}
205-
206-
~FIR()
207-
{
208-
delete this->h;
209-
delete this->x;
210-
}
188+
To use it, first create the filter with the desired coefficients:
211189
212-
float filter(const float value)
213-
{
214-
float ret = 0;
215-
x[iteration] = value;
216-
217-
for (int i=0; i<size; i++)
218-
ret += h[i] * x[(i + iteration) % size];
219-
220-
iteration = (iteration + 1) % size;
221-
return ret;
222-
}
223-
};
190+
const float b[] = {0, 1};
191+
const float a[] = {-0.5};
192+
Signals::IIR f(b, sizeof(b)/sizeof(*b), a, sizeof(a)/sizeof(*a));
224193
225-
/*
194+
Now filter the current ref value!
226195
227-
IIR Filter Design on Arduino.
196+
float fref = f.filter(ref);
228197
229198
*/
230199
class IIR
@@ -284,36 +253,60 @@ class IIR
284253
}
285254
};
286255

256+
/*
257+
258+
FIR Filter Design on Arduino. This is a special case of the IIR filter, and is implemented as such.
259+
260+
The N order filter assumes the type:
261+
262+
y[n] = b0*x[n] + b1*x[n - 1] + ... + bN*x[n - N]
263+
264+
To use it, first create the filter with the desired coefficients:
265+
266+
const float h[] = {0.25, 0.25, 0.25, 0.25};
267+
Signals::FIR f(h, sizeof(h)/sizeof(*h));
268+
269+
Now filter the current ref value!
270+
271+
float fref = f.filter(ref);
272+
273+
*/
274+
class FIR : public IIR
275+
{
276+
public:
277+
FIR(const float * h, const unsigned int size) : IIR(h, size, {0}, 1) {} // FIXME: i left size as 0 to prevent creation of 0 size array, even though it's permitted by gcc and works fine
278+
};
279+
287280
/*
288281
289282
A simple PI controller for Arduino based on discrete controller.
290283
291284
The controller is:
292285
293-
C = kc (z - q)
294-
-------
295-
z - 1
286+
C = kc (z - q)
287+
----------
288+
z - 1
296289
297290
To create PI instance:
298-
cPI controller(kc, q);
291+
cPI controller(kc, q);
299292
300293
To set the setpoint:
301-
controller.setpoint(SETPOINT);
294+
controller.setpoint(SETPOINT);
302295
303296
To calculate control signal:
304-
value = controller.calculate(SENSOR_READING);
297+
value = controller.calculate(SENSOR_READING);
305298
306299
Don't forget to delay your sampling time Ts:
307-
delay(Ts);
300+
delay(Ts);
308301
309302
Remember to limit your output, so your control signal won't skyrocket:
310-
controller.limit(min, max);
303+
controller.limit(min, max);
311304
312305
To use a filter, use the function setFilter(kf, pf). It's automatically applied to the controller. The filter equation is:
313306
314-
F = kf z
315-
-------
316-
z + pf
307+
F = kf z
308+
-------
309+
z + pf
317310
318311
The filter is normally used to cancel a zero in the dynamic in the closed loop system.
319312

0 commit comments

Comments
 (0)