Using OpenEEG’s Fiview to reproduce the Cade-Blundell filters

Now I have convinced myself that I can get a version of the OpenEEG hardware to run into EEGmir, I want to how see if I can reproduce one of the Cade-Blundell filters. I have an analogue simulation from earlier, and I want to see if I can reproduce this in EEGmir. The filter specification protocol in EEGmir is the same as in Fiview from Jim Peter’s site[ref]they use the same underlying library, fidlib[/ref], and since that displays the transfer function it looks like a good place to start.

a tale of linux graphical display woe…

The windows version doesn’t run, beats me why. So I try it on Linux. My most powerful Linux computer is an Intel NUC but because Debian is hair-shirt purist and therefore snippy about NDAs and proprietary drivers, I think it doesn’t like the graphics drivers. It was tough enough to get the network port working. Xserver and VNC is so deeply borked on that. If something is stuffed on Linux then it’s reload from CD and start again because I haven’t got enough life left to trawl through fifty pages of line noise telling me what went wrong. So I’m stuck with the command line. So I try fiview on the Pi, and this fellow sorts me out on tightVNC and the Pi which is a relief, trying to get a remote graphical display on a Linux box seems to be an endless world of hurt, and I only have a baseband video monitor on the Pi console.

Simulating the 9Hz Blundell filter

I already have SDL 1.2 on the Pi, so it goes. Let me try the 9Hz channel, which was the highest Q of the Cade-Blundell filters. If you munge the order and bandwidth specs you get fc=9Hz BW=1.51.

Converting that to Fiview-speak that is

fiview 256 -i BpBe2/8.22-9.72

which in plain English means simulate a sampling rate of 256Hz bandpass Bessel 2nd order IIR between 8.22 and 1.51. So let’s hit it.

fiview on the 9Hz Cade-Blundell filter. Shame about the linear amplitude axis…

Unfortunately the amplitude axis is linear, which is bizarre. Maybe mindful of their 10-bit (1024 level) resolution OpenEEG didn’t want to see the horror of the truncation noise and hash. I can go on Tony Fisher’s site (he wrote the base routines Jim Peters used in fiview) and have another bash

The same filter with a log amplitude scale, but a linear frequency scale Grr…

Running the analogue filter with the same linear frequency display I get

The analogue filter in LTspice on a linear frequency scale (256Hz × 0.15 = 38Hz, roughly the same endpoint as the digital chart)

which shows the same response[ref]It’s not strictly exactly the same because of the increasing effect of the frequency warping of the bilinear transformation as the frequency approaches fs/2. But in practice given the fractional bandwidth of the filters the warping only has an effect in giving the upper stopband a subtly different shape in the tails, I struggle to see it here.[/ref]. H/T to the bilinear transformation for that. I had reasonable confidence this would work, I did once cudgel my brain through this mapping of the imaginary axis of the s plane onto the unit circle when I did my MSc. Thirty summers have left their mark on the textbook and faded the exact details in my memory 😉 But I retained enough to know I’d get a win here.

My late 80s digital filtering textbook after many years

Modding the OpenEEG analogue to digital converter and comparing with OpenBCI

Now I can get signals into the OpenEEG modP2 format, the next stage is to qualify the filtering used within eegmir and to put an antialiasing filter in front of the ADC. The sampling rate is only 256Hz, so the highest frequency possible is 128Hz. Anything else will alias down, particularly frequencies +/- 50Hz of 256Hz, which will be aliased down to 0-50Hz and corrupt my area of interest. This includes the fourth, fifth and six harmonics of the 50Hz power frequency and the second harmonic of the 100Hz full-wave rectifier ripple tossed onto the powerline by every switched-mode power supply in the neighbourhood.

OpenEEG are good enough to put their schematic up on the Web, so I simulated their antialiasing filter.

Simulation of OpenEEG analogue filtering injecting signal at Electrode DC checkpoint, front-end isolated. Line is at the Nyquist frequency fs/2

Hmm, colour me underwhelmed. At a 10-bit resolution the steps are 1/1024, so quantisation noise is 20×log(1/1024) or about -60dBFS. So you’d like to be 60dB down at fs/2 of 128Hz, which is where I’ve drawn the line. We are at, …drum roll…, -16dB by then. At least the crap there gets aliased to the high frequencies, but by fs we are at -26dB. Nice try, but no cigar. I guess that’s the price I pay for saving myself the grunt of lining up all those analogue filters. TANSTAAFL and I get to try harder here. At least there are only two of these filters.

