A first look at the Olimex EEG-SMT

31/01/2013

Last week I ordered and received a small EEG device manufactured by a Bulgarian company called Olimex. Called the EEG-SMT, it is part of the OpenEEG project, and is a small USB device that looks like this:

The Olimex EEG device.

The Olimex EEG device.

It has five audio jacks for connecting custom electrodes. The ground electrode is passive, and the other four electrodes are active and comprise two bipolar channels. The system is very basic, and at around €150 (including the electrodes) is obviously not going to compete with high end multi-channel EEG rigs.  But, I’m interested in running some steady state VEP experiments that can be run with a single channel, and in principle are quite robust to lower signal to noise ratios from lower quality equipment. Given the price, I thought it was worth a shot.

Although there are several PC packages capable of reading data from the device, I ideally want to integrate EEG recording into the Matlab code I use for running experiments. So, I decided to try and directly poll the USB interface.

The first stage was to install a driver for the device. I’m using a Mac running OSX 10.8, so I went with the FDTI virtual COM port driver. I also found it useful to check the device was working with this serial port tool. The driver creates a virtual serial port, the location of which can be discovered by opening a Terminal window and entering:

    ls -l /dev/tty.*

On my machine this lists a couple of bluetooth devices, as well as the serial address of the Olimex device:

    /dev/tty.usbserial-A9014SQP

Matlab has its own tool for polling serial ports (Serial). I was able to read from the device this way, but I found it less flexible than the IOPort function that comes with Psychtoolbox 3. The rest of this post uses that function.

