ADS1299 electrode impedance measurement algorithm

wjcroftwjcroft Mount Shasta, CA
edited July 2023 in Cyton
[Editorial note added in 2015: the forum posts labeled below as "K" and "deborahgalloway" are actually the same engineer, and NOT the person Deborah Galloway. This engineer asked us to delete his forum account, so the forum software somewhat arbitrarily reassigned it to Deborah. The label "K" can be associated whimsically as the character in the Men in Black movies who forgets his own identity.]

On higher end commercial EEG amps, you can get built-in electrode impedance measurements for each sensor. This is helpful, especially when you have a lots of sensors on a cap. Because it's likely that on your first pass you may not apply enough gel or paste to get the best possible connection. (Loosely defined as impedance somewhere in the range of 5 to 20K ohms, the lower the better.)

The ADS1299 supports this with what is called "lead-off detection". a guy in Serbia has actually developed code to do this, which is explained in his post on the TI Forum. Below is a quote from that thread. He is willing to help us out in recreating this. I am in touch with him via email and gave him links to the OpenBCI site and Kickstarter. His original code was for a commercial customer, so cannot be posted.

Most likely this would be implemented not continuously, but for a brief period of time during cap setup. Continuous monitoring can be supported, but then the final app consuming the EEG data stream must filter out the injected signal after the impedance has been calculated.

----


Hi Graham,

I've succeeded to online measure electrode impedance by using ADS1299 internal current source. You can measure differential impedance by turning on current sources on both inputs of one or more channels, or you can separately measure impedance of electrode on positive input, or on negative input. You must use AC current source, with amplitude of 6nA (because it is small enough and it will not disturb EEG signal) with frequency of Fdr/4. For example is sampling rate is 500Hz, then current source frequency will be 125Hz. When you collect EEG data, you must convert AD data to voltage, and do FFT. In amplitude spectrum of the FFT you will see one component of frequency of 125Hz. When you divide amplitude of that component with amplitude of the current source, it will give you electrode impedance. To try this, you can attach resistors on ADS1299's inputs. I've tried it with fixed resistors of 1Kohm, 10Kohm and 33Kohm. The results is 1.1Kohm, 11Kohm and 30kOhm respectively. The difference of the real impedance and measured impedance is because of the error of the current source amplitude. If you calculate back amplitude of the current source with measured impedance and amplitude in spectrum on frequency of 125Hz, the result will be about 7.5nA. It is small error, and for EEG measurements this error is negligible.

If you need any help with this, please contact me, and I will help you.

Best regards,
K

