Hi everyone.
I've been playing with and Arduino Uno R4 WiFi and the OLIMEX-EKG-EMG shield.
I would appreciate some guidance in detecting the muscle signal properly.
Mods please feel free to relocate this post if this is the wrong category.
What I did:
- FFT of the analog signal input using the ArduinoFFT library
- Filtered out frequencies 0 to 60Hz
- Sent the data over to Processing for DSP and logging
What I can't seem to accomplish:
- Detect the jaw clenching reliably (current detection isn't continuous and it's prone to false positives, must be re-done from scratch)
- Setting beeps and alarms to stop clenching, this is more difficult than expected because of the unreliable detection
Must mention:
- I'm reusing the electrodes, the gel might not be fresh and that can become a problem soon.
What is the recommended approach to detect the signal in the FFT?
We're dealing with nonlinear signals, so I don't really know what I'm aiming for
Spectrogram of mostly resting jaw
Clenching and holding a couple times
Spectrogram including the frequencies 0 to 60Hz + some clenching
The following snippet illustrates how the vReal float array (from the examples of ArduinoFFT) is populated before sending it to Processing to draw the spectrogram.
float vReal[samples]; // We're working with this array, of size samples/2
ArduinoFFT<float> FFT = ArduinoFFT<float>(vReal, vImag, samples, samplingFrequency);
. . . . . .
void collect_samples() {
for (uint16_t i = 0; i < samples; i++) {
vReal[i] = analogRead(analog_pin);
vImag[i] = 0.0;
delayMicroseconds(1000000 / samplingFrequency);
}
}
. . . . . .
void loop() {
collect_samples();
FFT.windowing(FFTWindow::Hamming, FFTDirection::Forward);
FFT.compute(FFTDirection::Forward);
FFT.complexToMagnitude();
// Erasing all bins up to 60Hz (the shield has a filter)
uint8_t i = 255;
while (freq_bin * (++i) <= 60)
vReal[i] = 0;
send_to_udp();
}
The full code is a mess, partially done with GPT too. Needs to be rewritten as mentioned. I can still post it if needed.
(This post is also on reddit)