Elliptic filter design

The obvious way here would be to get an elliptic filter and target a notch at fs/2 and another at fs. I had thought there would be an online calculator by now, but perhaps nobody makes analogue filters any more[ref]You can do this with Matlab it appears, if you have a spare £1800. That looks a lot easier then the filter table process I used[/ref]. So it’s back to the Williams book. It’s all about the ratio between stopband and passband. The stopband is non-negotiable at fs/2, say 120Hz so hopefully a notch will be dropping just beyond that into 128 Hz. I have flexibility on the passband, the Mind Mirror goes up to 38Hz, say I choose a passband cutoff of 60Hz, I get a steepness of 2. I’m easily prepared to take a passband ripple of 0.3dB (p=25%)[ref]Electronic Filter Design Handbook, A Williams, McGraw-Hill, 1981, Table 2-3[/ref] so I am after a C ?order 25 ?theta

From Table 2-2 I want Θ=30° for my steepness of 2, so I want a C ? 25 30 filter, with only the order to determine. I’d really like that to be 3 rather than 5 😉 Sadly I look up C 03 25 28[ref]Electronic Filter Design Handbook, A Williams, McGraw-Hill, 1981 Table 12-57[/ref] and the stopband is only 30dB. Shifting Θ=20° would give me a steepness of 3 and a stop of 40dB, so my passband comes down to 40Hz

A C 05 25 32 would give me a stop of 60dB, I will give some of that up in component tolerances, but it’s better than 16dB and gives me some chance to fight all that mains rubbish, so let’s take a look.

the magenta line is the theoretical version, the green using preferred values. The blue line is the original OpenEEG one

It’s not bad. I’d probably want to shift the corner frequency down by 5Hz. It’s good that it isn’t anywhere near as sensitive to component values as the Cade-Blundell bandpass ones were, the shifts due to preferred values were significant but the traces are close. For comparison the original OpenEEG line is in blue. The filter is complex, but not terrible, I can take solace that this is the quid pro quo for not having to line up all those 54 filter centre frequencies 😉 Continue reading “Modding the OpenEEG analogue to digital converter and comparing with OpenBCI”


So far I have inched my way to making a Mind-Mirror compatible EEG in a theoretical way, but to make it work in real life I need a way of getting signals into the machine. You can buy a board made by Olimex for a reasonable £50, you get optoisolation and everything, and it’s probably the most cost-effective way. Trouble is I don’t know that EEGmir works yet, so I want to do it cheaper, and also now. A Microchip PIC16F88 will do the job here, and I have a few 🙂

eegmir, meet world. And that crystal was made in 1987 and has waited 30 years to find a purpose in life

I tinkered using this SPBRG calculator to find a suitable crystal to run the PIC16F88 at to match both the 256Hz sampling rate and the baud rate. The first run of EEGmir showed me nothing at all.

Inquiring further it seems the Raspberry Pi gets shirty about a 3% baudrate error at 57600 baud. I set up a test PIC to pump out an endless string of As, and when I brought up minicom they showed up as Ps. This is not good.

I needed to go find a 3.6864 MHz crystal, which lets you get down to 0% error at 57.6k, and by a fortunate stroke of luck fc/4 divides down integer-wise to 256Hz. Nice. So I did that, sending a bunch of As in the data frames to the Pi, after padding down the 5V TTL signal from the PIC.

You goofed, sunshine. Repeated over and over again. I get the message, guys!

Mincom showed the As OK from the test PIC, but it wouldn’t let go of the TTY until I rebooted. EEGmir comes up and shows me a load of gobby stuff about data errors. Pressing F12 shows it is assessing jitter

Did I really screw up that much computing the sampling rate?

and telling me I have a sampling rate of 325Hz. The nice thing about hardware is you can get a second opinion. Sometimes it’s the smoke pouring out of something, but here it’s in the frame rate of the signal, as I gave myself a sync pulse on a spare PIC pin to synchronise my scope to. So I appeal the outrageous assertion that I am running too fast

Yup, you’re too fast, bud

and get handed down the verdict of guilty as charged, I did screw up. And I didn’t wait for the camera to focus.

