large millivolt data values / FbEEG Full Band EEG

edited August 2018 in Cyton
Dear all, 

Comparison of two picures demonstrated that Alpha wave had been detected. So, I thought that experimental setup was fine.

However, I got raw data as the attached picure (Third column). What's problem? They were minus values all time. (Sample values ranged from -27407 to -27504 microvolts. About a hundred microvolt range, but with a -27400 constant offset.) Any suggestion, please?





  • wjcroftwjcroft Mount Shasta, CA
    edited March 2016
    P300, hi.  There is no "problem" with the raw data.  It just reflects the DC offset (~ -27.4 millivolts) that is present on top of the microvolt variations in EEG.  This is actually a significant and advanced 'feature' of DC coupled EEG amplifiers, such as the ADS1299.  The offset can be removed if you want with a high pass filter at say .5 hz.

    The offsets can just as easily be positive as negative.  They slowly vary over time.  One term for this is Slow Cortical Potentials, researched by Birbaumer.  Cycle time for these slow potentials is on the order of .1 hz down to .001 hz.  In other words, DC offset shifts can occur over many tens of seconds, minutes.  Your high pass filter will remove all of this.
    Excellent Fall 2013 review issue of ISNR Neuroconnections, "What's happening below 0.5 Hz?"


    PS one other suggestion: as you can see from the graphs generated by Chip's Processing GUI -- that code already has the high pass filtering built in.  So you could modify the code such that the filtered values are written to the file, instead of the raw values as currently.  However it's likely you are going to be doing other signal processing operations at some point in the pipeline, so wherever you decide to place your filtering code is up to you.
  • edited November 2014
    Dear William,

    Thank you very much for good explaination.

    I will try to implement DC filter on matlab using this raw data. Thank you for good reference.

    P.S. Actually, I had learned to modify built-in filtered already. I would like to make sure that I can see P300 wave using OpenBCi, so that why I start with raw data at this moment. Next step will be something like your suggestion!

    Thank you !!!
  • William is correct...the DC offsets are normal.  Every ADS1299 system that I've worked with has exhibited this kind of substantial DC offset, but I've never tried to validate this part of the chip's behavior.

  • I am working on an open source, browser based, GUI for the OpenBCI. I tried to replicate the EKG experiment in the getting started section of the documentation without much success. The electrodes on my arm put out a signal centered around 30 mV and the electrodes on my head produced a signal centered around 20 mV. I expected the signal to oscillate around 0 V with amplitudes in the 10's of microvolts. When I performed the same set-up in the Processing GUI, I was able to see brainwave looking wave forms from the noggin electrodes and a clear electrocardiogram from the arm electrode. Am I missing a step? Is there some data normalization that happens in the Processing GUI? Should the wave have a mean amplitude of 0V?

    Thanks much,
  • Hi Kevin,

    As discussed in the posts preceding yours (ie, prior to William merging your post with this thread), the big DC offset is normal in the data.  The Processing GUI applies a bandpass filter to the data prior to plotting it.  This filter removes the DC offset in the data, which is why you don't see it in the GUI.

    If you're looking at the log file, the DC offset will still be present (because the log file holds the raw data as received directly from the OpenBCI filtering or anything).  If you're working with the data from the log file, you'll have to apply your own filtering to remove the DC component.

  • wjcroftwjcroft Mount Shasta, CA
    edited February 23
    The technical term for the type of EEG data that OpenBCI records is Full Band EEG. This type of recording is now becoming a more widely recognized and emerging standard. See paper below,


    Full-band EEG (FbEEG): an emerging standard in electroencephalography
    Sampsa Vanhatalo, Juha Voipio, Kai Kaila


    While enormous resources have been recently invested into the development of a variety of neuroimaging techniques, the bandwidth of the clinical EEG, originally set by trivial technical limitations, has remained practically unaltered for over 50 years. An increasing amount of evidence shows that salient EEG signals are observed beyond the bandwidth of the routine clinical EEG, which is typically around 0.5–50 Hz. Physiological and pathological EEG activity ranges at least from 0.01 Hz to several hundred Hz, as demonstrated in recordings of spontaneous activity in the immature human brain, as well as during epileptic seizures, or various kinds of cognitive tasks and states in the adult brain. In the present paper, we will review several arguments leading to the conclusion that elimination of the lower (infraslow) or higher (ultrafast) bands of the EEG frequency spectrum in routine EEG leads to situations where salient and physiologically meaningful features of brain activity are ignored. Recording the full, physiologically relevant range of frequencies is readily attained with commercially available direct-current (DC) coupled amplifiers, which have a wide dynamic range and a high sampling rate. Such amplifiers, combined with appropriate DC-stable electrode–skin interface, provide a genuine full-band EEG (FbEEG). FbEEG is mandatory for a faithful, non-distorted and non-attenuated recording, and it does not have trade-offs that would favor any frequency band at the expense of another. With the currently available electrode, amplifier and data acquisition technology, FbEEG is likely to become the standard approach for a wide range of applications in both basic science and in the clinic.

  • edited March 2015
    @wjcroft Thank you for that link, and for all of your very informative posts on this forum!   Full-band EEG is very exciting.  I'm able to get a great deal of mileage from the Neurosky TGAM modules with appropriate shielding and layout, but the built-in filters are a severe limitation.  I can't wait to move to a good ADS1299 based system.   Is anyone able to get clean recordings with OpenBCI using short, shielded leads and proper DRL in the .01-200Hz band with no notch filtering?   
  • wjcroftwjcroft Mount Shasta, CA
    @ecube , thanks.

    Among other protocols, I'm doing ILF, infra-low frequency neurofeedback in the range of .001 to .01 hz. This is using ideas from the Othmer method. The only caveat with ILF is that you need Ag-AgCl sensors for their low frequency stability. No special shielding needed. My current ILF design is running with BioEra on an older amp that I have, but I intend to adapt this to OpenBCI, which should perform better due to the 24 bit samples and wide dynamic range. Filtering out the mains noise is ok with ILF, since the primary activity is way low in frequency.

    Note that due to the Nyquist limit, the 250 hz sampling rate could at best only include 125 hz EEG. But even that is a stretch because there would only be two samples per cycle. Also, when you start getting above 40 or so hz, you need to be careful that your signal is not getting confused with EMG from muscle tension. But this can be done, as the FbEEG paper demonstrates.

    Joel @biomurph and @jarek (BioEra author) have mentioned augmenting the board command set to allow faster sampling, if the number of channels is reduced. To be honest though I think most neurofeedback people using FbEEG ideas are considering that to be in the .001 to 50 hz range. There are researchers working in cEEG (direct cortical EEG) in those higher bands above the mains.


    @kevinjos , hi.

    Hey that would be a cool platform: golang; I know Google is really big on that. And it comes from the hand of Ken Thompson and Rob Pike, both of them creators of Unix and Plan9. There are a number of DSP libraries for C, as google would turn up. A well respected lib that is used by BioEra and BrainBay is,

    re: mains or other DSP filtering; this is done entirely in your software. See OPENBCI_GUI source. You could either do a bandpass from say .5hz to 40hz. Or a notch at your mains freq.

  • jpivjpiv florida
    edited March 2016
    [Original post title: Data graphed in GUI doesn't match data logged?]

    When using the provided processing GUI, I see a wonderful nice picture.  However, when I try to graph the data saved on the text file using python, i see something completely different.  I think it's clear I'm interpreting the values incorrectly, but I dont understand what to do to fix that.  Help??

  • wjcroftwjcroft Mount Shasta, CA
    edited March 2016
    @jpiv, hi. I merged your post into this existing thread. Read the explanations above. The CSV file contains raw data, you need to apply your own hipass and notch filters, etc. There are Python DSP libraries that can do this,

    Also Chip's later EEGHacker posts used Python, source code on his Github,

  • wjcroftwjcroft Mount Shasta, CA
    edited February 23
    @jpiv, as you can see from the previous posts, others have had this same question. It would probably be helpful if we put a couple paragraphs explanation of the raw nature of the data format someplace on the Docs site, perhaps here,

    Another idea would be perhaps a mod to the GUI program itself to have a CSV: RAW vs FILTERED switch or button. In RAW the output would be as it currently is. In FILTERED, the CSV would reflect what filtering has been selected on the GUI configuration. However the downside of adding more complexity to the GUI, is that it is intended to be easy to use and fairly simple to operate.

    Most applications that consume the data from the OpenBCI are interested in the raw stream, since that gives you full control of the DSP you want. Saving data that has been DSP filtered once, and applying subsequent filters or DSP operations, would result in loss of information and reduced resolution.


  • As a small bit of help, an OpenBCI data file is just a text file, so you can open it in any text editor...notepad, Word, or whatever.  The top of the file describes the contents...

    %OpenBCI Raw EEG Data
    %Sample Rate = 250.0 Hz
    %First Column = SampleIndex
    %Other Columns = EEG data in microvolts followed by Accel Data (in G) interleaved with Aux Data
    0, 24959.99, 187500.00, 187500.00, 187500.00, -187500.02, -187500.02, 187500.00, 187500.00, 0.00, -0.08, 1.07
    1, 24958.38, 187500.00, 187500.00, 187500.00, -187500.02, -187500.02, 187500.00, 187500.00, 0.00, -0.08, 1.07
    2, 24947.74, 187500.00, 187500.00, 187500.00, -187500.02, -187500.02, 187500.00, 187500.00, 0.00, -0.08, 1.05
    3, 24941.77, 187500.00, 187500.00, 187500.00, -187500.02, -187500.02, 187500.00, 187500.00, 0.00, -0.08, 1.05
    4, 24945.89, 187500.00, 187500.00, 187500.00, -187500.02, -187500.02, 187500.00, 187500.00, 0.00, -0.08, 1.05

    I'm not saying that it's the most helpful header possible, but at least it's something.  First column is simply a counter.  The next 8 columns are raw EEG data (in microvolts) and the final columns are a mash-up of accelerometer data or other auxiliary data.

    To see how you might read this data into Python, you can look at one of my iPython notebooks.  This one doesn't do filtering, but it does do spectrograms and FFT, which is cool, too...

    That notebook is for the experiment that I did trying to get auditory steady state response (

  • wjcroftwjcroft Mount Shasta, CA
    @harithasreevihar, hi.

    I answered your question once above. Please don't post this same question on other thread topics that are unrelated to the subject matter. If you have a followup question or do not understand, just reply here in this thread.

    The text CSV file shows RAW microvolts values. The values shown on the GUI screen have had various FILTERS applied before plotting. If you want to take the RAW values and do your own signal processing, you must do your own filtering operations using whatever DSP (digital signal processing) library that is most appropriate. You can Google for some of these. Some of the filters the GUI screen uses are 'notch' (at mains frequency), 'hi pass' (at around .5 hz to remove DC offset), 'band pass' (to restrict to a specific range of frequencies).

  • Hi,
    How to use these kind of filters? Will that be available in python or nodejs?
  • wjcroftwjcroft Mount Shasta, CA

    One example of a Python library from MIT,

    DSP filters operate on STREAMS of EEG sample data. A bandpass filter admits a range of frequencies (for example .1 hz to 40 hz), and rejects all other frequencies. A notch filter removes just one frequency, for example a 50 hz mains noise. Etc.
  • wjcroftwjcroft Mount Shasta, CA
    Here's a free book on DSP, viewable on the web.

    This DSP library for C programmers is widely used. It's part of BioEra and BrainBay, for example.

    The manual on that library shows the kind of filter configurations typical of DSP packages.

  • pablopablo Guatemala
    Hi William!
    Regarding the posts about doing your own signal processing from the raw data i was wondering what kind of filters should be the best to get the most accurate results, and by that i mean to get the most precise/similar data compared to the values that the OpenBCI_GUI actually plots. Should they be FIR or IIR? Butterworth? How many poles should be good enough? Or is this to much trouble and is better and easier to use one of the DSP libraries you recommend in earlier posts? 

    Also, the uVrms value that is printed in the GUI for each channel is the peak rms at the present time or this value is calculated by some mean? 

    Once again thanks in advance for your help and time to answer this questions!
    Best regards, 
  • wjcroftwjcroft Mount Shasta, CA
    Pablo, hi.

    The FidLib filters default to IIR,

    But either FIR or IIR is fine, they have slightly different characteristics, 

    In terms of removing the DC offset, all you have to be concerned with is removing components below say .5 Hz. So that can be achieved for example with a Butterworth bandpass from .5 to 45 Hz, or a highpass at .5 Hz. Many people also use a notch filter at your mains frequency, 60 or 50 Hz. The order is not that critical, though it does effect the edges of the band; higher orders give greater sharpness. 4th order is probably fine for most applications. The DSP libraries that construct filters based on filter type, order, and passband -- are easier to use than specifying coefficients by hand.

  • Hi there,

    I am plotting the raw data out from the cyton board w/o adding any filter.

    Why the voltage will keep increasing over time? Is that due to the board? Thx

  • wjcroftwjcroft Mount Shasta, CA
    edited February 23

    @qijia, hi.

    I merged your new thread, into this existing thread on the same subject. Please see previous comments. Normally a bandpass or highpass is applied to the data from Cyton. This is what the OpenBCI_GUI is doing. Conventional EEG is typically between .5 Hz and 45 Hz. With a notch filter at your mains frequency.


Sign In or Register to comment.