IIR filter help

Hi, I have one question regarding implementation of IIR filter. I try to write C code of IIR filter for ARM microcontroler for real time signal processing. Filter should be lowpass and second order. I try to do this in interupt function. This should be part of the code . volatile int count, count_on; char On_ind; volatile float Sample[3],Filtered[3], Max, Min, Power_curent, Power_wanted, Scal, FB;;

/* Timer0 interupt funkcija*/ void tc0 (void) __irq { IODIR0 = 0x00000001;

Sample[2]=Sample[1]; Sample[1]=Sample[0]; Sample[0]=(float)ADC1_read();

Filtered[2]=Filtered[1]; Filtered[1]=Filtered[0];

Filtered[0]=0.0002478584065*Sample[0]+0.000495716813

*Sample[1]+0.0002478584065*Sample[2]+ 1.964326262*Filtered[1]-0.9654386044*Filtered[2]; // ffiltering

But there is a problem this code doesnt work. I try to implement IIR filter order 1

I replace

Filtered[0]=0.0002478584065*Sample[0]+0.000495716813

*Sample[1]+0.0002478584065*Sample[2]+ 1.964326262*Filtered[1]-0.9654386044*Filtered[2]; // ffiltering

with

Filtered[0]=

0.044263*Sample[0]+0.044263*Sample[1]+0.91147*Filtered[1];

and this filter works fine. I am not shure but I don't know what is a problem when i am trying to implement second order IIR filter. Could anyone help me, please.

I designed this filters using Matlab "filters design and analys tool" (fdatool). I tested bouth filters in matlab and as test signal I used signal that is almost the same the one I am using with lpc2148. When I am testing filter order 1(with mc) the results is expected but when I use filter of second order I am getting wrong results (I am constantly getting '0').

I apreciated any kind of help.

Thanks Zoran

Reply to
Zorjak
Loading thread data ...

Only guessing... but I see you are using floating point math in an interrupt function. Is it possible that this never completes within the time allowed between interrupts? Or are there floating point software "registers" that should not be used in an interrupt service routine?

--

John Devereux
Reply to
John Devereux

Do you want float?

or double?

You are mixing data types.

Reply to
linnix

Same question as I asked when you asked this in the Yahoo LPC200 group. Why do you think floating point will work in an interrupt?

Robert

--
Posted via a free Usenet account from http://www.teranews.com
Reply to
Robert Adsett

Please track down the Wikipedia entry on cross-posting. Read it until you understand the difference between cross-posting and multiple-posting.

Then stop multiple-posting!

--
Tim Wescott
Wescott Design Services
 Click to see the full signature
Reply to
Tim Wescott

I believe he's using an LPC2000 ARM7 micro, there are no floating point registers, it's all software. I wouldn't really expect the the emulation to be reentrant but you never know. I'd certainly want to make sure before attempting to use floating point in an interrupt though.

Robert

--
Posted via a free Usenet account from http://www.teranews.com
Reply to
Robert Adsett

Why shouldn't it? Failure would be contrary to the C standard, which says nothing about interrupts.

--
 Chuck F (cbfalconer at maineline dot net)
   Available for consulting/temporary embedded and systems.
Reply to
CBFalconer

For one because interrupts are outside the C standard so their behaviour owes more to the processor and particular compiler extensions than to the standard.

Also it would be contrary to experience. While I wouldn't be shocked to see a re-entrant floating-point implementation I've yet to encounter one.

I don't expect __irq to work for more basic items either. Experience leads me to not trust architecture specific compiler extensions. Especially when they are easily avoided (as in the case of interrupts). Not everyone shares my pessimism in this regard, but I would have thought knowledge of non-reentrant floating point was fairly common.

Robert

--
Posted via a free Usenet account from http://www.teranews.com
Reply to
Robert Adsett

... snip ...

I built one 30 years ago for the 8080. Fully re-entrant, thread safe, etc. So I consider such missing to be carelessness by the developer. The penalty was roughly 5 decimal digits of precision. It was published in Dr. Dobbs.

--
 Chuck F (cbfalconer at maineline dot net)
   Available for consulting/temporary embedded and systems.
Reply to
CBFalconer

Thanks for all posts

I'll try to realize this filter in integer arithmetic to see waht will happen. My sample frequencuy is 10000HZ so I thought that this isn't too much (and when my first order filter worked fine I was sure:)), but now I will think about this more.

Thanks aga> Zorjak wrote:

Reply to
Zorjak

