Building the Mind Mirror filter bank

Drafting out the Mind Mirror analogue filters, scaling values to the nearest good combination of series resistors looks good at 1% tolerances of resistors and capacitances, according to LTspice

Monte Carlo simulation at 1% tolerance

but realistically the capacitance tolerances are 10% although resistors are 5%, and that’s makes a mess of some channels

Monte Carlo simulation with resistors at 5%, capacitors at 10%

in particular the 6,7.5, 9, 10.5, 12.5 and 19, 24, 30 and 38Hz channels. These are simulated using multiple-feedback bandpass filters (MFBP). I then simulated the same spread on the highest Q so most sensitive 9Hz band on the dual amplifier bandpass topology (DABP) and the state variable topology (SVBP) using three opamps per stage.

the DABP and SVBP simulated filters, SVBP on top. The funky values are so the Monte Carlo simulation can tinker with the values between runs

Both the latter are meant to have a lower sensitivity to tolerances, and both have the advantage of having a defined gain, whereas the MFBP gain varies quite dramatically with fractional bandwidth and Q.

sensitivity of the topologies, blue is the DABP, green is the MFBP and red is the SVBP

There’s not much to be won here with the different topologies regarding sensitivity to tolerances, which surprised me. Williams states that the DABP is less sensitive to component tolerances than the MFBP and the SVBP less still. Examining the SVBP I got a variation in level of 5dB, the MFBP of 2.4dB and the DABP of 3.07. I have the suspicion I will need to tune these, in which case the DABP is easier, since the MFBP has interaction between fc and Q in tuning, as well as a wider spread of resistor values with Q² as opposed to with Q in the DABP. However, that is 14ch × 2 stages × 2 sides = 56 pots or S.O.T. resistors 😉 As they said

The original analogue filters in Mind Mirrors 1 and 2 were precise but expensive to manufacture. The digital Band Pass filters parameters were modelled on the band pass characteristics of the analogue filters, and were able to more accurately guarantee the performance of the filters.

Lining up the analogue filters isn’t too hard – Williams [ref]Electronic Filter Design Handbook, A Williams, McGraw-Hill, 1981, p5-46[/ref] says set the input frequency to be the desired centre frequency, monitor the input and output of the filter on a scope set to XY mode and adjust filter centre frequency until the Lissajous figure closes to a straight line. The thought of doing this 56 times does not fill me with joy, however. So one last time, how about DSP?

The siren song of DSP

Certainly if you’re going to make more than one you’d go DSP, even I am tempted along the DSP route seeing the effect of tolerances on simulation, but that would make the whole thing too dear, and I have no DSP development system. It is possible to transform the analogue filters into IIR digital domain filters using the bilinear transformation so there’s no particular magic about getting a DSP implementation, apart from the learning curve and the price for a one-off.

I could use a Raspberry Pi and something like GNURadio to do that job. Power consumption will skyrocket, but I get to forget about tuning the filters. Alternatively something like octave with the signal package might work, but I haven’t convinced myself that this will display in real time. There also seems to be some degree of hurt available with IIR filters – GNURadio focuses on FIR filters and doesn’t seem to feature IIR very much. Perhaps because of that hurt 😉

The trouble is that I am a total noob with DSP, and to match the Mind Mirror shapes and delays I need to transform the analogue filters, which means IIR from the maths. And IIR seems to be the area that causes noobs trouble, in terms of the filters not settling due to truncation errors.

The obvious way is to use a FFT, or more likely the DFT implementation., but the catch at these low frequencies is that to get the frequency resolution to match the older filters I’d need sub-1Hz resolution. The DFT frequency resolution is fs/N. So imagine I sample at 1000Hz I need 1000 samples before I get any output, giving me a 1s latency. This seems to be the basis of the issues in using FFT to replicate the Mind mirror results. There is the very real possibility of Mind Mirror talking their book of course 😉

