Basic info needed regarding filters (FIR)

J

John Larkin

Jan 1, 1970
0
John Larkin wrote:
@hotmail.com> wrote:
Here is the basic realpole filter which is simpler and appears to have
almost identical response:
const u8 order = 4;
s32 LPF(s32 x)
{
static s32 z[order];
for(u8 i = 0; i < order; i++) x = z+= (x - z)>>6;

return x;
}
Making digital filter as the simulation of an analog filter is rarely a
good idea.
I've sold over 3000 of the temperature controllers that use this
filter.
McDonalds serves somewhat 10 billion meals per year. But this fact doesn't
make those meals taste any better or worse :)
Selling things for high prices to high-end customers, in volume, for
years, bug-free, means we're doing exactly what we want to do. Any
other criterion for engineering quality is, literally, academic.
Why whining about the Evil Empire of Bill Gates then?

Because it's slow, bloated, and bug-ridden, from a company run by
sociopaths who crush competition out of sheer ruthlessness.
I am sorry if you didn't understand 3 lines of trivial C code without
comments. It would be a good idea to do some learning before suggesting the
advanced digital filter topologies...
I've made a solemn vow to never code in C.
Yes. C++ is lot better.

Funny! I write apps that run in, typically, 4-6 kilobytes of eprom and
2K of ram, manage a few FPGAs and a VME or serial/ethernet interface,
run thousands of interrupts per second, and have guaranteed response
times in the 100 usec sort of range, 100% of the time. And never
crash.


But comments don't explain
code, comments explain what code is for and what it does. Your filter
is just a heap of code. I have no idea what it's response is like, and
would have to analyze or simulate it to determine that.
So, what is its frequency response?

1/64
H(Z) = (---------------) ^ 4
63
1 - --- Z^-1
64

So, what is its frequency response?

John


I suppose you could use the bilnear transform to map it into the S
domain, then do a spreadsheet to see the response.

Learning basic C isn't that difficult. The object oriented flavor is
another story.


What I'm doing works.

I have the UART interrupt service routine, which builds a string from
edited input characters. When the command string is done, it sets a
flag to let the main loop know that a command string is ready, and the
main loop in turn calls the command parser, which executes the string.
The box I'm doing now has exactly 100 distinct serial commands. Some
user commands can call certain canned sequences, stored as strings,
which the parser executes re-entrantly. So far so good.

But some command strings can take a long time, perhaps minutes, to
execute. So I've assigned one serial character as an abort. When the
ISR sees this, it just resets the stack and jumps to the top of the
main opside loop, totally dumping whatever was going on and starting
fresh. I've asked a couple of my C guys how they would do this in C,
and the answers were sort of mumbles.

Another thing I like to do is copy a chunk of code, like the FPGA
loader, from eprom into a block of cpu ram, and execute it from there.
That speeds things up by 2:1 or so... no byte-wide bus fetches. Then I
can use that block of ram for normal system variables. All that sort
of thing is easy in assembly.

All my embedded programs are monolithic, absolute assemblies of a
single source file. I can usually archive a project *including all the
tools* on a single floppy. The program listings are heavily commented,
neatly paged, and start with an automatically generated table of
contents, which makes it really easy to see the structure and find
whatever you may be looking for. I can revisit a years-old project and
find what I want in seconds.

The methodology is ancient, like making bread in wood-fired ovens. But
it works.

John
 
J

John Larkin

Jan 1, 1970
0
Comments explain what code is supposed to do. Whether or not it actually
behaves as described is a different matter.

If I don't think that the behaviour of a piece of code is sufficiently
clear, my first response would be to consider re-writing the code rather
than adding comments.

Of course, that's much more feasible in a high-level language than in
assembler.

Suppose you code a digital lowpass filter that has some 3 dB point,
some gain, and a notch at some frequency, and the coefficients have
been converted from the textbook values into shifts, but that produces
a 5% time-domain tail with some decay tau. How do you convey all that
without comments?

Answer: you don't.

Comments aren't there to mainly to explain code execution, they are
primarily to explain context and behavior. And hazards.

John
 
J

Jan Panteltje

Jan 1, 1970
0
On a sunny day (Sat, 24 Nov 2007 14:25:05 -0800) it happened John Larkin
<[email protected]>:

I can usually archive a project *including all the
tools* on a single floppy.

Whotsa floppy? ;-)

The methodology is ancient, like making bread in wood-fired ovens. But
it works.

Not to feed the millions.
 
J

John Larkin