Let’s look on the bright side. This PIC is sending out data at the right baud rate, sort of the right number of frames, too damn fast. And EEGmir is reading from the Pi serial port and struggling manfully to make some sense of it. The (256Hz) on the jitter display even gives me hope it might adapt if I choose to run at 128Hz. Oh and I find that the escape key is the quit command in EEGmir, which saves having to go find the PID and do a kill-9 PID on it, which always feels a bit bush league.

The sampling rate error is because I failed to wait for the TMR1 to time out which I was using to define the frame rate, doing that fixed the sampling rate, it’s now 256.04 according to EEGmir. Still hollering about data errors, so I probably failed to understand the OpenEEG2 protocol somehow. Continue reading “OpenEEG2 ADC”

Running EEGMIR on a Raspberry Pi

In my library/Google trawl I turned up EEGMIR which is to be found here. This uses regular C code to run the IIR filters, the implication is this is a digital implementation of analogue filters, probably achieved by transforming the s plane to the z plane and predistorting the response. This would save me heroic amounts of tweaking analogue filters. If I could run it on a Raspberry Pi, i could get my Mind Mirror 1 LED display by extending the display code and using the GPIO.

But first I need to characterise the program, compile it on the PI and get it working. And the program is 14 years old… I’m not a C guru though I have used the language, not professionally but in its bastardised form for the Arduino, and I’m not a DSP guru either. So I’m hopelessly way out of my depth. I do like the way Jim Peters took an interesting approach to the amplitude display of the bands, downconveritng the bandpass with fc to make a direct-conversion receiver to DC. When you can do this with an IQ demodulator it works better than the amateur radio hardware implementation. But first things first. Does it compile?

Compiling eegmir on the Pi

I get a new Raspberry Pi B+ V2, and a copy of jessie-lite. If you are starting form scratch use a regular Pixel Jessie install. it’s a graphical program though it looks ugly, so you need the Xwindows system.

sudo apt-get update
sudo apt-get upgrade

[GUIDE] Raspbian Lite with PIXEL/LXDE/XFCE/MATE/Openbox GUI

to install Pixel. And X. That’s why you should have started with a full install. EEGMIR is a graphical display program, nearly everything else I use Pi for is command line. I don’t normally bother with the desktop on a Pi because I run these guys headless.

do ./mk a
compiler screams, I need something called SDL. Due to the age of the program SDL2 doesn’t work. Install SDL 1.2

sudo apt-get install libsdl1.2-dev libsdl-image1.2-dev libsdl-mixer1.2-dev libsdl-ttf2.0-dev

now ./mk a grizzles thusly

=== page_bands.c
tmp-linux/page_bands.c: In function ‘draw_signal’:
tmp-linux/page_bands.c:335:4: error: label at end of compound statement

Hmm. I’m in trouble now, I look at Jim Peters’ code page_bands.c and he makes a leap out of some nested loops

//    Draw the signal area