Or I could try an Arduino. With an analogue antialiasing filter of about 200Hz and a sampling rate of 1000Hz I could use IIR filters from and sample on change of millis(), the Arduino could then also do the LED display. Depending on how long the floating point maths takes I might be able to run two channels on the Arduino, so  I will end up with a rig with 14 Arduino chips. Sampling with the Arduino is doable, as shown here.

If I’m going to go microcontroller I could also consider a PIC, a 16F88 is £2.50 at 10-off prices, has onboard A/D. I use JAL as a high-level language for PICs because I’m not prepared to pay out £200 for a C compiler for those, so floating point is resource-hungry, but I understand interrupts etc on the PIC 16 series, where I don’t really on Arduino. The ATMega328 used in Arduino Uno is a similar price, which sort of favours the Arduino as there’s more example code and the sorta C compiler is free. But I get to either buy preprogrammed Arduino chips which are dearer or I get to buy an AVR programmer for about £20 to  program the Arduino bootloader onto vanilla ATmega 328s

Every time I look at everything else I need to do to make this happen digitally I am drawn back to the analogue solution. Lining up filters is tedious, particularly at such low frequencies, but easy.  I have a LCR meter so I could screen the capacitors to get a better tolerance, I could probably match them to 1% and recalculate the resistors for whatever value they are measured at. The DABP can be done with a single LM324 per channel, at 50p rather than £2.50 Arduino, and LM3914s are to be had cheaply from China. But before I actually go that way, I will take a step back, and investigate again what people have already done in this space. Researching this post picked up a fair amount of open source work in this field, and some of it looked like it would support IIR filtering.





