Implementing a “headset in use” vs. “headset not in use” feature
Hello all, I’m trying to implement a real-time feature (using brainflow in Python) to detect if my headset (ultracortex mark iv, cyton) is “in use” (turned on, on the user’s head, with clips attached to earlobes) or “not in use” (turned on, but at rest on a table, clips not attached to anything).
I’ve tried multiple ways to achieve this:
- Using the railing values: this does not work because while turning on the headset at rest all railing values are at 100%, after about 2 min. most channels get unrailed.
- Calculating the moving average over a time_window of 2s on each channel, then do a standard deviation analysis on the last 20 time_windows. The idea is that at rest fluctuations in the signal are minimal, so if the std dev of the moving average values remain below a certain threshold I can consider the headset to be “at rest”. Problem with this is that free pins are extremely sensitive to perturbations (due to the amplification and unconnected ref), so just by bumping into the table or waving my hand around the headset without touching it, fluctuations appear with an amplitude equivalent to the “in use” case.
- Using the accelerometer_data : it’s pretty easy to detect if the headset is barely moving. Problem is that I can sit still enough with the headset on my head to basically obtain the same acceleration values than at rest.
- Using the band power values for a frequency range of [40, 50] Hz (I used the OpenBCI GUI spectrometer to find the frequency range where “in use” and “not in use” are the most differentiated). Problem is that this is also pretty sensitive to perturbations.
So none of these methods worked. I’ve got a couple of further ideas, but I’d like to have your opinion on them before implementing them, for various reasons:
Using reference values directly: could theoretically be a good idea, but I can’t find a way to get these values separately from the cyton board. And even if I found a way to get these values, it could be just as sensitive to perturbations as case 2.;
Use a neural network taking as input railing values, standard deviation of the moving average over the last time_window, accelerometer data, and band power, and training it to detect if the headset is “in use” or “not in use”. While this could work, this represents a LOT of work, so I prefer first considering easier methods to implement.
So my questions to you are:
- Are there any ready-made scripts out there doing this?
- If not, are there easier ways to do this?
- If not, do you know of any other methods I could try out (based on other parameters perhaps)?
I started programming this feature thinking it would be done in a couple of hours, but it turned out to be way more difficult than I expected. So any ideas, feedback on the above, help, tips, or even ready-made solutions would be greatly appreciated. Thanks in advance for your help!
Comments
Hi Romain,
Have you considered using the impedance checking mode?. Channel impedances when touching skin are markedly different than when not touching. The forehead channels (Fp1 or Fp2) are good candidates, since these have larger contact surfaces than the combs.
https://docs.openbci.com/Cyton/CytonSDK/#leadoff-impedance-commands
You want to be measuring the N-channel input, since this is the default wiring on Cyton. Pins closest to board surface.
It might be wise to do a combination of this with the accelerometer approach. Accelerometer moving would be your primary indicator of usage. If accelerometer becomes very still, no movement, check the impedance periodically to confirm it is still on the head.
Regards, William
Hello William,
Thanks a lot for your suggestion, this indeed seems to be a viable way to achieve this detection feature!
With the impedance check I have about 500kOhm when in use, and 5000kOhm when not in use, and unlike the railing values this difference remains stable over time. But I have some questions concerning this impedance check:
Thanks for all the fish the help!
re: "railing percentage" changing over time.
The GUI developer, Richard @retiutut may have further insights. Actually I think this is happening in the ADS1299 hardware. As it will, over time, try to normalize whatever is happening at the electrodes. Remember, no electrode skin contact is a completely unacceptable situation as the ADS1299 is then at the mercy of whatever EMF environmental noise is present in your room. Both the electrode and connecting wires then act like 'antennas' for impinging EMF.
re: combination of accelerometer and impedance
Yes this is why I suggest the accelerometer is your primary indicator, and you only need to check the impedance if the subject is very still and accel is showing 0,0,0.
re: deriving impedance values from Brainflow
There are some other threads here on the Forum which suggest solutions for that. Use the Google Advanced Search button in the upper right to find those threads.
William
Thanks a lot William! It's greatly appreciated!