Jan 1, 1970
0
On a sunny day (Sat, 24 Nov 2007 14:25:05 -0800) it happened John Larkin
<[email protected]>:

I can usually archive a project *including all the

Whotsa floppy? ;-)

We formally release everything - pcb's, parts lists, firmware, fpga
designs, test set designs and test procedures, eco's - to the company
library, and manufacturing works from released stuff only. Release
involves physical custody transfer, on a floppy for small stuff or a
cd for bigger things. It gets copied to the library server and logged,
and I put the original media in a baggie and stash it in the cave
under my garage.
Not to feed the millions.

My wife received a magazine that had an ad inside for Yellow Tail
wines. It was a thick full-page insert, with pictures of a bunch of
insects of some sort and a caption [press here]. When you press it,
the bug tails flash yellow for a while. Inside is a controller pcb, a
bazillion wires, and a separate pcb for each led. I should post a pic.

Do you think that was programmed in C++?

John
 
N

Nobody

Jan 1, 1970
0
Suppose you code a digital lowpass filter that has some 3 dB point,
some gain, and a notch at some frequency, and the coefficients have
been converted from the textbook values into shifts, but that produces
a 5% time-domain tail with some decay tau. How do you convey all that
without comments?

Answer: you don't.

Comments aren't there to mainly to explain code execution, they are
primarily to explain context and behavior. And hazards.

We appear to be talking about different things.

Certainly, documentation is often necessary. The documentation may be
embedded in the source file as comments; nowadays, it's common for such
comments to use a distinct syntax so that they can be automatically
extracted from the code for inclusion in the manual, e.g. Doxygen. But
that information should be provided whether the code is supplied as source
code or a pre-compiled library. If you're not supplying source code,
having that information in comments alone won't help.

OTOH, "normal" comments such as those which appear at the RHS of most
lines in your assembler code are seldom necessary in a high-level
language. At least, not for code, although it may be useful to comment
declarations of variables and structure fields if their meaning cannot
be adequately conveyed by their name alone.

Also, regarding the use of shifts: if you multiply or divide an integer by
a constant which is a power of two, modern compilers will automatically
generate a shift instruction. They'll also convert multiplication by
arbitrary constants into a sequence of shift and addition/subtract
instructions if it will be faster than a multiplication instruction
(unless you tell them to optimise for smaller code size over faster
execution).
 
On Fri, 23 Nov 2007 12:43:10 -0600, Vladimir Vassilevsky
Here is the basic realpole filter which is simpler and appears to have
almost identical response:
const u8 order = 4;
s32 LPF(s32 x)
{
static s32 z[order];
for(u8 i = 0; i < order; i++) x = z+= (x - z)>>6;
return x;
}
Making digital filter as the simulation of an analog filter is rarely a
good idea.
I've sold over 3000 of the temperature controllers that use this
filter.
McDonalds serves somewhat 10 billion meals per year. But this fact doesn't
make those meals taste any better or worse :)
Selling things for high prices to high-end customers, in volume, for
years, bug-free, means we're doing exactly what we want to do. Any
other criterion for engineering quality is, literally, academic.
Why whining about the Evil Empire of Bill Gates then?
Because it's slow, bloated, and bug-ridden, from a company run by
sociopaths who crush competition out of sheer ruthlessness.
I am sorry if you didn't understand 3 lines of trivial C code without
comments. It would be a good idea to do some learning before suggesting the
advanced digital filter topologies...
I've made a solemn vow to never code in C.
Yes. C++ is lot better.
Funny! I write apps that run in, typically, 4-6 kilobytes of eprom and
2K of ram, manage a few FPGAs and a VME or serial/ethernet interface,
run thousands of interrupts per second, and have guaranteed response
times in the 100 usec sort of range, 100% of the time. And never
crash.
But comments don't explain
code, comments explain what code is for and what it does. Your filter
is just a heap of code. I have no idea what it's response is like, and
would have to analyze or simulate it to determine that.
So, what is its frequency response?
Here:
1/64
H(Z) = (---------------) ^ 4
63
1 - --- Z^-1
64
So, what is its frequency response?
John

I suppose you could use the bilnear transform to map it into the S
domain, then do a spreadsheet to see the response.
Learning basic C isn't that difficult. The object oriented flavor is
another story.

What I'm doing works.

I have the UART interrupt service routine, which builds a string from
edited input characters. When the command string is done, it sets a
flag to let the main loop know that a command string is ready, and the
main loop in turn calls the command parser, which executes the string.
The box I'm doing now has exactly 100 distinct serial commands. Some
user commands can call certain canned sequences, stored as strings,
which the parser executes re-entrantly. So far so good.