First we open the serial port and give it a handle:

    [h,e] = IOPort(‘OpenSerialPort’,'/dev/tty.usbserial-A9014SQP’);

Then we can set a few parameters, including the baud rate for data transmission, buffer size etc:

    IOPort(‘ConfigureSerialPort’,h,’BaudRate=57600′);
    IOPort(‘ConfigureSerialPort’,h,’BlockingBackgroundRead=0′);
    IOPort(‘ConfigureSerialPort’,h,’InputBufferSize=65536′);
    IOPort(‘ConfigureSerialPort’,h,’PollLatency=0.0039′);

To start recording, we purge the buffer and then send this command.

    IOPort(‘Purge’,h);
    IOPort(‘ConfigureSerialPort’,h,’StartBackgroundRead=1′);

We wait for a while, then we check how much data is waiting for us in the buffer and read it out into a vector:

    WaitSecs(3);
    bytestoget = IOPort(‘BytesAvailable’,h)
    [longdata,when,e] = IOPort(‘Read’,h,1,bytestoget);

Finally, we stop recording, purge the buffer and close the port:

    IOPort(‘ConfigureSerialPort’,h,’StopBackgroundRead’);
    IOPort(‘Purge’,h);
    IOPort(‘Close’,h);

I had some trouble initially streaming data from the device. If you forget to purge the buffer it can cause your entire system (not just Matlab) to hang and restart. This is very annoying, and slows development progress.

Now that we have some data, we need to process it. The vector is a stream of bytes in packets of 17. We can separate it out like this:

    for n = 1:17
        parseddata(n,:) = longdata(n:17:end);
    end

And plot each signal separately:

Outputs from the Olimex serial interface

Outputs from the Olimex serial interface

According to the device’s firmware, the first two plots are control lines that always output values of 165 and 90. This provides an anchor that lets us know the order of the signals. The next plot tells us the firmware version (version 2), and the fourth plot is a sample counter that increases by 1 each time the device samples the electrodes. The sampling happens at a fixed frequency of 256Hz, so 256 samples represent one second of activity. Plots 5-16 are the outputs of the electrodes (this is what we’re interested in), and I don’t really understand plot 17 yet.

Each channel gets 2 bytes (e.g. 16 bits), but only uses 10 of those bits. This means that to get the actual output, we need to combine the data from two adjacent bytes (paired by colour in the above plots). The data are in big-endian format, which means that the first byte contains the most significant bits, and the second byte the least significant. We can combine them by converting each byte to binary notation, sticking them together, and then converting back:

   for l = 1:6
    for m = 1:length(parseddata)
      trace(l,m)  = bin2dec(strcat(dec2bin(parseddata(lineID(l,1),m)),dec2bin(parseddata(lineID(l,2),m))))./1023;
    end
    end

We now have six ten bit signals, which we can plot as follows:

Channel outputs

Channel outputs

Although the waveforms look exciting, they aren’t very informative because most of what we’re seeing is an artefact from the ‘hum’ of AC mains electricity. We can see this if we examine the Fourier spectrum of one of our waveforms:

Example EEG fourier spectrum

Example EEG fourier spectrum

It is clear that much of the energy is concentrated at 0, and at 50Hz. We can remove these using a bandpass filter, that includes only frequencies between (approximately) 1 and 49Hz. Taking the inverse Fourier transform then gives us a more sensible waveform:

Bandpass filtered waveform

Bandpass filtered waveform

Actually though, I’m more interested in what is happening in the frequency domain. This is because I want to run experiments to measure the response of visual cortex to gratings flickering at a particular frequency. However, there are some problems to overcome first. Critically, I don’t understand how the four active electrodes on the device map onto the six channel outputs that I read over the serial connection. They all seem to produce a signal, and my initial thought was that the first four must be the outputs of individual electrodes, and the final two the differences between positive and negative electrodes for channels 1 & 2. As far as I can tell, that isn’t what’s actually happening though. I have posted on the OpenEEG mailing list, so hopefully someone with experience of using these devices will get back to me.

If anyone is interested, I have put a version of the code outlined above here (with a few extra bells and whistles). Note that it may require some modifications on your system, particularly the serial address of the device. You will also need to have Matlab (or maybe Octave), Psychtoolbox and the driver software installed. Finally, your system may hang if there are problems, and I hereby absolve myself of responsibility for any damage, loss, electrocution etc. that results in you using my code. However, I’d be very interested to hear from anyone else using one of these devices!


New job, first month

27/01/2013

So, at the beginning of the month I started working at York. It’s been a busy few weeks, meeting lots of people and finding out how things work. The department is great, people have been very friendly and welcoming. So far I’ve mostly been walking in to work, and the winter mornings have been (occasionally) lovely:

Mist on the Ouse

Mist on the Ouse

My new computers showed up this week and are nearly set up the way I want them. I managed to install Grace under OSX Mountain Lion, which was rather easier than I was expecting. The lab setup is coming together. I’ve now got two very sturdy Headspot chin rests all the way from Houston and a couple of height adjustable tables are on their way.

Also, excitingly, I ordered a small EEG device (EEG-SMT) from a Bulgarian company called Olimex. It’s a very basic open source design, but should hopefully be good enough for measuring VEPs with. It arrived on Friday, and I’ve managed to stream data from it into Matlab using the USB port (and the Psychtoolbox IOPort command). Working out how to interpret that data might take a little work, and I’ll likely produce a blog post once I’ve cracked it. I think the device has lots of potential if it produces clean enough data, and is easily affordable (at well under £200) for anyone interested.

At the start of this month I went to the EPS meeting in London. It was the first one I’ve been to and I really enjoyed it. There was much more vision on the program than I was expecting, and I met some really interesting people. I’ll definitely start going to more of the meetings and maybe also join the society.


Last day at Aston

13/12/2012

So, today is my last day on campus at Aston. I’m amazed at how quickly the last three and a half years have passed, it feels like no time at all since I was starting back here after postdoccing in Southampton. Still, it’s been a productive time, and on balance I’m glad I chose to come back here rather than do something else.

This morning I made a Wordle from the text of all the papers I’ve published. I might put it on my new website:

paperswordle

The other day we went for some leaving drinks at the Bull, which went like this:

Lots of people at the Bull to celebrate me leaving.

Lots of people at the Bull to celebrate me leaving.

At the moment our house is full of boxes. Laura is off work today to do some last minute packing (mostly of her craft materials) and hopefully sell her car. Then tomorrow some burly men will arrive and load everything into a lorry and take it to York. I’ll be there already (hopefully) with the cats to tell them where to put everything.

Next week I’m giving a talk at the AVA Christmas meeting in London, and then I’m back in London again just after New Year for the EPS meeting. It’s the first one I’ve been to, and I’m looking forward to going to a more general psychology conference. I’ll need to make my talk less geeky though!

Lastly, John Cass and I submitted our first collaborative paper together yesterday. We sent it to a journal that will probably reject it without even bothering to review, but hey, it doesn’t hurt to aim high!


Clearing the decks

10/11/2012

In the last few weeks running up to Christmas there’s lots to get done. At the moment I’m trying to tie up lots of projects, and get data collected on a few experiments. One of those is a collaboration with John Cass, who came to visit the lab in September. We’re looking at consciousness during binocular rivalry, and it looks like it’s going to be an interesting study. I’ve got a few more subjects to run, and then we can start analysing and writing it up.  Here’s John savouring some beer:

John drinking beer

Our lab moved from Aston’s monolithic main building into the Vision Sciences building a few weeks ago. The new space is really great, with a big open area to have meetings and conversations in. We’ve had a few teething problems with the heating and lighting, but we’re getting things sorted now.  Here’s the open area on move-in day – it’s a bit tidier now!

A wide angle shot of the new lab space on move-in day.

We’ve also finally sorted out a place to live in York. It’s big, near the station, and they’re happy with our cats living there, so it fits all our criteria. The move should happen in about five weeks time, which means we’ll be moved in ready for Christmas. I’m really looking forward to starting the new job in January, I even have a temporary new website up in my new department.

In tying up lots of projects, we’ve had a few new papers published, some of which have been in the pipeline for quite a while. There are a couple in the final stages of review, and here are some that are already out:

This is the first thing we’ve published from Alex Baldwin‘s PhD. Alex measured sensitivity to small grating patches across the visual field, in much greater detail than people had attempted before. It turns out that sensitivity falls off as a bilinear function of eccentricity, which has important ramifications for models of spatial vision.

Another study by Wallis et al looked at the slope of the psychometric function for a range of different stimuli. We wanted to see if slopes varied with spatial frequency or pattern size (they don’t), and also to work out the most accurate method for estimating slopes over many sessions.

Finally, in a collaborative paper with Pi-Chun Huang and Robert Hess, we looked at the temporal properties of interocular suppression, in both normal and amblyopic subjects. We explain all of our findings with a simple model that assumes that signals are blurred and delayed slightly in time before they have a masking effect on the opposite eye. Surprisingly, the amblyopes don’t show greater suppression than the normal observers, once you take into account the difference in sensitivity between their eyes.


Drooling over cameras

10/11/2012

A few weeks ago, I finally gave in to temptation and bought myself a new camera. It’s a Fuji X100, and it is unique in that it contains a large APS-C sensor usually found in DSLR cameras, but in a small body that you can fit in a bag or (coat) pocket. To me this makes all the difference, as it means I can have a good camera with me all the time (I have a DSLR too, but it’s just too big and heavy to take everywhere with me). Often opportunities for great photographs happen when you least expect, and you miss them if you don’t have a camera with you. Here’s a sample image I took the other day in our local cemetery:

Graveyard teddy keeps dead people company

The advantage of a large sensor is that the signal to noise ratio at each photosite is higher. In practical terms, you can take photos in lower ambient light without using the flash, and without ending up with blurry or grainy images. This is ideal for social situations like parties, pub or restaurant outings, which is where I find myself taking lots of photos. The camera’s lens also has a large aperture, which lets in lots of light, also improving indoor and nighttime photos. Here’s an indoor nighttime shot of me playing a song at our local open mic night recently:

Me playing a song at the Glebe open mic night. Lots of people were watching, they’re just behind the camera…

So far I’ve been loving the camera, particularly the black and white setting, which allows you to see how a photo will look in greyscale immediately. There’s also some very clever image processing going on to deal with complex lighting situations, but it’s all seamless and invisible, and always seems to get things right first time.

Some huge tentacles trying to eat (or perhaps sell) a rather ugly bag.

So, for anyone thinking about buying a new camera, the Fuji X100 comes highly recommended.


All about noise masking

02/10/2012
So, a few years ago I got interested in noise masking. It’s a widely used paradigm, where you measure detection thresholds for targets buried in various amounts of external noise (kind of like the ‘snow’ on an untuned TV set).

Some 2D white noise, increasing in contrast from left to right. Stronger noise (right) will impede detection of a target.

The technique is useful because it allows sensitivity deficits, sometimes due to clinical conditions like amblyopia, to be characterised better. For example, it might show that internal noise is greater in some condition, and this in turn could inform new models, treatments or therapies.
For a long time people have sort of half realised that there are some funny things about noise masking. The data don’t always come out the way the dominant model of noise masking says they should, and different labs sometimes come up with quite different results. This has been noted in passing in several papers, but there was clearly a need for someone to really nail the problem, and get to the bottom of things.
After a few years of pilot experiments (this has never been my main focus, always an exciting side project), Tim and I came up with a series of experiments that we thought would shed some light on what’s going on in noise masking. Our hypothesis was that the white noise masks that people typically use might actually cause most of their masking through a process of suppression (and not by injecting noise into the decision variable like they’re supposed to). We came up with four tests for this, each of which appeared to support our conjecture.
What really convinced us though was when we developed a new type of noise, that was much ‘purer’, and didn’t produce any suppressive masking on our four tests. It’s actually a very simple idea that appears in the literature way back about 40 years ago, but in experiments on detecting luminance instead of contrast. All you do is take your target stimulus and add or subtract a little bit of its contrast, randomly, in both intervals of a 2IFC experiment. Here’s an example trial sequence:

Demo of 0D noise: Each column represents a trial, with the upper row showing the stimulus presented in the first interval, and the lower row the stimulus in the second interval. Each stimulus is a log-Gabor, with its contrast drawn from a zero-mean Gaussian distribution. When the contrast is positive, the stimulus has a bright bar in the centre. When it is negative it has a dark bar in the centre. The top row has also had a positive target contrast added (in this example, always 30%). An observer in the experiment selects the interval with the highest positive contrast, as this is the one most likely to contain the target. In the first column, this is Interval 1, as it has high positive contrast, whereas Interval 2 has high negative contrast. So, the observer’s choice is correct. However, in trial 2, the displayed contrast in Interval 1 is actually negative (despite the target contrast being added to it) whereas in Interval 2 it is positive. In this situation, the observer will pick the ‘wrong’ (e.g. non-target) interval, even though they are behaving sensibly. But, on average over many trials, they will tend to choose the target interval when the target contrast is high enough to overcome the variance of the ‘noise’.

From the perspective of a mechanism tuned for detecting the target, this ‘contrast jitter’ behaves in exactly the same way as the more widely used ‘snow’ type white noise. Crucially though, it doesn’t activate any other nearby mechanisms that might cause suppression. Because it has no spatial or temporal dimensions, we call this new stimulus zero-dimensional (0D) noise.
I think the 0D noise technique is a much cleaner way of doing noise masking experiments. What we’re saying is quite controversial though, so whether anyone else agrees remains to be seen! But at least the paper is out there now. It’s probably my favourite project, despite (or because of) the level of nerdiness involved in parts of it. It’s open access, and you can read the paper here:
Zero-dimensional noise

Big ‘ooohs’ and big news

13/09/2012
Last week I was in Sardinia for this year’s ECVP conference. Despite some bad weather, organisational problems, and the first venue I’ve been to without free wifi, it was a great week with some fantastic talks and posters. There was lots of nice food and company too, and we saw some amazing caves:
My talk was on the Tuesday, and was the first outing for a new size adaptation effect we discovered in the Aston lab. The room was stacked to the rafters, and I was very surprised at the response I got from the first demo video – everyone went “oooh” at the same time! There should be a write-up of the illusion coming soon in the Friday Illusion blog at New Scientist. [EDIT: Now live, here].
Also whilst in Sardinia, I had a job interview over Skype. A bit unconventional, but it seemed to work OK. Anyway, they must have liked me because they offered me the job! So, from this January I will be a lecturer in the Dept of Psychology at the University of York. I went for a visit this week, and it’s a lovely campus with a great department. Lots of interesting things going on to get involved with.

Follow

Get every new post delivered to your Inbox.