5 thoughts on “Building the Mind Mirror filter bank”

  1. Thank you for sharing this and other subjects.

    In an old version of the site, Mr Neil Hancock or someone else, wrote:

    “The original analogue filters in Mind Mirrors 1 and 2 were precise but difficult to construct with individual components and became too expensive to manufacture. An unusual design was adopted for the filters which allowed the center frequency and bandwidth to be set independently. I have never seen this in a filter textbook even though it is very easy to implement. ”

    I’ve sent him one or two emails with no answer, because I’m puzzled with the filters he refer.
    Do you have an idea of what kind of filter he is talking about?

    As you note, they give a lot of information on the filters, (and say “We would be happy to supply the Filter coefficents”, but don’t. Shall we ask for them?), and they are just Butterworth and Bessel! Those are now digital, but supposed to mirror the analog ones… what do you think? How could they put so many components in the prior versions?



    1. The go-to reference in the Seventies when the MM was developed was Don Lancaster’s Active Filter Cookbook, I have a tattered copy of the 1975 first edition. That doesn’t have the DABP configuration which is in Williams, which does let you set Q and Fc separately, but it does have the biquad three op-amp config which superficially looks like the SVBP but isn’t the same. The biquad also lets you set Q and fc separately. I contacted Neil and he very kindly told me they used the biquad, implemented on an 80C196 in 1991. That chip is now discontinued. But I’d tend to favour a Raspberry Pi or suchlike nowadays. There’s lots of stuff on the web about the digital variants – this for instance, and if you have a SHARC development kit this seems to have example code but sadly it all looks like line noise to me 🙁

      Although lining up the analogue filters would be a first-rate PITA it wouldn’t be too hard to fit it all in. My initial ideas would be to make a modular set of 28 identical PCBs running as vertical daughter boards on a veroboard backplane feeding the power and wideband EEG signal in parallel. The LEDs would run along the top edge of the daughter board. Using the DABP configuration and quad opamp packages it wouldn’t be too hard to fit it all in, the original MM looks like it was about a two foot square. If I went SMD I could get it a bit smaller.

      1. Hi Richard.

        Thank you, very very much for the information I was looking for so many years.
        I am probably too old now to start the project, but maybe I get the courage… :-))

        Following your steps and after posting, I discover an Analog Devices Mini Tutorial (209) where they say the DABP allow the center frequency and bandwidth to be set independently!

        I thought about using Gyrators and Antoniou inductance-simulation circuit could solve the problem of the coils, but this would complicate too much the design.

        To get the 50db/oct they refer, I expect a filter with a signicant order. With my comment about the space, I mean that the filter circuits in MM I and II could not be very complicated to fit in the box, since I expect them to use DIL ICs, and 5mm LEDs, for example, besides it should get hot! Of course now is much easier with SMDs and low power components.

        Your idea of the Veroboard backplane and daughter boards seems very interesting, but shouldnt you
        anticipate a lot of noise? Is it screenable?

        I agree that RPi or similar would do the job, and is probably powerful enough to implement the filters, if not in Python, at least in C, but it has to be tested. Still, for some reason, I would trust much more the hardw solution, don’t ask me why. (Yes, its a PITA…). I will wait for your veredict! ;-))))
        There is another problem: how to get real input data for the tests, and how to validate the results.
        Maybe some leprechaun give you a copy of a MM real session recording… ;-))

        Thank you once more.



        1. I read the 50dB/oct as the response an octave off the frequency of interest. More like a matching template, which is often how you line up an analogue filter on a spectrum analyser and tracking generator.

          Let’s face it, these guys were using a 16 LED linear (I assume!? from the uV in the spec) display, so each step is about 5%FS. You only have to get spurious responses to be -24dBFS to be lost in the LSB

          The 9Hz filter drops by 36dB @ 4.5Hz and [email protected] When you look at this

          and see the specs are for the passband to be 3dB down that makes the drop 39 and 38dB an octave out. That’s using two cascaded second-order BP sections, so the ultimate attenuation is 12dB/octave in the stopband.

          That’s good enough for me. It’s possible the MMI used three cascaded analogue sections, but since the DSP version ran at -40dB I will stick with two. If they wanted to achieve -50dB/8ve ultimate rejection they’re on 8 cascaded sections, That just sounds way OTT for what’s not an incredibly high resolution display. And lining that 16 sect filter up would be a stupendous misery.

          FWIW Neil said the filter coefficients were the digital coefficients for his DSP implementation. I wouldn’t be using the same chip or code so I am guessing that’s not applicable. Sounds like Blundell was the analogue man, so the analogue knowledge was lost in 2003, but I am reasonably confident I matched the analogue passband/stopband specs in when taken in connection with knowing the filters are all Bessel other than the lowest Butterworth.

          The veroboard would be fine. We’re talking frequencies of < 250Hz, and the backplane signal would be driven at low impedance from the input signal conditioning circuit with the instrumentation amps and rough low-pass filtering. I could use the OpenEEG front-end supplied by Olimex for about $100

          if you look at the schematic

          it comes straight off the TLC272 opamp so will be lo-Z. Personally I’d put a 47R resistor is series with that so the opamp doesn’t hoot and take off at some high frequency when driving the cable, but maybe it’s unity gain compensated. It would probably be a good idea to buffer into the backplane. Some of the active filter topologies assume a Lo-Z drive anyway.

          I agree that RPi or similar would do the job, and is probably powerful enough to implement the filters, if not in Python, at least in C, but it has to be tested. Still, for some reason, I would trust much more the hardw solution, don’t ask me why.

          I know what you mean, but take a look at my recent post on this. I’m really, really, trying to convince myself not to go analogue, because it is the 21st century, and I really ought to smarten up my act and learn DSP, or at least the RPi version. Looks like somebody has already a Linux impementation of the MM filters, which would change the job into getting something to take the output of the Olimex board and munge it into OpenEEG2 format. Which sounds like a job for an Arduino or a PIC 16F88 these days. But I need to first find out if I can compile that program for the RPi

Leave a Reply to Mike Cancel reply

Your email address will not be published. Required fields are marked *