Ganglion firmware, direct EEG read [resolved]

edited October 2021 in Ganglion

Quick question: Is there a way by which I can obtain the EEG values for each channel directly from the ADC onboard, without having to go through the GUI or Processing? I want to be able to do some simple calculations onboard the Ganglion with the EEG values streaming in from the ADC in real-time. In the OpenBCI_Ganglion Library, I see the references to ganglion.MCP_dataReady() and ganglion.processData(), but is there a method or command to access the actual EEG data itself??

Comments

  • @wjcroft and @retiutut : Do you gentlemen have any pointers or advice to share that could point me in the right direction?

  • wjcroftwjcroft Mount Shasta, CA

    AJ / teknomage, hi.

    As you've seen by looking over the general scheme of the Ganglion firmware, it starts with the "main loop",

    https://github.com/OpenBCI/OpenBCI_Ganglion_Library/blob/master/examples/DefaultGanglion/DefaultGanglion.ino

    Which checks the ready status of each input device on the Ganglion, then enters the routine to handle that. As you say, then enters ganglion.processData() when a new sample is available. The whole idea is that the main loop functionality must be maintained intact, otherwise the other aspects of this "mini operating system" are not going to get the cycles they need.

    Consequently, yes, at some point the actual EEG sample is read from the chip and prepared by buffering and staging it for radio transmission. This includes compressing the data stream.

    So the short answer is, you can add code to what this main loop does, but you must preserve the general idea of what it is doing, otherwise all the other features of the "mini operating system" are not functional. If your goal is to forget about what the Ganglion does, and just read samples, process, and do some output action on the Ganglion itself (no radio output packets), then you can basically toss the main loop idea and roll your own main loop. You'll have to dig into the processData routine and others called to see how each sample is pulled in from the chip. But remember, you can only grab a new sample when it is ready.

    One last thought if you are considering outputting to digital / analog GPIO pins on the Simblee: note that EEG is highly sensitive, operating in the microvolt region. Digital logic on the other hand is operating in the multivolts (3.3V) range. So it's possible that signals you output via wires connected to the board, will induce coupling (capacitive / inductive), into nearby EEG input wires. So the potential for getting noise into your EEG is possible, if not careful. This is why Bluetooth forwarding the data stream to another processor on the laptop or Raspberry, etc, avoids all this trouble.

    William

  • edited October 2021

    As always, thank you so much for the detailed reply, William! Rest assured for the purpose I have in mind, I certainly intend to maintain the functionality of the main loop, I dont plan to mess around with that. I merely need to be able to read the actual EEG data, do a few computations and simply send an output in response to the data processed. And thanks for the reminders, w.r.t waiting until a new sample is ready and preventing crosstalk/coupling within the EEG cable - points noted!

    However, when I asked if there was a method or command to access the ADC data, I meant if there was a simple function or method available for the Ganglion object? Is there something convenient similar to the ganglion.processData() method that I could simply call to get the raw data? I looked through the Ganglion Library .h file and I dont see any public or exported functions that can do this directly. I'm assuming if I were to make changes to the library I'd have to recompile it all from source, which I'd like to avoid, if possible. Anyways, from a quick glimpse, am not sure if ganglion.updateMCPdata() would serve the purpose?

    Further down the .h file, I also see variables required for MCP3912's functionality, so maybe this might be closer to the actual raw data I'd need?
    int channelData[4]; // holds channel data
    int lastChannelData[4]; // holds last channel data
    byte rawChannelData[24];

  • wjcroftwjcroft Mount Shasta, CA

    I would not be looking 'only' in the .h file, but in the actual source code which reads from the MCP chip register. (Not just function definitions.) As mentioned previously you'll have to dig into the source code yourself.

Sign In or Register to comment.