But some command strings can take a long time, perhaps minutes, to
execute. So I've assigned one serial character as an abort. When the
ISR sees this, it just resets the stack and jumps to the top of the
main opside loop, totally dumping whatever was going on and starting
fresh. I've asked a couple of my C guys how they would do this in C,
and the answers were sort of mumbles.

Another thing I like to do is copy a chunk of code, like the FPGA
loader, from eprom into a block of cpu ram, and execute it from there.
That speeds things up by 2:1 or so... no byte-wide bus fetches. Then I
can use that block of ram for normal system variables. All that sort
of thing is easy in assembly.

All my embedded programs are monolithic, absolute assemblies of a
single source file. I can usually archive a project *including all the
tools* on a single floppy. The program listings are heavily commented,
neatly paged, and start with an automatically generated table of
contents, which makes it really easy to see the structure and find
whatever you may be looking for. I can revisit a years-old project and
find what I want in seconds.

The methodology is ancient, like making bread in wood-fired ovens. But
it works.

John


Even if you prefer assembler, you would benefit from learning C. I had
a project where we weren't sure exactly how the word width effected
performance, so the hardware was emulated in C. Once we understood the
rounding issues, we knew how to build the hardware for real. OK, we
made it one bit wider just in case...

In your application, you might experiment with the DSP filter in C,
get a handle on the number of taps required, then program it in
assembler. I didn't look carefully at your particular app, but IIR
filters have settling issues in DSP. You get more bang (filtering) for
the buck (cycles), but FIR is free from limit cycle issues.

To sum it up, C may not be your in final product, but it can be a
usefull development tool.

BTW, isn't a CDROM cheaper than a floppy?
 
J

John Devereux

Jan 1, 1970
0
[...]

What I'm doing works.

I have the UART interrupt service routine, which builds a string from
edited input characters. When the command string is done, it sets a
flag to let the main loop know that a command string is ready, and the
main loop in turn calls the command parser, which executes the string.
The box I'm doing now has exactly 100 distinct serial commands. Some
user commands can call certain canned sequences, stored as strings,
which the parser executes re-entrantly. So far so good.

But some command strings can take a long time, perhaps minutes, to
execute. So I've assigned one serial character as an abort. When the
ISR sees this, it just resets the stack and jumps to the top of the
main opside loop, totally dumping whatever was going on and starting
fresh. I've asked a couple of my C guys how they would do this in C,
and the answers were sort of mumbles.

There is a facility called setjmp/longjmp which can be used for this
sort of thing. However ISRs are outside the official C language, so I
think whether it works would be dependent on the implementation on
your system. So use assembler just for that bit (the stack reset and
jump).

A C based application will generally have a small amount of assembler
to support it. This is usually confined to startup code and wrappers
for interrupt handlers. It is also used for code which manipulates the
stack, like task-switching and like your example.
Another thing I like to do is copy a chunk of code, like the FPGA
loader, from eprom into a block of cpu ram, and execute it from there.
That speeds things up by 2:1 or so... no byte-wide bus fetches. Then I
can use that block of ram for normal system variables. All that sort
of thing is easy in assembly.

This is commonly done in C systems too, where on-chip ram is faster
than flash. It is quite easy to do, since C has do do this already,
for initialized data. You tell the linker to put the code in the same
segment as initialised data, and the C startup code automatically does
the copying for you.
 
J

John Larkin

Jan 1, 1970
0
On Nov 24, 10:39 am, John Larkin
John Larkin wrote:
@hotmail.com> wrote:
Here is the basic realpole filter which is simpler and appears to have
almost identical response:
const u8 order = 4;
s32 LPF(s32 x)
{
static s32 z[order];
for(u8 i = 0; i < order; i++) x = z+= (x - z)>>6;

return x;
}
Making digital filter as the simulation of an analog filter is rarely a
good idea.
I've sold over 3000 of the temperature controllers that use this
filter.
McDonalds serves somewhat 10 billion meals per year. But this fact doesn't
make those meals taste any better or worse :)
Selling things for high prices to high-end customers, in volume, for
years, bug-free, means we're doing exactly what we want to do. Any
other criterion for engineering quality is, literally, academic.
Why whining about the Evil Empire of Bill Gates then?
Because it's slow, bloated, and bug-ridden, from a company run by
sociopaths who crush competition out of sheer ruthlessness.
I am sorry if you didn't understand 3 lines of trivial C code without
comments. It would be a good idea to do some learning before suggesting the
advanced digital filter topologies...
I've made a solemn vow to never code in C.
Yes. C++ is lot better.
Funny! I write apps that run in, typically, 4-6 kilobytes of eprom and
2K of ram, manage a few FPGAs and a VME or serial/ethernet interface,
run thousands of interrupts per second, and have guaranteed response
times in the 100 usec sort of range, 100% of the time. And never
crash.
But comments don't explain
code, comments explain what code is for and what it does. Your filter
is just a heap of code. I have no idea what it's response is like, and
would have to analyze or simulate it to determine that.
So, what is its frequency response?