Please do not top-post. Your answer belongs after (or intermixed with) the quoted material to which you reply, after snipping all irrelevant material. See the following links:

--
  
  
 Click to see the full signature
Reply to
CBFalconer

You can consider it carelessness by the developer, but many floating point implementations are not reentrant, particularly if they are implemented in a hardware FPU with it's own state, or if they are emulating said FPU.

_I_ would consider it carelessness by the developer to assume that a floating point implementation _is_ reentrant, without either testing it or seeing a declaration of reentrancy in the tools documentation.

--
Tim Wescott
Control systems and communications consulting
 Click to see the full signature
Reply to
Tim Wescott

No latentcy penalty?

Sometimes the penalty is rather considerable overhead to preserve the state of the floating point processor.

It's not unusual for division or multiplication to be an issue as well. A number of micros have interruptable multiplication instructions and you cannot safely perform a multiplcation in an interrupt without saving extra state. IME it's unusual for the compilers to take that precaution (It does slow down interrupt response).

IIRC I've also run across a compiler that had non-reentrant long arithmetic routines. It always pays to read the compiler documentation carefully.

I certainly wouldn't assume the compiler's standard had set up a standard C environment before checking the documentation. Actually I don't trust the compiler to do this task anyway but I'm a bit paranoid on this point.

Robert

--
Posted via a free Usenet account from http://www.teranews.com
Reply to
Robert Adsett

Or naivete. My original question was meant to be Socratic rather than combative. I'm not sure it ended up that way.

Robert

--
Posted via a free Usenet account from http://www.teranews.com
Reply to
Robert Adsett

None. Remember, this was for an 8080. All data was in the registers, and all locals were created on the stack. The available registers forced the system to use a 16 bit significand with an 8 bit exponent. That processed medical data for over 15 years without any accuracy failings.

--
 Chuck F (cbfalconer at maineline dot net)
   Available for consulting/temporary embedded and systems.
Reply to
CBFalconer

How can it be contrary to something it says nothing about. That doesn't sound very logical. If it says nothing about it then there is little that one can conclude other than the standards are silent on the matter.

Peter

Reply to
Peter Dickerson

Simple. Since it specifies nothing about interrupts, it is up to the system designer to ensure that any added interrupts (or anything else) do not disturb any systems. They can delay operation, because the C standard does not specify any speeds. However, the C standard DOES specify the floating point capabilities of the system, so if they are used, they must not get disturbed by interrupts, etc.

--
 Chuck F (cbfalconer at maineline dot net)
   Available for consulting/temporary embedded and systems.
Reply to
CBFalconer

And since the system designer is usually the person using the compiler rather than the one writing the compiler it's up to them to ensure that. Provided, of course it's not more reasonable to work within the limitations imposed by a more restricted environment.

Robert

--
Posted via a free Usenet account from http://www.teranews.com
Reply to
Robert Adsett

Hi after some break I've been made regarding this problem, I had one more ask for help. I try to implement some filter in integer arithmetics. I stil use lpc2148 and my sample frequency is 10kHz. I have simulated this filter in matlab and when I try to implement it in the lpc2148 the results are totaly wrong. I have only two multiplication so I think that this shouldnt be a problem. It's like that problem came when I use second order IIR filter.I tested some FIR filter where I had 3 multiplication and it works fine (I tested this this using floating point also and that worked fine too). I don't know but It seems like when I use 2 delay for output problems came in. I don't know what to think more. thas anybode had similar problems ever. can anybody help me. I know that I am boring but I am desperet.:)

Thanks for all Your help Zoran

void tc0 (void) __irq {

Sample[2]=Sample[1]; Sample[1]=Sample[0]; Sample[0]=ADC1_read();

Filtered[2]=Filtered[1]; Filtered[1]=Filtered[0];

Filtered[0]=Sample[0]-Sample[2]+((2044*Filtered[1])- ((1021*Filtered[2]))>>10) CBFalc> >

Reply to
Zorjak

Question - What are the types of the various variables? - Does matlab support integer arithmetic? I seem to remember a package that did.

Suggestions - First dump the __irq and implement this as a normal function. When it works as a normal function then you can look at doing it in an interrupt. That'll also let you verify the timing. I still think the original suggestions to implement this outside of the interrupt were good though. - Second test this in C on your PC. You can feed it a file containing sample data to filter and check the results. Watch particularly for overflows. Order of operations can be critical as well.

Robert

--
Posted via a free Usenet account from http://www.teranews.com
Reply to
Robert Adsett

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.