GUI v2 freezing, wrong sample rate?

edited January 2017 in OpenBCI_GUI
Hello:

I have installed the new V2 of the GUI on my Mac running Sierra. If I run the compiled version, it will stream data for 1-2 seconds and then the GUI freezes. I have to shut it down and power down the dongle and board, then start over, and the same thing happens. When I run the GUI v2 in Processing by downloading the code, it streams better, but if I try to alter my channel setup (change the channels included in the Bias, etc.), the stream locks up and no more data gets collected. I get the following error message on the Processsing console:
Error, disabling serialEvent() for /dev/tty.usbserial-DJ00ISMD
null

v1 of the GUI still works, but I really like the new features of v2 and would love to use it. I bought my Cyton plus Daisy (16 channel system) in December, so I believe it should have the most recent firmware. Please let me know if you have any ideas. I'm excited about using the system for my research, but am concerned about its stability.

Thanks!
Dan Fletcher

Comments

  • Sorry, I realized that the message in the Processing console right before the error message might be useful:

    X :: 1328872
    OpenBCI_ADS1299: apparent sampleIndex jump from Serial data: 11 to  13.  Keeping packet. (1)
    Error, disabling serialEvent() for /dev/tty.usbserial-DJ00ISMD
    null

  • OK, so I did some more investigating. It looks like although the GUI code states that you should use a sampling rate of 125 Hz for 16 channels, it actually sets a constant sampling rate of 250Hz. I changed it to 125 in the Processing code and that seems to prevent the errors I was getting. 

    This begs the question. Is V2 of the GUI considered beta still at this point, or is it a true release? Just trying to decide whether I should still use V1 for now if V2 is not quite ready for primetime. Thanks for any input.

    Dan
  • wjcroftwjcroft Mount Shasta, CA
    Mentioning @Conor and AJ @pushtheworld. V2 should not be considered beta at this point because Ganglion depends on it. I guess the bug you found just squeaked through the checkout process. Thanks so much for catching this. It should be reflected in the Github as soon as possible.

  • edited January 2017
    @djfletch42 changing that constant to 125 fixed the issue? Just like that? Everything is based on the number of channels it looks like.


    Just put in a line of code to update this. Although I really must say I think this is from the incorrect "nchan" value.
  • In hardwaresync.pde I changed line 300 to be:
    private final float fs_Hz = 125.0f;  //sample rate used by OpenBCI board...set by its Arduino code
    and in datalogging.pde I changed line 411 to
    private int fs_Hz = 125;

    I didn't have time last night to dig around more and do more extensive testing. It didn't immediately crash like it had before. For those of you who know much more about the code than I do, if either of these look incorrect or if there are other things in the code that should be changed, please let me know. I'd love to get this working locally until the official code is updated.

    I also noted someplace in the code last night a comment that changing the sampling rate to anything other than 250 would affect the filter code, but I can't find it now. Any ideas about that?

    Thanks,
    Dan

  • Sorry, found it. It's in DataProcessing.pde lines 369-376

    //check to make sure the sample rate is acceptable and then define the filters
        if (abs(fs_Hz-250.0f) < 1.0) {
          defineFilters(0);
        } else if (abs(fs_Hz-200.0f) < 1.0) {
          defineFilters(1);
        } else {
          println("EEG_Processing: *** ERROR *** Filters can currently only work at 250 Hz or 200 Hz");
          defineFilters(0);  //define the filters anyway just so that the code doesn't bomb

    Does this mean that the filters won't work for the 125Hz sampling rate?

    Thanks!
  • So, I let the GUI run for awhile just now and it seemed OK at first, then I started getting these messages repeatedly in the Console:
    OpenBCI_ADS1299: apparent sampleIndex jump from Serial data: 133 to  135.  Keeping packet. (64834)
    OpenBCI_ADS1299: apparent sampleIndex jump from Serial data: 135 to  133.  Keeping packet. (64835)
    OpenBCI_ADS1299: apparent sampleIndex jump from Serial data: 133 to  135.  Keeping packet. (64836)
    OpenBCI_ADS1299: apparent sampleIndex jump from Serial data: 135 to  133.  Keeping packet. (64837)
    OpenBCI_ADS1299: apparent sampleIndex jump from Serial data: 133 to  135.  Keeping packet. (64838)
    OpenBCI_ADS1299: apparent sampleIndex jump from Serial data: 135 to  133.  Keeping packet. (64839)
    OpenBCI_ADS1299: apparent sampleIndex jump from Serial data: 133 to  135.  Keeping packet. (64840)

    The data in the GUI started looking crazy at this point. So I think my simple fix didn't work.

    Thanks,
    Dan
  • @djfletch42

    I am nervous about changing the sample rate as well. Will need to talk with @biomurph before we make these changes.
  • In case it's helpful, I did go through and calculate the filter coefficients for the 125Hz sampling rate. This code will incorporate the new filter coefficients into DataProcessing.pde. I used Matlab to calculate the coefficients and verified for each one that the coefficients matched the 250 and 200Hz coefficients currently in the system.

    This raised another question for me. At some points in the code it says that the Ganglion sampling rate is 256Hz, but the filter calculations were done assuming a 200Hz sampling rate. Not sure which is correct?

    Anyway, hope the code below is helpful.

    All the best,
    Dan








    p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; -webkit-text-stroke: #000000}
    p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; -webkit-text-stroke: #000000; min-height: 14.0px}
    span.s1 {font-kerning: none}

      // Daisy board 16 channels, sampling rate 125 Hz

       case 2:

         //loop over all of the pre-defined filter types

         n_filt = filtCoeff_notch.length;

         for (int Ifilt=0; Ifilt < n_filt; Ifilt++) {

           switch (Ifilt) {

           case 0:

             //60 Hz notch filter, assumed fs = 200 Hz.  2nd Order Butterworth: b, a = signal.butter(2,[59.0 61.0]/(fs_Hz / 2.0), 'bandstop')

             b2 = new double[] { 0.931378858122982, 3.70081291785747, 5.5390319127052, 3.70081291785747, 0.931378858122982 };

             a2 = new double[] { 1, 3.83246204081167, 5.53431749515949, 3.56916379490328, 0.867472133791669 };

             filtCoeff_notch[Ifilt] =  new FilterConstants(b2, a2, "Notch 60Hz", "60Hz");

             break;

           case 1:

             //50 Hz notch filter, assumed fs = 200 Hz.  2nd Order Butterworth: b, a = signal.butter(2,[49.0 51.0]/(fs_Hz / 2.0), 'bandstop')

             b2 = new double[] { 0.931378858122983, 3.0178169314316, 4.30731047590091, 3.0178169314316, 0.931378858122983};

             a2 = new double[] { 1, 3.12516981877757, 4.3025960583552, 2.91046404408562, 0.86747213379167};

             filtCoeff_notch[Ifilt] =  new FilterConstants(b2, a2, "Notch 50Hz", "50Hz");

             break;

           case 2:

             //no notch filter

             b2 = new double[] { 1.0 };

             a2 = new double[] { 1.0 };

             filtCoeff_notch[Ifilt] =  new FilterConstants(b2, a2, "No Notch", "None");

             break;

           }

         } // end loop over notch filters


         n_filt = filtCoeff_bp.length;

         for (int Ifilt=0; Ifilt<n_filt; Ifilt++) {

           //define bandpass filter

           switch (Ifilt) {

           case 0:

             //butter(2,[1 50]/(200/2));  %bandpass filter

             b = new double[] {

               0.615877232553134, 0, -1.23175446510627, 0, 0.615877232553134

             };

             a = new double[] {

               1, -0.789307541613509, -0.853263915766876, 0.263710995896442, 0.385190413112446

             };

             filt_txt = "Bandpass 1-50Hz";

             short_txt = "1-50 Hz";

             break;

           case 1:

             //butter(2,[7 13]/(200/2));

             b = new double[] {

               0.0186503962278356, 0, -0.0373007924556712, 0, 0.0186503962278356

             };

             a = new double[] {

               1, -3.17162467236842, 4.11670870329067, -2.55619949640702, 0.652837763407545

             };

             filt_txt = "Bandpass 7-13Hz";

             short_txt = "7-13 Hz";

             break;

           case 2:

             //[b,a]=butter(2,[15 50]/(200/2)); %matlab command

             b = new double[] {

               0.350346377855414, 0, -0.700692755710827, 0, 0.350346377855414

             };

             a = new double[] {

               1, 0.175228265043619, -0.211846955102387, 0.0137230352398753, 0.180232073898346

             };

             filt_txt = "Bandpass 15-50Hz";

             short_txt = "15-50 Hz";

             break;

           case 3:

             //[b,a]=butter(2,[5 50]/(200/2)); %matlab command

             b = new double[] {

               0.529967227069348, 0, -1.0599344541387, 0, 0.529967227069348

             };

             a = new double[] {

               1, -0.517003774490769, -0.734318454224822, 0.103843398397761, 0.294636527587914

             };

             filt_txt = "Bandpass 5-50Hz";

             short_txt = "5-50 Hz";

             break;

           default:

             //no filtering

             b = new double[] {

               1.0

             };

             a = new double[] {

               1.0

             };

             filt_txt = "No BP Filter";

             short_txt = "No Filter";

           }  //end switch block


           //create the bandpass filter

           filtCoeff_bp[Ifilt] =  new FilterConstants(b, a, filt_txt, short_txt);

         } //end loop over band pass filters


         break;

  • edited January 2017
    @djfletch42 the ganglion was originally 256Hz, then BLE said nope, and it's 200Hz. Thanks so much for taking a crack at the filter coefficients, I will add this to the patch.

    Why do you have "assume 200Hz" in the pasted code? Do you know how to github?

    Thanks

    AJ
  • Sorry, that was just copy and pasted from the original code. I didn't finish editing the comments. Those coefficients are for the 125Hz sampling rate. I did clone the distribution from github, but I figured you guys were likely working on fixing the other parts of the code for the 125Hz sampling rate, so didn't want to push back multiple versions. It all seems to be working OK on my system right now. I'll be collecting data from a dog next week so will let you know if I see any problems.

    Also, I noticed that you were working on a way to connect to the board without resetting it so that you don't interrupt writing data to the SD card. Is that something that still might be coming? It would be very helpful for my application.

    Thanks,
    Dan
  • Hey @djfletch42 ... I don't think switching 'private final float fs_Hz' to 125.0f makes sense. That code was the same in GUI V1. One thing I suggest you try: 

    Go to OpenBCI_GUI.pde and change: 

    final int nPointsPerUpdate = 10; //update the GUI after this many data points have been received

    back to ...

    final int nPointsPerUpdate = 24; //update the GUI after this many data points have been received

    This will reduce the "smoothness" of your GUI, but should increase the chances of it working properly. There is no guarantee that this fixes the issue, but it might. Let us know.

    Sorry for the trouble and thank you for your detailed post. And yes, we should probably refer to this as a Beta release. ; )
  • Hey Folks

    Just wanted to update some things regarding the 16 channel board.

    I'm confused about the sampling rate. Looking at the files collected, although my understanding is that when the 16 channel board is used streaming only occurs at 125Hz, the saved files state that they are at 250Hz, and the filters I generated assuming the samples coming in are at 125Hz do not work. Can someone confirm whether the streaming occurs at 125Hz or at 250Hz? This is obviously important for analyzing any data collected by the system. 

    Dropping the nPointsPerUpdate allows me to collect data, so that did seem to help. I'm still having issues with the GUI getting out of sync after data are collected for some period of time (usually within an hour or so). Would really like to get to the bottom of this.

    I found one other bug in the software. In the SD card file conversion algorithm (convertSDFile), it's assumed that you're not using a Daisy board. If you are collecting 16 channels it only converts the first 8 channels. I just added a numChannels variable and set it to 8 if the number of columns of data is less than 16 and to 16 otherwise. This allowed conversion of all 16 columns of data. I did notice that it seems that the accelerometer data is not converted to the same values as those stored in the streamed file. Could someone take a look at that?

    Thanks,
    Dan
Sign In or Register to comment.