1/64
H(Z) = (---------------) ^ 4
63
1 - --- Z^-1
64
So, what is its frequency response?

I suppose you could use the bilnear transform to map it into the S
domain, then do a spreadsheet to see the response.
Learning basic C isn't that difficult. The object oriented flavor is
another story.

What I'm doing works.

I have the UART interrupt service routine, which builds a string from
edited input characters. When the command string is done, it sets a
flag to let the main loop know that a command string is ready, and the
main loop in turn calls the command parser, which executes the string.
The box I'm doing now has exactly 100 distinct serial commands. Some
user commands can call certain canned sequences, stored as strings,
which the parser executes re-entrantly. So far so good.

But some command strings can take a long time, perhaps minutes, to
execute. So I've assigned one serial character as an abort. When the
ISR sees this, it just resets the stack and jumps to the top of the
main opside loop, totally dumping whatever was going on and starting
fresh. I've asked a couple of my C guys how they would do this in C,
and the answers were sort of mumbles.

Another thing I like to do is copy a chunk of code, like the FPGA
loader, from eprom into a block of cpu ram, and execute it from there.
That speeds things up by 2:1 or so... no byte-wide bus fetches. Then I
can use that block of ram for normal system variables. All that sort
of thing is easy in assembly.

All my embedded programs are monolithic, absolute assemblies of a
single source file. I can usually archive a project *including all the
tools* on a single floppy. The program listings are heavily commented,
neatly paged, and start with an automatically generated table of
contents, which makes it really easy to see the structure and find
whatever you may be looking for. I can revisit a years-old project and
find what I want in seconds.

The methodology is ancient, like making bread in wood-fired ovens. But
it works.

John


Even if you prefer assembler, you would benefit from learning C. I had
a project where we weren't sure exactly how the word width effected
performance, so the hardware was emulated in C. Once we understood the
rounding issues, we knew how to build the hardware for real. OK, we
made it one bit wider just in case...


Oh, I do a lot of numerical and system simulation, but I do it in
PowerBasic. There are lots of situations, like doing a weird pll, or a
Hilbert in an FPGA, where nothing but simulation will tell you what
the quantization issues will be.
In your application, you might experiment with the DSP filter in C,
get a handle on the number of taps required, then program it in
assembler. I didn't look carefully at your particular app, but IIR
filters have settling issues in DSP. You get more bang (filtering) for
the buck (cycles), but FIR is free from limit cycle issues.

The filter that I posted was for cleaning up thermocouple samples. All
the math was 32 bits, and the bata was noisy to start, so any limit
cycles in this case would be way down in the mud. I used two versions
of the filter, one for the control loop and a *really* slow one for
the user display! Everybody wanted to see the 0.1 degree digit hold
steady, even though turbulence downstream of the heater was flailing
the t/c temperature around almost 1 degree RMS.
To sum it up, C may not be your in final product, but it can be a
usefull development tool.

BTW, isn't a CDROM cheaper than a floppy?

I guess, but loading a floppy is quicker... drag and drop. Ten or 20
cents doesn't matter when the data cost $50K to create.

We run a bunch of DOS machines in test racks and stuff, and flops are
handy for them, too.

John
 