static void 
draw_signal(PageBands *pg, int xx, int yy, int sx, int sy, int tsx) {
   int tb= 1;    // Timebase -- samples/pixel
   int a, b;


        if (oy0 < sy && oy1 >= 0) {
           if (oy0 < 0) oy0= 0;
           if (oy1 >= sy) oy1= sy-1;
           vline(xx + ox, yy+oy0, oy1-oy0+1, pg->c_sig1);
   no_more_data: // <- COMPILER MOANS ABOUT THIS

I’m in pretty deep trouble here. I don’t really understand what’s going on. I invoke the spirit of the Big G on the error message and I am educated like so

 case 5: 
     // here you need to add statement 
     //if you don't want to do anything simple break statement will work for you

to lob in a break statement after that no-more-data: label. I am hacking, I’m not proud of it but sometimes you have to try and keep the wheels running to make progress 😉 . Compiler is now happy with a modest amount of bellyaching

=== fidlib/fidlib.c
 In file included from fidlib/fidlib.c:622:0:
 fidlib/fidmkf.c:151:1: warning: conflicting types for built-in function ‘csqrt’
 csqrt(double *aa) {
 fidlib/fidmkf.c:175:1: warning: conflicting types for built-in function ‘cexp’
 cexp(double *aa) {

I throw caution to the winds and run the program. It now comes up but spits bricks on the command line

[email protected]:~/eegmir/eegmir-0.1.12 $ ./eegmir
 eegmir: Unable to open serial device: /dev/ttyS0

maybe need to detach ttyS0. You do that with Raspi-config, turn off terminal output but keep the hardware enabled, Still moans about ttyS0. That’s because on the Pi this should be ttyAMA0

I change ttyS0 to ttyAMA0 in eegmir.cfg

it now responds, though glacially slowly on Xwindows, to the F2 (MM) and F3 (display test) and F4 (exponential frequency map) and F10 (jitter calc). I take the hit and run it on a real composite video display. My cable was a camcorder cable so I needed to use the right audio cable. Ain’t Google marvellous.

Responsiveness is much improved. My addition of the break statement has not obviously borked the program. In Googling there was talk of some versions of gcc letting the empty statement after a label pass and some versions getting shirty, maybe this was different 14 years ago.

The Mind Mirror screen. Observe the ominous rattle in the LF channels with 0 input. On a 16 LED display this will not matter one whit

I observed the lack of settling to zero on the IIR filters in the low frequencies, which corroborates the feeling i got reading about the effects of truncation of the filter coefficients being worse close to the sampling frequency and close to zero. After all, I can absolutely dead-certain guarantee that the input is digital silence, because there is no input.

The jitter test screen on F10 moans at me that it can’t work out the jitter. Can’t really argue with that, because there is no input. I need to go fix that next.

Pressing F11 gives me

So I jack a pair of cans across the audio output of the Pi and I get to hear what sounds to me like 1kHz tone


This program is on Github at

Jim Peters GPL2 it so I have retained the same license on Github

Conclusion – it works in principle

So far I surmise that I haven’t mortally wounded the program by tossing in that arbitrary break statement and that it will run on a Pi. I have no idea of if I have enough MIPS for a decent performance. A Raspberry Pi 2 has 4,744 MIPS whereas a 2003 vintage Pentium 4 had 9,726 MIPS, since I am using a Pi B+ which is less than the pi 2 I may be short of processing grunt. But for that I need a signal.

Rummaging around looking for the HDMI to VGA adapter I had in the loft I found a Pi 2 sitting unloved, so I swapped the B+ for a Pi2 for an instant hardware upgrade. There is a comparison of the performance of the B+ and the 2 here. The program is more responsive now, so I do the whole

sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade
sudo apt-get clean

and then recompile, this time it recompiles all the program components, so I figure something changed under the hood to get all those four cores working for me. I get the same griping about the conflicting types.

I find out how to boost the bar gain, to take a better look at that suspected truncation noise in the low frequency filters. That’s the b key followed by a number

boosted LF cruft

This doesn’t really trouble me, that’s lifted by 100 times. I will do gain control in the analogue domain and the Mind Mirror did not eq individual channels or do any other levelling other than master gain. But it shows that the 0.75Hz Mind mirror channel could be ‘interesting’ to add. Truncation noise seems to get worse as you get to fs/2 and to 0. fs/2 is 128 Hz so I am well away from that, I could benefit from halving fs, and is something to bear in mind in the hardware design, and testing if the software will adjust.

EEG Open Source hardware and software search

A couple of months in the laboratory can frequently save a couple of hours in the library.

Frank Westheimer

And now we have Google 😉 In an attempt to avoid some of that time in the lab lining up a load of analogue filters I was tempted to go DSP, but I lack the DSP smarts to do this in hardware, so I turned to the Big G again. Turns out I didn’t spend enough time in the library.

An EEG has two technical challenges, the hardware of the signal-conditioning amplifiers, and then the display mechanism, which was an analogue filter bank and LEDs in the original Mind mirror, and a computer display afterwards. This is software, and in modern practice this hardware/software division is clear. There has been a lot of open source activity in this field, although as it happens I am still drawn to the retro.


There are two big open source/hardware projects for EEG hardware that I can find. OpenBCI seems to be in the lead with a multichannel board that digitises 16 channels of EEG and sends this via Bluetooth to a computer. There is another one, OpenEEG, which seems to be at least 15 years old. Anybody who still keeps their introductory material in Adobe Flash has clearly not kept up with the times.[ref]The sooner the company Adobe can be stamped into the ground and turned to dust for dreaming up such an evil concept as the Creative Community software rental scam the better IMO. I am glad that the Internet finally picked up the fact Adobe is an insidious protection racket holding your work to ransom and rerouted around it bringing us HTML5 audio and video. Creative Cloud is the epitome of what’s wrong with the damn Cloud. They got you by the goolies,[/ref]

The obvious one to favour is OpenBCI, but there’s one small problem. It’s shockingly expensive. A Cyton + Daisy RF module gives me an impressive 16 channels for about a thousand dollars. In comparison, the Vilistus 4 interface is £650 (£850 with Bluetooth).

£540? You have to be kidding, right?

Unfortunately in the latter case one has to buy a 1984 DOS looking piece of software for £540, which is apparently the most advanced Mind Mirror program yet. Even if I were a billionaire it would pain me to hand over £540 for something that looks like an old program I wrote for a BBC Micro in the late 1980s tracking galvanic skin resistance. But compared to OpenBCI their hardware is pretty good value.

OpenEEG has the problem of being 10-15 years old. The schematic is from 2003, but pretty much how I would have done it. It doesn’t base it all on a proprietary chip, if I blow the input up the INA114P can be changed out for about £7. It’s available for ~£75 assembled, which is sort of within the groove. I’m kind of up to £200 interested in this, not much more. It’s only two channel. I could get the digital interface for another £50.

So although it’s old, OpenEEG matches my budget and requirements better. There’s not much point in me trying to wrangle the analogue front-end myself, unless I use active electrodes, in which case I can lose the INA114P and I may as well make the analogue back-end LPF of OpenEEG on veroboard


Looks like I am late to the party and EEGMIR from Jim Peters on the openEEG project had largely solved this for me more than 10 years ago. Now I just said a lot of rude things about Vilnius’s most advanced MM software looking fugly, and EEGMIR isn’t a thing of beauty either

but you can’t grouse about the price, if it works 😉 Instant win. Since it runs on Linux it will be Raspberry Pi friendly, in theory, though I have no idea of how much Linux has changed in the intervening 14 years. The nice thing about the Pi is all those GPIO pins – so I can hate on this display all I like, but if I want it to be on LEDs I can do it. And Jim Peters seems to be using IIR filters from the filter description language. I would need to purchase the £50 EEG Digital board or hack a PIC or an Arduino to output the openEEG type 2 serial data format. A 16F88 would probably cope a treat on two channels. Continue reading “EEG Open Source hardware and software search”

First evidence for higher state of consciousness found at Imperial

It’s heartening to see that all that drinking, listening to Pink Floyd and setting the world to rights many years ago at my alma mater has finally borne fruit at Imperial

Researchers have uncovered the first scientific evidence of a ‘higher’ state of consciousness.

In the study, neuroscientists observed a sustained increase in the diversity of brain signals of people under the influence of psychedelic drugs, compared with when they were in a normal ‘awake and aware’ state.

This measure of the complexity of brain activity – called neural signal diversity – provides an index of the level of someone’s consciousness.

Scientists have shown that people who are awake have more diverse neural activity using this scale than those who are asleep. Previous studies have tended to focus on lowered states of consciousness, such as when people are asleep, under anaesthesia, or are in a ‘vegetative’ state.

Must’ve been an interesting assignment.

For the study, Michael Schartner, Dr Adam Barrett and Professor Seth of the Sackler Centre reanalysed data that had previously been collected by Imperial College London and the University of Cardiff in which healthy volunteers were given one of three drugs known to induce a psychedelic state: psilocybin, ketamine and LSD.

Poor old Max Cade was there in the 1970s, although without the psychedelic drugs, and elementary observation of the likes of Syd Barrett on acid or listening to some of the, er, stranger Floyd tracks might have shown that LSD alters consciousness, but it’s good to have independent corroboration. Exactly why they chose to use a magnetic imaging technique rather than, say EEG but good for them. Slightly embarrassing for Imperial who did the initial work, it appeared they failed to spot the differences, and it was the University of Sussex who reprocessed the data. Perhaps post-processing had got more powerful since the original results.

A good year for Nightingales, locally

First I hear a pair at Newbourne Springs, then one at Orwell Country Park

Orwell Country Park, not really classic Nightingale habitat of low scrub


and finally one at Mill Stream Nature reserve

Three separate places with a fair amount of human and dog interference in less than a week.

The BTO doesn’t seem to agree that it’s a good year countrywide – Nightingale reporting seems lower than the historical average

Nightingal reporting seems down accordign to Birdtrack