Lab 2 Filters
Lab 2 Filters
Lab 2 Filters
The
purpose
of
a
filter
is
to
remove
some
unwanted
component
from
a
signal.
In
this
lab,
it
will
be
used
to
remove
high
frequency
noise
from
the
IR
signal
we
wish
to
analyze.
The
cut-‐off
frequency
is
the
boundary
in
a
filter's
response.
Any
frequencies
outside
the
cut-‐off
frequency
range
will
be
attenuated.
Ideally
the
filter
would
completely
eliminate
any
frequencies
outside
the
cut-‐off
frequency
range.
However,
in
reality,
the
attenuation
depends
on
the
order
of
the
filter.
Higher
order
filters
attenuate
the
unwanted
frequencies
more
effectively,
but
increase
the
lag
(phase
delay)
between
the
input
and
output.
The
figure
below
shows
various
orders
of
low
pass
filters
(order
1
to
5).
Notice
that
the
steepest
attenuation
is
associated
with
the
highest
order
filter.
Figure
1-‐
Low
Pass
Filters
of
various
Orders
You
can
either
have
an
analog
filter
or
a
digital
filter.
As
you
might
expect,
analog
filters
are
used
for
analog
signals
(continuous
waveforms)
and
digital
filters
are
used
for
digital
(discrete)
signals.
Analog
filters
are
created
from
hardware
components
such
as
resistors,
capacitors
and
inductors
whereas
digital
filters
are
software
based.
You
are
likely
more
familiar
with
analog
filters
because
of
your
Controls
class.
The
steps
for
designing
a
digital
filter
are
very
similar
to
those
for
an
analog
filter.
First,
the
desired
filter
response
must
be
characterised
and
then
the
parameters
calculated.
For
analog
filters
the
parameters
calculated
are
the
resistor,
capacitor
and
inductor
values
required
to
build
the
filter.
For
digital
filters
the
parameters
calculated
are
the
coefficients
used
in
the
software
implementation
of
the
filter.
In
this
lab
we
will
be
using
a
recursive,
linear
time
invariant
(LTI)
filter.
This
is
a
filter
whose
output
is
a
linear
combination
of
the
input
signals
and
the
previous
output
signals.
The
filter
coefficients
do
not
vary
with
time.
The
formula
below
describes
the
most
basic
time
domain
input-‐output
relationship
for
a
first
order,
LTI,
recursive
filter.
Where
x(i)
is
the
filter
input
(raw
data),
y(i)
is
the
filter
output(filtered
signal),
α
is
the
filter
coefficient,
i
is
the
current
time
step
and
y(i-‐1)
is
the
previous
filter
output.
There
are
many
methods
used
for
characterizing
a
filter,
but
the
most
commonly
used
is
the
transfer
function.
Transfer
functions
are
usually
used
to
describe
single-‐input
single-‐output
filters.
The
input
signal
goes
through
the
transfer
function
and
is
converted
into
the
desired
output
signal.
See
below.
Input
x(t),
X(z)
H(z)
Output
y(t),
Y(z)
x(t)
and
y(t),
usually
denoted
with
lowercase
x
and
y,
are
the
time
domain
signals
and
X(z)
and
Y(z),
usually
denoted
with
uppercase
X
and
Y,
are
the
frequency
domain
signals.
To
define
the
transfer
function,
you
must
first
convert
the
time
domain
signals
into
frequency
domain
using
the
Z-‐transform.
The
Z-‐transform
is
the
equivalent
of
the
Laplace
Transform,
but
for
digital
instead
of
analog
signals.
Once
the
relationship
between
the
input
and
output
signals
is
defined
in
frequency
domain,
the
transfer
function,
H(z),
is
simply
the
output,
Y(z),
over
the
input,
X(z).
The transfer function for a linear, time invariant, digital filter is defined as follows.
𝑌 𝐵(𝑧) 𝑏+ + 𝑏- 𝑧 .- +
𝑏0 𝑧 .0 +
. . . 𝑏2 𝑧 .2
𝐻 𝑧 = = =
𝑋 𝐴(𝑧) 1 + 𝑎- 𝑧 .- +
𝑎0 𝑧 .0 +
. . . 𝑎5 𝑧 .5
Where
H(z)
is
the
transfer
function
in
frequency
domain
(z)
and
the
parameters
to
be
determined
are
B(z)
and
A(z).
B
is
a
1xN
matrix
of
the
numerator
coefficients
and
A
is
a
1xM
matrix
of
the
denominator
coefficients.
So
B
=
[b0
b1
b2
...
bN]
and
A
=
[
1
a1
a2
....
aM
].
For the 1st order filter above the transfer function is as follows. This was derived using the Z-‐transform.
1
𝐻(𝑧)
=
1 + 𝛼𝑧 .-
The
type
of
filter
you
require
depends
on
which
frequencies
you
want
to
attenuate.
For
example,
a
low
pass
filter
passes
low
frequencies
and
attenuates
the
high
frequencies
(frequencies
higher
than
the
cutoff
frequency).
The
time
domain
representation
of
a
low
pass,
LTI,
first
order,
recursive
filter
can
be
seen
below:
𝑦8 = 𝛼𝑥8 + (1 − 𝛼)𝑦8.-
Where
x
is
the
unfiltered
data,
y
is
the
filtered
data
and
α
is
the
filter
(smoothing)
coefficient.
The
smoothing
coefficient
can
be
modified
depending
on
the
desired
system
response.
For
an
in-‐depth
explanation
of
low
pass
filters
and
the
derivation
of
this
equation,
visit
the
low
pass
filter
Wikipedia
page:
http://en.wikipedia.org/wiki/Low-‐pass_filter
Once
the
time
domain
equation
is
known,
the
Z-‐transform
is
used
to
get
the
equation
in
frequency
domain
so
the
transfer
function
can
be
determined.
The
Z-‐transformation
is
shown
below.
𝑦8 = 𝛼𝑥8 +
1 − 𝛼 𝑦8.-
𝑦8 − 1 − 𝛼 𝑦8.- = 𝛼𝑥8
𝑌 − 1 − 𝛼 𝑌(𝑧)𝑧 .- = 𝛼𝑋
𝑌 ∗ 1 − 𝑧 .- + 𝛼𝑧 .- = 𝛼𝑋
𝑌 𝛼
=
𝑋 1 − 𝑧 + 𝛼𝑧 .-
.-
𝐵 𝑧 𝛼
𝐻 𝑧 = =
𝐴 𝑧 1 + (𝛼 − 1)𝑧 .-
B = α
A = [ 1 (α-‐1)]
Just a few notes on how to do the Z-‐transformation (in case you were interested):
Since
digital
filters
are
implemented
in
code,
there
are
various
ways
you
can
program
them.
One
is
to
use
the
filter
functions
built
into
Matlab.
These
functions
require
inputs
of
either
the
sampling
frequency
or
the
coefficients,
A
and
B.
Although
you
will
likely
not
be
using
Matlab
for
your
final
project,
it
may
be
useful
to
use
the
Matlab
filters
to
compare
and
optimize
your
Arduino
filtering.
This
is
why
we
will
go
over
using
the
filter
functions
in
Matlab
Another
way
to
implement
the
filter
in
code,
is
simply
to
use
the
time
domain
formula.
This
is
the
simplest
way
and
is
good
for
programming
languages
where
there
are
no
filter
functions
built
in,
like
the
Arduino.
In
order
to
implement
the
low
pass,
LTI,
first
order
filter
in
the
code,
you
simply
use
the
time
domain
function
for
the
low
pass
filter
from
above.
The
formula
below
is
the
implementation
of
this
filter
in
Matlab
code.
y(i) = a*x(i)+(1-a)*y(i-1);
Where
y
is
an
array
of
the
filtered
values
and
x
is
an
array
of
the
raw
data.
y(i)
is
the
filtered
data
output
and
y(i-‐1)
is
the
previous
filtered
data
output
value.
We
will
now
use
this
formula
to
filter
the
input
from
an
IR
sensor.
The
Arduino
code
in
Appendix
A
will
read
the
IR
sensor
values
and
output
the
raw
values
to
Matlab.
Once
we
have
the
raw
values
we
will
filter
and
plot
them
in
Matlab.
The
sample
code
to
do
this
filtering
is
shown
in
Appendix
B.
This
function
reads
the
IR
output
from
the
Arduino
and
plots
the
raw
and
filtered
data
with
respect
to
time.
The
time
array
is
created
using
the
'tic'
and
'toc'
functions
in
Matlab.
If
a
more
precise
counter
is
required,
it
should
be
done
on
the
Arduino.
The
plots
below
show
the
un-‐filtered
and
filtered
IR
data
for
α
=0.1
and
α=0.01.
Note
that
the
smaller
the
α
value,
the
smoother
the
data,
but
the
larger
the
phase
delay.
Figure
2-‐
Filtered
Voltage(red)
and
Unfiltered
voltage(blue)
from
IR
sensor
with
alpha
=
0.1
Figure
3-‐
Filtered
Voltage(red)
and
Unfiltered
Voltage(blue)
from
IR
sensor
with
alpha
=
0.01
Notice
that
a
value
of
α
=
0.01,
causes
too
much
filtering
and
the
output
curve
is
excessively
smoothed.
You
will
need
to
find
the
optimal
combination
between
eliminating
noise,
but
still
having
a
function
that
responds
quickly
to
changes.
This
is
done
by
trial
and
error.
This
is
the
most
basic
implementation
of
the
low
pass
filter
and
is
very
useful
if
you
do
not
have
any
built
in
filtering
functions.
However,
Matlab
does
have
built
in
filter
functions.
These
functions
require
the
coefficients
(A
and
B),
that
were
calculated
above,
as
inputs
to
define
the
type
of
filter.
We
will
only
look
at
the
filtfilt
function
in
this
lab,
but
there
are
lots
of
other
types
you
can
use.
If
you
notice,
the
filtered
voltage
above
is
shifted
from
the
original
voltage
in
both
of
the
above
graphs.
This
is
due
to
the
time
required
to
process
the
filtering
equation
on
the
fly.
In
order
to
avoid
this
shift
we
can
use
the
filtfilt
function
in
matlab.
The
filtfilt
function
performs
zero-‐phase
shift
digital
filtering
by
processing
the
data
in
both
the
forward
and
reverse
direction.
However,
since
filtfilt
needs
to
process
the
data
both
backwards
and
forwards,
it
needs
to
know
all
the
data,
meaning
it
cannot
be
used
on
the
fly.
You
must
first
create
an
array
of
all
the
collected
data,
raw
values,
and
then
filter
that
array
instead
of
using
the
function
on
every
data
point
individually
as
we
did
in
the
previous
example.
To
learn
more
about
the
filtfilt
function,
type
"help
filtfilt"
into
the
Matlab
command
line.
The
following
line
shows
how
to
properly
call
the
filtfilt
function.
Y = filtfilt(B,A,X);
Where
X
and
Y
are
the
unfiltered
and
filtered
data
arrays
respectively
and
B
and
A
are
the
transfer
function
coefficients
calculated
above.
The
Matlab
code
below
uses
the
filtfilt
function
to
filter
the
IR
data
from
above.
%This function using filtfilt to low pass filter data(an array of values from
the IR sensor). It then plots the filtered and unfiltered data.
function IR_SENSOR_FILTFILT(obj)
tic;
i= 1;
while toc < 10
time(i) = toc;
voltage(i) = (obj.ard.analogRead(2))*(5/1024);
i = i+1;
end
a = 0.1; %sets the value of alpha
filtered_data = filtfilt(a,[1 a-1],voltage);
%uses filtfilt to filter the voltage data
figure;
plot(time,voltage,'b');
hold on;
plot(time,filtered_data,'r');
xlabel('Time');
ylabel('Voltage');
end
See
the
plot
below
for
the
output
of
the
unfiltered
(blue)
and
filtered
data
(red),
found
using
the
filtfilt
function.
Figure
4-‐
FiltFilt
Filtered
and
Unfiltered
voltage
plot
with
alpha
of
0.1
Note
that
in
the
plot,
the
filtered
voltage
is
not
offset
from
the
original.
Sometimes,
depending
on
the
type
of
filter,
the
offset
will
be
linear
so
a
formula
can
be
used
to
shift
all
the
data
backwards.
Unfortunatley,
this
is
not
the
case
for
the
simple
low
pass
filter
formula
we
used.
This
is
why
the
zero
phase
shift
of
the
filtfilt
function
is
so
useful
however,
since
it
can
only
be
used
after
all
the
signal
data
has
been
read,
it
would
not
be
useful
for
a
balancing
robot
application.
In
order
to
balance,
the
signal
needs
to
be
read
and
filtered
in
real
time.
Butterworth
The
Butterworth
filter
is
another
type
of
linear,
time
invariant
filter.
However,
it
will
have
different
B
and
A
transform
function
coefficients
than
the
basic
LTI,
low
pass
filter.
There
is
a
Butterworth
filter
function
builder
in
Matlab
so
it
is
very
easy
to
use.
If
you
want
to
implement
a
Butterworth
filter
in
the
Arduino
you
should
first
use
Matlab
to
determine
the
A
and
B
coefficients.
In
order
to
determine
these
coefficients
we
use
the
'butter'
function
in
Matlab.
The
butter
function
will
create
a
butterworth
filter
and
give
us
the
coefficients
(B
and
A).
The
syntax
to
call
the
function
is
shown
below.
Where
B
and
A
are
transfer
function
coefficients,
N
is
the
order
of
Butterworth
filter
you
wish
to
design
(remember
the
higher
the
order
the
more
accurate,
but
the
more
lag)and
Wn
is
the
normalized
cut-‐off
frequency.
By
default,
the
Butterworth
filter
is
a
low
pass
filter
i.e.
butter(N,Wn)
will
design
a
low
pass
filter,
but
you
can
design
all
types
of
filters
(see
help
butter
in
Matlab
for
more
details).
The cut-‐off frequency for a digital filter can be given by the following formula:
1
𝑓= =
1−𝛼
2𝜋∆𝑇
𝛼
This
formula
comes
from
substituting
the
RC
formula
for
digital
filters
into
the
cut-‐off
frequency
formula
for
analog
filters(see
Wikipedia
low
pass
filter
page).
∆T
is
the
sampling
period.
For
operations
in
Matlab,
you
can
calculate
an
approximate
value
of
∆T
by
creating
a
time
array
using
the
'tic'
and
'toc'
functions.
The
sampling
period
is
then
the
maximum
value
in
the
time
array
and
divided
by
the
number
of
entries.
This
is
not
the
most
accurate
method
since
'tic'
and
'toc'
are
just
counters,
but
provided
you
don't
do
too
many
time
intensive
processes
(graphing,
printing,
complex
math
etc)
in
between
the
counting
you
should
get
a
good
result.
The
use
of
tic
and
toc
are
shown
in
in
the
IR_SENSOR_FILTFILT
function
above.
𝑓=
𝑊C
=
2𝑓D
Where
fs
is
the
sampling
frequency
(1/sampling
period).
If
you
are
using
the
Arduino,
you
could
set
a
timer
interrupt
and
sample
everytime
the
interrrupt
goes
off.
That
way
you
know
your
exact
sampling
frequency.
Once
we
have
the
coefficients,
we
can
implement
the
filter.
We
will
go
over
how
to
implement
it
in
both
Matlab
and
Arduino.
To
implement
the
filter
in
Matlab,
we
will
use
the
filtfilt
function
due
to
the
zero
phase
shift,
but
you
could
also
use
Y
=
filter(B,A,X).
The
following
function
outlines
how
to
create
and
use
a
butterworth
filter
in
Matlab
to
filter
the
raw
IR
data.
The
plot
below
shows
the
filtered
and
unfiltered
data
when
'butter'
is
used
to
determine
the
B
and
A
matrices.
Figure
5-‐
Filtered
and
Unfiltered
Voltage
plots
using
Butterworth
filter
design
and
alpha
of
0.1
To
implement
this
filter
on
the
Arduino
you
will
need
to
manually
write
out
the
equation
using
the
coefficients.
Recall
from
above
that
the
transfer
function
in
frequency
domain
can
be
defined
as
follows:
𝑌 𝑏+ + 𝑏- 𝑧 .- +
𝑏0 𝑧 .0 +
. . . 𝑏2 𝑧 .2
=
𝑋 1 + 𝑎- 𝑧 .- +
𝑎0 𝑧 .0 +
. . . 𝑎5 𝑧 .5
Assume
that
the
B
and
A
matrices
for
the
low
pass,
LTI,
first
order,
recursive
filter,
defined
above,
are
as
follows:
The
Butterworth
filter
can
be
determined
using
the
following
relation.
𝐴𝑦 = 𝐵𝑥
Plugging
in
the
matrices
and
solving
for
Y
gives
the
following.
Remember
this
example
is
for
a
1st
order
Butterworth.
If
you
want
a
higher
order,
you
will
get
larger
matrices.
A
second
order
Butterworth
filter
would
yield
1x3
matrices
and
would
give
you
the
following
equation:
Note: y*a1 yields yi-‐1 and y*a2 would yield yi-‐2 etc.
Since
we
used
the
butter()
function
in
Matlab
to
determine
the
A
and
B
coefficients,
we
are
implementing
a
Butterworth
filter.
If
you
would
like
to
use
another
type
of
filter,
you
can
use
a
different
function
in
Matlab
to
determine
the
coefficients.
For
example,
to
obtain
the
A
and
B
coefficients
for
a
Chebyshev
filter
you
could
use
the
chebyl
function
in
Matlab.
Lab
Requirements
This lab showed a few different ways to do filtering. For this lab you will need to do the following:
You
do
not
need
to
implement
the
butter
filter
on
the
Arduino
for
this
lab,
but
it
may
be
useful
for
your
final
project
so
you
may
want
to
try
it.
If
you
choose
to
use
it
as
one
of
your
three
filtering
methods,
you
will
need
to
import
the
filtered
data
and
graph
it
in
Matlab.
Remember
the
filtfilt
function
is
not
defined
on
the
Arduino
so
it
can
only
be
used
in
Matlab.
Also
for
your
project
you
will
want
to
measure
and
evaluate
the
data
in
real
time
so
the
filtfilt
function
wouldn't
really
be
useful
anyway.
Appendix
A
Appendix
B
clc;
clear all;
numSec=10;
IR=[];
IR_filt = [];
a = 0.5; %smoothing coefficient (to be optimized)
i=0;
t0=tic;
while (toc(t0)<=numSec)
i=i+1;
t(i) = toc(t0);
t(i) = t(i)-t(1);
IR(i)=fscanf(s1,'%f'); % must define the input % d, %f, %s, etc.
if(i==1)
IR_filt(i) = IR(i);
else
IR_filt(i) = a*IR(i)+(1-a)*IR_filt(i-1);
end
plot(t,IR); %plots the raw IR output
hold on;
plot(t,IR_filt,'r'); %plots the filtered IR output
drawnow;
end
fclose(s1);
catch exception
fclose(s1); % always, always want to close s1
throw (exception);
end