39 am, John Larkin
On Fri, 23 Nov 2007 12:43:10 -0600, Vladimir Vassilevsky
Here is the basic realpole filter which is simpler and appears to have
almost identical response:
const u8 order = 4;
s32 LPF(s32 x)
{
static s32 z[order];
for(u8 i = 0; i < order; i++) x = z+= (x - z)>>6;
return x;
}
Making digital filter as the simulation of an analog filter is rarely a
good idea.
I've sold over 3000 of the temperature controllers that use this
filter.
McDonalds serves somewhat 10 billion meals per year. But this fact doesn't
make those meals taste any better or worse :)
Selling things for high prices to high-end customers, in volume, for
years, bug-free, means we're doing exactly what we want to do. Any
other criterion for engineering quality is, literally, academic.
Why whining about the Evil Empire of Bill Gates then?
Because it's slow, bloated, and bug-ridden, from a company run by
sociopaths who crush competition out of sheer ruthlessness.
I am sorry if you didn't understand 3 lines of trivial C code without
comments. It would be a good idea to do some learning before suggesting the
advanced digital filter topologies...
I've made a solemn vow to never code in C.
Yes. C++ is lot better.
Funny! I write apps that run in, typically, 4-6 kilobytes of eprom and
2K of ram, manage a few FPGAs and a VME or serial/ethernet interface,
run thousands of interrupts per second, and have guaranteed response
times in the 100 usec sort of range, 100% of the time. And never
crash.
But comments don't explain
code, comments explain what code is for and what it does. Your filter
is just a heap of code. I have no idea what it's response is like, and
would have to analyze or simulate it to determine that.
So, what is its frequency response?
Here:
1/64
H(Z) = (---------------) ^ 4
63
1 - --- Z^-1
64
So, what is its frequency response?
John
I suppose you could use the bilnear transform to map it into the S
domain, then do a spreadsheet to see the response.
Learning basic C isn't that difficult. The object oriented flavor is
another story.
What I'm doing works.
I have the UART interrupt service routine, which builds a string from
edited input characters. When the command string is done, it sets a
flag to let the main loop know that a command string is ready, and the
main loop in turn calls the command parser, which executes the string.
The box I'm doing now has exactly 100 distinct serial commands. Some
user commands can call certain canned sequences, stored as strings,
which the parser executes re-entrantly. So far so good.
But some command strings can take a long time, perhaps minutes, to
execute. So I've assigned one serial character as an abort. When the
ISR sees this, it just resets the stack and jumps to the top of the
main opside loop, totally dumping whatever was going on and starting
fresh. I've asked a couple of my C guys how they would do this in C,
and the answers were sort of mumbles.
Another thing I like to do is copy a chunk of code, like the FPGA
loader, from eprom into a block of cpu ram, and execute it from there.
That speeds things up by 2:1 or so... no byte-wide bus fetches. Then I
can use that block of ram for normal system variables. All that sort
of thing is easy in assembly.
All my embedded programs are monolithic, absolute assemblies of a
single source file. I can usually archive a project *including all the
tools* on a singlefloppy. The program listings are heavily commented,
neatly paged, and start with an automatically generated table of
contents, which makes it really easy to see the structure and find
whatever you may be looking for. I can revisit a years-old project and
find what I want in seconds.
The methodology is ancient, like making bread in wood-fired ovens. But
it works.
John

Even if you prefer assembler, you would benefit from learning C. I had
a project where we weren't sure exactly how the word width effected
performance, so the hardware was emulated in C. Once we understood the
rounding issues, we knew how to build the hardware for real. OK, we
made it one bit wider just in case...

Oh, I do a lot of numerical and system simulation, but I do it in
PowerBasic. There are lots of situations, like doing a weird pll, or a
Hilbert in an FPGA, where nothing but simulation will tell you what
the quantization issues will be.


In your application, you might experiment with the DSP filter in C,
get a handle on the number of taps required, then program it in
assembler. I didn't look carefully at your particular app, but IIR
filters have settling issues in DSP. You get more bang (filtering) for
the buck (cycles), but FIR is free from limit cycle issues.

The filter that I posted was for cleaning up thermocouple samples. All
the math was 32 bits, and the bata was noisy to start, so any limit
cycles in this case would be way down in the mud. I used two versions
of the filter, one for the control loop and a *really* slow one for
the user display! Everybody wanted to see the 0.1 degree digit hold
steady, even though turbulence downstream of the heater was flailing
the t/c temperature around almost 1 degree RMS.


To sum it up, C may not be your in final product, but it can be a
usefull development tool.
BTW, isn't a CDROM cheaper than afloppy?

I guess, but loading afloppyis quicker... drag and drop. Ten or 20
cents doesn't matter when the data cost $50K to create.


I have given up on CD-R or CD_RW now too.
Only DVD or memory stick or SDcards.
Not that I use it, but with UDF and packet writing, you can drag and
drop
to DVD or CD too, already in win 98 actually.

But SDcards are way cool, perhaps even keep data longer then DVD.
It makes sense to use both.
 
Top