2
votes

I'm new to the world of Python and my programming skills are fairly poor but I'm trying to figure a way to use Python to display the output from an EEG circuit (using the OpenEEG circuit http://openeeg.sourceforge.net)

The analogue output is amplified and processed via an ADC (in an ATmega8 microcontroller) and is converted to RS232 by a MAX232.

The RS232 Signal is as follows:

Byte 1: sync value 0xa5
Byte 2: sync value 0x5a
Byte 3: version
Byte 4: Frame number
Byte 5: Channel 1 Low Byte
Byte 6: Channel 1 High Byte
Byte 7: Channel 2 Low Byte
Byte 8: Channel 2 High Byte
...
Bytes 9-16 are for extra electrode channels but data not required since only using the first two
...
Byte 17: Button states (b1-b4)

I've got some basic PySerial functionality but I need to figure a way to make use of the incoming data by buffering it and plotting the useful values as 2 real-time x-y waveforms (time vs voltage)

Question update:

I'm getting the code to print with the obvious few lines of PySerial but it's gibberish. I'm trying to strip the data down in to the format of values that can then be plotted. The 17 bytes of data is currently coming in at 256 frames/sec. The (two) channels are made up 10 bits of data each (with 6 zeros to make up the rest of the 2 bytes). They are unsigned giving possible values of 0 to 1023. These correspond to values that should be plotted as positive and negative, so a binary value of 512 corresponds to a plot of zero (micro)volts....

How do I read the incoming stream as 8 bit binary (stripping out the data that I don't need), then combine the two relevant bytes from each channel that I want (possibly removing the surplus 6 zeros if necessary)?

2
Which bytes represent the voltage? How important is the "real-time" requirement? AFAIK, matplotlib does not support real-time plotting...unutbu
Yes it does, to some extend. But for real-time plotting something like Chaco is probably the better solution.nikow
the voltage for each channel is represented by the low byte and the 2 LSBs of the high byte (the rest of the high byte is zeros) A delay would be fine (e.g. a second) as long as it will display a few seconds worth on the screen, then maybe redraw a new plot. If I can only display data after it has all been recieved, then I may need to rethink.S_Swede
What exactly is your problem at the moment? This sounds like a pretty generic task that can be easily solved after a little reading in the matplotlib and numpy/scipy tutorials?nikow
nikow, I'm getting the code to print with the obvious few lines of PySerial but it's rubbish chars. I'm trying to strip the data down in to the format of values that can then be plotted. The 17 bytes of data is currently coming in at 256 frames/sec. The (two) channels are made up 10 bits of data each (with 6 zeros to make up the rest of the 2 bytes). They are unsigned giving possible values of 0 to 1023. These correspond to values that should be plotted as positive and negative, so a binary value of 512 corresponds to a plot of zero (micro)volts....S_Swede

2 Answers

2
votes

To handle the complicated binary data format you could maybe use structured arrays in numpy (see also here for a nice introduction). After defining the structure of the data it should be very easy to read it in. Then you could use numpy's functionality to cook down the data to what you need.

2
votes

There's a good realtime plotting example here. It's a good example in that it runs with self generated data, so it's easy to test, but it's also obvious where to modify the code for plotting real data, and the code is easy to follow.

The basic idea is to make a plot window and then update that data as it comes in using

set_xdata(np.arange(len(self.data)))
set_ydata(np.array(self.data))

(Though in the current versions of matplotlib you may want to use set_data(xdata, ydata) instead.)

As for parsing the serial port data, it's probably better to ask that as a separate question.