How to measure impedance using Cyton serial command protocol

edited January 2020 in Cyton

We can measure the impedance of each electrode using OpenBCI_GUI.
I want to measure it from my software, using Cyton serial protocol.
According to the SDK, there is a command to turn on/off the Impedance Setting mode.
https://docs.openbci.com/docs/02Cyton/CytonSDK#leadoff-impedance-commands
If I set the electrode 1 to the Impedance Setting mode, then what should I do after that?

Comments

  • wjcroftwjcroft Mount Shasta, CA
    edited April 2021

    Hi Hiroki,

    See this section in the GUI Processing code:

    https://github.com/OpenBCI/OpenBCI_GUI/blob/master/OpenBCI_GUI/DataProcessing.pde#L52

    Regards, William

  • Let me confirm the calculation.
    I think I should send 'z 1 0 1 Z' to cyton since I use N pin to measure, is this right?
    After I receive the EEG data, I should multiply the data with -1, since the data is negative upper, is this right?
    When I turn the impedance check mode on using OpenBCI_GUI, the impedance is shown as around 640kOhm.
    But my program which measures impedances shows that it is around 2900.
    My program calculates impedances according to the above code, like: sqrt( 2.0 ) * (-v) * 1.0e-6 / 6.0e-9 - 2200 ( v is the EEG data streamed ).

    Something wrong with my program. Do you have any idea?

  • Hi William,
    You might add [resolved] to this thread title but is not resolved.
    Can you provide additional information?

  • retiututretiutut Louisiana, USA
    edited January 2020
    // Subtract the 2.2kOhm resistor
            impedance -= cyton.get_series_resistor(); // Subtract 2200
    

    If you say your program outputs around 2900 then it sounds like you forgot to subtract the resistor, though it is included in your equation here in the forum.

    Thanks for asking about checking Cyton Impedance outside of the GUI. Check your program to see if you are indeed subtracting 2200, and let us know the result.

  • wjcroftwjcroft Mount Shasta, CA
    edited January 2020

    @Hiroki said:
    ...
    When I turn the impedance check mode on using OpenBCI_GUI, the impedance is shown as around 640kOhm.
    But my program which measures impedances shows that it is around 2900.
    ...
    Something wrong with my program. Do you have any idea?

    Richard, so regardless of his subtraction value for the series resistor, 640K is way different than what he is getting. My hunch is that there is something odd going on with the "...1.0e-6 / 6.0e-9..." part of the expression. Looking at the code segment on Github,

    https://github.com/OpenBCI/OpenBCI_GUI/blob/master/OpenBCI_GUI/DataProcessing.pde

    (Lines 150+), the array variable, "dataProcessing.data_std_uV[Ichan]" is multiplied by 1 microvolt (1.0e-6). Yet why is the variable named uV? I guess it must be actually Volts and not microvolts? The result of (sqrt(2.0)*dataProcessing.data_std_uV[Ichan]*1.0e-6) is then divided by leadoff drive 'amps' (cyton.get_leadOffDrive_amps()). Six nanoamps, (6.0e-9).

    It's possible that there are some layers of DSP filters that precede this stage of calculation in the GUI. Such as to remove mains noise, and even zero in (via bandpass filter) on the particular frequency output by the impedance measurement generator in the chip. Which I think I recall is 31 Hz.

  • wjcroftwjcroft Mount Shasta, CA

    Looking again at Hiroki's expression, I don't think it has the correct parentheses grouping to control order of expression evaluation. The GUI sources does this:

    float impedance = (sqrt(2.0)*dataProcessing.data_std_uV[Ichan]*1.0e-6) / cyton.get_leadOffDrive_amps();
    
  • Hello,

    The source code of GUI:
    float impedance = (sqrt(2.0)*dataProcessing.data_std_uV[Ichan]*1.0e-6) / cyton.get_leadOffDrive_amps();
    // Subtract the 2.2kOhm resistor
    impedance -= cyton.get_series_resistor();

    My python source code is:
    impedances = [ sqrt( 2.0 ) * (-v) * 1.0e-6 / 6.0e-9 - 2200 for v in sample.channel_data ]

    I think the Python code is as same as the GUI's code.

  • wjcroftwjcroft Mount Shasta, CA

    Must be some code outside of this, that is affecting the computation. I mentioned bandpass filtering.

  • wjcroftwjcroft Mount Shasta, CA

    Remember, the only important amplitude being measured, is at 31.2 Hz. Any other EEG frequency components would contaminate that.

    Are you sure that data_std_uV[Ichan] is the same as sample.channel_data. This calculation should be looking at amplitude or power of the EEG, on that channel. Not raw sample values, which go above and below the Y axis. sample.channel_data looks like a raw sample to me.

  • wjcroftwjcroft Mount Shasta, CA

    "Not raw sample values, which go above and below the Y axis." This is of course assuming you've done a high pass filter at say .5 Hz, to cut off the DC offset.

  • Oh, yes, sample.channel_data is raw data, not band-pass filtered.
    I use cyton.py to read EEG data, so sample.channel_data is a list of raw amplitudes at unit uV.
    I'll add a narrow band-pass filter (31.2Hz +- some Hz) to my code and try again.

  • wjcroftwjcroft Mount Shasta, CA

    The expression in the GUI is NOT using raw EEG data samples. There is some preceding step in the GUI source code that you are missing that computes data_std_uV from the raw data. That is my guess. You CANNOT feed this impedance expression raw EEG values. Because raw EEG samples are both above and below the Y axis (plus and minus microvolts), the output will just be nonsense. The input to this expression is some type of estimate of power or amplitude of the overall EEG. Possibly related to what is displayed on the time series graph, showing the small numeric text on each channel, with the approximate rms power.

  • wjcroftwjcroft Mount Shasta, CA

    Additionally, any sort of amplitude or power estimate would include some type of time averaging, running average. So that instantaneous small peaks are smoothed out.

  • Now I'm trying this problem. I think we can get the impedance data after executing config_board('z 1 0 1 Z') or config_board('z 4 1 0 Z') on Python. And I used this calculation "data2=data*4.5/ float((math.pow(2, 23) - 1)) / (24) * 1000000", which commented on brainflow's slack.
    But the impedance was different from OpenBCI_GUI. Could someone help me?
    @Hiroki
    Did you solve this problem??

  • Hi,

    When using the impedance settings to stream impedance values from the channels, should the raw output be multiplied by anything (similarly to the EEG and ADS scale factors) to get the Ohm values?

    Thanks,
    Zach

  • wjcroftwjcroft Mount Shasta, CA

    @ZachNairac, hi.

    Merged your new thread into this existing one on the same topic. See previous comments.

    William

  • XaviWhiteXaviWhite Tarragona

    Good morning,
    I've been programming a little file to export the data impedance gived in channel 2 in which I'm trying to measure a 2.2kohm resistor. The problem is that checking with the OpenbciGUI shows me the correct resistance I'm measuring but I don't know if I'm doing correctly with the python file because I can not export the correct value. Any help, please?
    ThankU:)

  • wjcroftwjcroft Mount Shasta, CA

    @XaviWhite, hi.

    I merged your comment into this existing thread, please see previous comments.

    See this section of the GUI code,

    https://github.com/OpenBCI/OpenBCI_GUI/blob/master/OpenBCI_GUI/DataProcessing.pde#L52

    William

  • I'm still struggling with the impedance issue.
    The impedance values are still not accurate and always come out around 2.4. In addition, the value changes very little when the EEG machine is put on and off. Has anyone had any success with impedance measurements? Also, does anyone have any advice?

    Our code firstly changed setting by config.board('z X 1 0 Z'), and get the board data by get_board_data(). After that, we applied the 31Hz bandpass filter and calculated the standard deviation(data_std) for 1 second data. Then we calculated the impedance by using this formula.
    impedance = (sqrt(2.0)data_std_uV[X]1.0e-6) / BoardCytonConstants.leadOffDrive_amps(6.0e-9);
    impedance -= BoardCytonConstants.series_resistor_ohms(2200);

  • Sorry, my explanation is little wrong. I multiplied 1/1000 by the impedance. So the factor of BoardCytonConstants.series_resistor_ohms largely affected the value. So the value of the impedance is near 2.2~2.4.

  • I've got a Cyton + Daisy board with 16 channels. I used this code here (https://github.com/OpenBCI/OpenBCI_Cyton_Library/pull/96) to update the board firmware to save directly to an SD card, which lets me get a 500Hz sample rate. To set the sample rate at 500Hz, I changed line 1354 of 'OpenBCI_32bi_Library.cpp' to be 'curSampleRate = SAMPLE_RATE_500'. Then, I used the GUI to start/stop data collection, although no data appears on the GUI once I start streaming. This method works to get 500Hz data saved on the SD card.

    However, to check impedances, I need to re-boot the Cyton board's firmware with a 250Hz sample rate and re-open the GUI. This is a tedious process. There must be a way to send a 'check impedance' signal to the board, and get a numeric answer back? How would I do this?

    I tried running the GUI using Processing. The console shows that a signal is sent to the board when I click the impedance button on the GUI, but the console (and the GUI) don't report the resulting impedance value. Do I need to use BrainFlow with python, as described here? https://docs.openbci.com/docs/11ForDevelopers/SoftwareDevelopment

    Thanks in advance.

  • wjcroftwjcroft Mount Shasta, CA

    Hi, @super248,

    I merged your new thread into this existing thread, on the same subject. Look at some of the previous comments. I'm not sure this is resolved yet, but at least you can PM with the other commenters here and see if you can brainstorm together.

    Note that when measuring impedance generally you want the board to be online (not recording), and during impedance check the channels are not reading EEG, instead a 31 Hz signal is injected and you are looking at the amplitude of that resulting scalp signal.

    There is also a related thread on the Brainflow Slack, you can likely find it with a search there.

    https://brainflow.org/ [see Slack signup on that page]

    Regards, William

  • lukasstingllukasstingl Germnay
    edited March 7

    Hi everyone,

    currently, we are in the process of measuring impedence from a cyton board as well. We connect to the board with Webserial API and send the respective commands to the Board to activate impedance check. As far as I saw by plotting the incoming data, there is data sent at around 31Hz with and without activating the impedance check. Therefore I am not entirely sure if my setup is correct and would like to double check my calculations here.

    Setup:
    1. Filter raw, incoming data with notch60 as described here: https://openbci-stream.readthedocs.io/en/latest/notebooks/A2-electrodes_impedance.html
    2. Filter the data using a GenericButterBand filter with the low processing band 1,4, 8, 13, 30 and high processing band 4, 8, 13, 30, 55 as described in the GUI repository.
    3. I then use the standard deviation from the filtered data and insert it in above formula.

    My calculations are quite close to the one from the GUI with quite good impedance (my calculation is about 20-50 kOhm and the GUI says 50-70 kOhm). Is this the recommended procedure for manual impedance calculation?

    Additionally, is it appropriate to utilize the processing bands from the GUI repository? I've noticed that researchers from openbci-stream use 27 as the low frequency band and 37 as the high frequency band. When applying this filter, my impedance drops to 7-10 kOhm with the same raw data as input.

    As I'm relatively new to impedance checks, I'd appreciate any guidance on whether I'm on the right track.

    Thank you in advance.

    Kind regards
    Lukas

  • wjcroftwjcroft Mount Shasta, CA

    Lukas, hi.

    Current versions of the GUI have a bug that is reporting the wrong impedance when used with calibration resistors. See the discussion at,

    https://openbci.com/forum/index.php?p=/discussion/3790/high-impedance#latest

    Until the updated GUI binary is available, the thread above contains the 2 source code lines which need to be changed.

    The Cyton widget code is here,

    https://github.com/OpenBCI/OpenBCI_GUI/blob/master/OpenBCI_GUI/W_CytonImpedance.pde

    William

  • Hi William,

    thanks for the quick response. I guess I have an older version, since my impedance values are way lower than the ones described in the thread you’ve posted.

    I just wanted to confirm my processing is correct and why the widget is using multiple frequencies for the filter.

    Thank you in advance.

    Kind regards
    Lukas

Sign In or Register to comment.