Comments

  • biomurphbiomurph Brooklyn, NY
    This method of using the internal excitation signal is the direction that we want to go with our OpenBCI system. I did notice there is a DC method, that reports via the status register (first 24 bit word in data stream). The DC method requires external components, and does not appear to reveal the impedance, just ON or OFF.
    Wondering if you have looked into the DC method? If so, why did you decide to go for the AC method?
  • wjcroftwjcroft Mount Shasta, CA
    Joel, hi. In the Brainmaster Discovery 19 channel amp I use, it offers continuous readouts of the impedance values on each sensor. Not just 'on' or 'off'. So you can tell if a particular 10-20 location is in range or out of range. For example, it might start off in range, but then drift out of range during the session if the cap shifts too much. So for commercial grade applications, having the actual impedance measurements seems to be commonly supported.

    In the BCI2000 video I just posted on the other thread, they just check the impedances at the START of the session, by putting the amp into a special mode. I think they were using a Guger amp in that.

    I'm hoping that K will setup a login here and jump in.
  • biomurphbiomurph Brooklyn, NY
    No doubt that having continuous measurements of impedance is much better for our purposes and it greatly improves the attractiveness of OpenBCI. The implementation, based on TI forum thread http://e2e.ti.com/support/data_converters/precision_data_converters/f/73/t/238755.aspx
    appears to be pretty straightforward, and it does look like the impedance can be measured in absolute terms (with some acceptable error) which is what we call around here 'Awesome!'
  • Hi guys,

    I will write you now a little letter about impedance measurement of the electrode-skin interface in EEG measurements.
    First I would like to say biomurph something about impedance measurement. You cannot measure impedance by using DC current source. Impedance is a complex term which consists of two parts, real and imaginary. Like a series or parallel connection of the resistor and capacitor. Electrode-skin impedance can be modeled like parallel connection of the resistor and the capacitor. If you use DC current source, than you cannot impedance of that parallel connection. DC current source can be used only to say if the electrode is connected or not. That method is more used in ECG measurements, where the amplitude of the signal is 100x greahter than EEG signal amplitude.
    ADS1299 posses AC signal sources with three different frequencies of the signal (7.8Hz, 31.2Hz and Fs/4). First two frequencies (7.8Hz and 31.2Hz) cannot be used for online impedance measurements, because this two frequencies are in range of the EEG signal spectrum. So I more prefer using the current source on the frequency of the Fs/4. I'm using sampling frequency of the 500Hz, so the current source frequency will be 125Hz.
    If you short connect all INM inputs of the ADS1299, then we can measure impedance in two ways. First if we want to measure impedance of the all electrodes on INP inputs without measuring the impedance of the reference electrode on INM input. This impedance can be measured by calculating FFT of the every signal and extracting component at 125Hz. This component we can divide with the current of the current source, and we get impedance.
    Second way is to measure sum impedance of the reference electrode and electrode on the INP input.
    I've implemented this two methods and it works great.
    I will send to you an equation which you can use for extraction component at 125Hz from FFT spectrum, and impedance calculation.
  • Back with our OpenBCI V1 board, I looked into doing the AC impedance checking. As K said, the only really usable frequency is the option for Fs/4. Unfortunately, we tend to run the sample rate as low as possible (250Hz) to keep the aggregate data rate down to ease the plotting effort by Processing. Running at that sample rate, Fs/4 becomes 62.5 Hz, which is too close to our power line interference (60Hz) to be helpful.

    At the time, I was not prepared to increase the sample rate, so I stopped pursuing the idea of continuous impedance monitoring. Since we're now smarter with the system and how it responds, maybe now is the time to start re-considering this choice. If my only reason was fear of too much data, maybe that was a bad decision. Maybe increasing the data rate would work out just fine. Hmmm...

    Chip
  • Chip,

    when using sample rate of the 250Hz, you cannot implement good impedance measurement. This sample rate is too low for EEG. What about person who have epileptic disease? EEG of the epileptic person is above 60Hz (70-90Hz). If you sample with 250Hz, you will not be able to see this spikes in EEG signal.
    I'm using 500Hz sampling rate for 24 EEG channels (three ADS1299 IC's) which is 2mS. On every 2mS I sample all 24 channels and transfer that data to the PC over bluetooth (83 bytes) in real-time. The data is plotted and processed in real-time on PC + 24 FFT calculations for the impedance measurement.
    In OpenBCI system you use only 8 channels, you can easily increase sampling rate to the 1024Hz. That must work properly without any interruption. That is my expirience.

    K
  • How fast are you running your bluetooth link? On some BT modules, a robust consistent connection only seems to be reliable up to 56 kbps, which is quite constraining.

    In my situation, at 250 samples per second at 24-bits per sample times 8 channnels, I'm at 48 kbps of raw data. Given the overhead of the serial link, that is about as fast as a "56kpbs" link will go.

    If you're doing 500Hz with 24 channels, you're pumping at least 500 Hz x 24bits x 24channels = 288 kpbs, which is quite a lot of data.

    You're really doing that over Bluetooth? Which module are you using? How do you have it configured? Have you tried this in multiple locations, or just at one location in your home/lab?

    I'm very curious!

    Chip
  • Hi Chip,

    I'm using Bluegiga WT12 Bluetooth module. Baudrate between MCU and Bluetooth module is 921600b/s. I'm using SPP prifile, so max baudrate in the air can 500kb/s. For this application you must use handshaking and ring buffer.

    K
  • If you're concerned with measuring only a single frequency for the impedance measurement (e.g. 125 Hz), a single dot product can be used.

    V = \sum_{n=0}^{N-1}(x(n)*e^(-j*2*pi*f_r*n/F_s))

    If the frequency of interest is Fs/4, then the complex exponential in the above equation reduces to the repeating sequence { 1, -j, -1, +j}. That turns the multiply operation into a sign changing and data steering operation. This might not be all that useful with processors with hardware floating point multiply capability, but it can save a significant number of ops vs. an FFT.

    -- Mike
  • edited June 2019
    Cross posting from my other thread, that is exactly what I did and it runs onboard the STM32 without issue.<div style=""><br></div><div style=""><a href=" style=""><br></div><div style="">implementation is here:</div><div style=""><br></div><div style="">https://github.com/peabody124/TauLabs/blob/eeg/flight/Modules/EEG/eeg.c#L136 </div><div style=""><br></div><div style="">Hopefully no embarrassing mistakes. The sqrt(2) is a fudge factor till I look up the fourier series of a square wave.</div>
  • wjcroftwjcroft Mount Shasta, CA
    James, K and Mike (DphiDt), this is fantastic! Thanks to you all for implementing this feature which is usually only found on amps costing thousands of dollars. With the anticipated usage by our university and corporate backers, it really positions OpenBCI as comparable to research-class systems.
  • Hi all,

    first I would like to say to James that he done a great job, bu implementing impedance measurement. James, according to your schematic, you have internal serial resistors of 10Kohm on every input. The big problem is that real electrode-skin impedance at EEG measurements is not pure resistor. It also have a capacitor in parallel with resistance. In your case, you can simply subtract input resistance from the total calculated impedance and that will be the electrode impedance (modeled as a pure resistor)!!! In real EEG measurements we have a complex impedance (real + imag part). If you want to have a precise impedance measurement you must know starting phase angle of the current source. The problem is because we dont know phase angle of the current, so when I implemented impedance measurement I was assumed that impedance is modeled as a capacitor, so my formula for impedance measurement is:

    Zelectrode = sqrt((V125/I)^2 - R^2);

    where V125 is the amplitude of the voltage across electrode impedance + input resistance at 125Hz, I is the 6nA current source, and R is input resistance, which is in your case 10K, according to your schematic.
    Can you please try to implement this, instead of:
    float impedance = amp * 1000.0f / 6.0f; // your peace of code


    All comments are welcome.
  • I forgot to say in previous post, EEG input stage can be designed with LC components instead of RC components. Inductors have near zero impedance at 125Hz, so code that James presented to us will give the great results.

    K
  • Peabody,

    I checked out your code on github. Thanks for sharing.

    There were a few things that I couldn't find...for instance, where are the header files that you #include? Specifically, I'm interested in looking at the one that does the EEG setup. Do you have it shared?

    Thanks,

    Chip
  • I've finally gotten around to working on the impedance measuring on my V1 and V2 OpenBCI boards. It's working pretty nicely and I'll have a blog post in a couple of days describing what I've found.

    One question that I have is regarding the AC current source built into the ADS1299. I'm using the 6nA setting at ~31Hz frequency. What is the actual current waveform? Sine wave? Square wave? This affects how one scales the calculation of impedance.

    For example, with my hardware using known resistors, I seem to get the best answer if I do my calculation as:

    Impedance = Vrms * sqrt(2) / 6 nA

    where Vrms is after filtering the signal (10 Hz pass band) around the expected ~31 Hz frequency. If this equation really is correct (especially the sqrt(2) scale factor), it implies that the waveform of the injected current has an amplitude (not RMS) of 6 nA. Or, said another way, that the injected current waveform is a sine wave with a peak-to-peak amplitude of 12 nA.

    Is this correct?

    Chip
  • I think that I worked through most of my issues with getting the impedance measuring to work for the ADS1299 (and, therefore, for OpenBCI). Now, I can successfully measure the impedance of each channel, as confirmed by testing an OpenBCI board with the "+" electrodes shorted to the "-" electrodes (and to "bias"). With this setup, I correctly see ~5K of resistance, which corresponds to the 5K series resistor that is on each channel. Success!

    If you're interested in a little more detail about how (I think) EEG impedance measuring works, you can check out by post:

    http://eeghacker.blogspot.com/2014/04/openbci-measuring-electrode-impedance.html

    Chip
  • Chip,

    its great to hear that you have measured impedance. Measuring frequency of 31Hz is not good because it is in range of the EEG signal spectrum. You must increase this frequency to Fs/4. In real EEG measurements you will have a error when measuring impedance because of the EEG signal at this frequency. Also, real EEG impedance is not pure resistive. It also have a capacitive component. Try to measure parallel connection of the known resistor and capacitor. Also try to measure series connection of the resistor and capacitor. You will see that this is not trivial task. You cannot simply subtract input resistor value.
  • Hello K,

    I concur with your statements regarding the complications of the simplistic method that I've used...but I'd like to reply with the following views:

    1) The purpose of the impedance measuring is to try to get it "low enough", so absolute accuracy is not as important as "is it low or is it high". Therefore, any real EEG signals near 31 Hz are only a problem if they are large. In this context "large" would mean EEG signals of a magnitude of (10 kOhm * 6 nA) = 60 uV, which is highly unlikely.

    2) Your suggestion to move to Fs/4 is excellent if I want to monitor impedance continuously while doing my EEG recordings. While this is an excellent way of operating (and I know that you've achieved it), it is not my goal. For me, running at 250 Hz, fs/4 would be too close to my 60 Hz line noise. I know that it is possible to run faster, but we discussed that earlier.

    3) I concur that the capacitive component of the skin impedance greatly complicates things and that my "subtract 5K" is inappropriate in a number of cases. As a first step, it is better than nothing. I need to build experience before making refinements. I bet others are in a similar place...they need to get started, see the deficiencies, and then make improvements. The purpose of my post was to get myself and others started on the first step.

    I saw all your posts over on TI's community forum, too. You're really helping everyone understand how this is done!

    Chip
  • And as a follow-up to my earlier post, I've measured the electrode-to-skin impedance for real electrodes on my real skin using my OpenBCI system. I tried disposable ECG electrodes and I tried gold cup EEG electrodes. If you're interested in seeing come results, you check out:

    http://eeghacker.blogspot.com/2014/04/impedance-of-electrodes-on-my-head.html

    Chip
  • wjcroftwjcroft Mount Shasta, CA
    I am very grateful for all the engineering work that K, Chip, James, Mike and others have put into the impedance calculation capability for the ADS1299 and our OpenBCI hardware. This is a type of feature that is generally only found on high end EEG equipment, so I see it as a significant plus for OpenBCI acceptance.

    I've mentioned before that several prominent experts in the field of EEG neurofeedback have argued that skin impedances even in the range of 100K+ ohms are acceptable. This is because the input impedance of amps these days is so high, in the hundreds of megohms or even gigaohm. So considering the effect of that difference between 10K and 100K in how the EEG microvolt signal is effected -- the actual microvolt difference is miniscule. Yes you can see large differences in microvolts with the constant current injected signal used by the ADS1299 lead off circuit topology. But real EEG measured from the scalp is not operating in this constant current paradigm.

    Here is a page from the book, Clinical Neurotherapy, the chapter by Dr. Richard Soutar. A very clear explanation of what is often a contentious issue. And it cites Robert Thatcher's painstaking numerical calculation as well, as further evidence.

    http://www.lightfield.com/jpg/thatcher-impedance.png

    As some more data points, I have done some DC impedance measurements of my Ag-AgCl saline sensor system, and also get impedances in the 100K range. This is completely normal for a saline system which uses no skin abrasion. Skin abrasion in fact these days is being called into question, since you want to avoid any possibility of breaking through the skin barrier. A number of other EEG headsets are using simple saline pads, such as the Emotiv EPOC, so impedances in this range are quite normal and functional.

    I do see the value of the ability to check our impedances so we can see when they have gotten significantly out of range. Or when the ADS1299 is being used in say a medical / clinical setting where they might have strict rules about acceptable ranges for their applications or research.

    Thanks again to Chip and everyone who is making this measurement possible, and adding to our knowledge of ADS1299 EEG practice.
  • wjcroftwjcroft Mount Shasta, CA
    edited June 2019
    Another well known clinical Ag-Ag/Cl saline system is that from EGI http://www.egi.com/ , their Geodesic Sensor Nets. Here's a paper where they discuss their comparison of 5K vs 40K impedance differences in the EEG signal. No significant differences were found.<br><br>http://wwe.eeginfo.com/research/ElectrodeImpedance.pdf<br><br>For those wanting to experiment with the 5K / 10K impedance standards, here is a common prep gel used,<br><br>http://www.amazon.com/D-O-Weaver-NuPrep-Skin-Prep/dp/B002C2UQIA
  • wjcroftwjcroft Mount Shasta, CA
    edited September 2014
    Here's a post-historic note on the comments in this thread.  :-)  The
    commenter labeled "deboragalloway", is not really that person.  This was
    a side effect of importing the forum from the old bbPress software into
    Vanilla forums.  The account / person who generated the
    "deboragalloway" posts, deleted their own forum account on the bbPress
    site when their management complained that they may be divulging too
    much information.  And thus the internal database "account number" got
    reused by the later user "deboragalloway".  No relation to the posts in
    this thread AT ALL.

    Some of the posts above have also been edited
    to remove that person's original name.  That name was replaced with the
    string "K", the amnesiac character in the Men in Black movie series. 
    :-)  We want to thank K for all his contributions and suggestions.  A
    really brilliant engineering professor.

    ----

    A more user-friendly tutorial on how to implement the impedance measurement algorithm, is on Chip's blog, at these posts,

    http://eeghacker.blogspot.com/2014/04/openbci-measuring-electrode-impedance.html
    http://eeghacker.blogspot.com/2014/04/impedance-of-electrodes-on-my-head.html

    ----

    This September 21 addendum to this thread was prompted by another thread discussing the possibility of GSR measurements with the ADS1299.  I referred back to this thread for a historic context.

    http://openbci.com/forum/index.php?p=/discussion/156/gsr-openbci

  • Hi.
    I have 2 questions regarding this topic, one using the GUI and other about code on board for that.

    1)
    I'm trying to replicate what @chipaudette did here: http://eeghacker.blogspot.pt/2014/04/openbci-measuring-electrode-impedance.html (thanks for the great explanation!)
    I think it's working quite well (the calculations are fine for I=6nA), however, the impedance is significantly below 5K.
    Does anyone have an idea of what's happening here?

    2)
    This is maybe a dumb question but I couldn't find the answer, sorry.
    Instead of using the GUI, I wanted to code "turn on" the injection of current on board (for acquisition using OpenViBE, for example) but I can't find how to do it.
    I know I can confiure it with OBCI.configureLeadOffDetection(LOFF_MAG_6NA, LOFF_FREQ_31p2HZ); and I was expecting I could make it work using changeChannelLeadOffDetect_maintainRunningState().
    So, how do I tell it to inject the current for impedance measurement?

    Thank you for all the work you guys have been doing and thanks in advance for the reply
This discussion has been closed.