Bruxism alarm using EMG

This video shows a prototype of a system that provides an audible alarm when the user suffers a case of bruxism (https://en.wikipedia.org/wiki/Bruxism). When the amplitude of the EMG signal generated by the masseter muscle (one of the muscles of mastication) exceeds a threshold set during system calibration, a buzzer emits an audible signal that wakes up the user in the case of sleep bruxism, or warns him in case of awake bruxism.

This video shows a prototype of a system that provides an audible alarm when the user suffers a case of bruxism (https://en.wikipedia.org/wiki/Bruxism). When the amplitude of the EMG signal generated by the masseter muscle (one of the muscles of mastication) exceeds a threshold set during system calibration, a buzzer emits an audible signal that wakes up the user in the case of sleep bruxism, or warns him in case of awake bruxism.

#include <MsTimer2.h>

static const unsigned int EMG_CH1 = 0;

static const unsigned int buzzerPin = 9;

static const unsigned int ledPin = 13;

static const unsigned int sampleTime = 1;

static const double adcRef= 5.00;

static const unsigned int adcRes = 1023;

static const double adcConv = adcRef/adcRes;

volatile unsigned int emg = 0;

double emgMean = 0.00;

double emgMovav = 0.00;

double emgMvc = 0.00;

volatile unsigned int sOK = 0;

unsigned int i = 0, k = 0;


/* sampling reads the ADC every 1 ms with the MsTimer2 interrupt. */

void sampling()

{

emg = analogRead(EMG_CH1);

sOK = 1; // sOK indicates that there is a new sample

}


/* meanCalc computes the mean value of the EMG signal during a period of

meanSamples. The mean value of the signal is its baseline. This value is

subtracted from the measured EMG signals to have a baseline of 0 V. */

void meanCalc(unsigned int meanSamples)

{

while(i < meanSamples)

{

delayMicroseconds(50);

if(sOK==1)

{

sOK = 0;

Screen Shot 2019-11-11 at 4.58.53 PM.png

i++;

emgMean = emgMean + emg*adcConv;

}

}

i = 0;

emgMean = emgMean/meanSamples;

}


/* movAv computes the running moving average of the EMG signal. First, the

baseline of the signal is lowered to 0 V, to be able to rectify it. The running

moving average rectifies and smooths the signal (acts as a low pass filter),

returning the amplitude of the signal. */

void movAv()

{

double emgZero = emg*adcConv - emgMean; // Signal with 0 V baseline

emgMovav = emgMovav*0.99 + abs(emgZero)*0.01; // Rectified and smoothed signal

}


/* mvcCalc computes the maximum voluntary contraction, the maximum force the

user is able to exert. This value is used to compute the activation threshold */

void mvcCalc(unsigned int mvcSamples)

{

while(i < mvcSamples)

{

delayMicroseconds(50);

if(sOK==1)

{

sOK = 0;

i++;

movAv();

if(emgMovav > emgMvc) {

emgMvc = emgMovav;

}

}

}

i = 0;

emgMovav = 0.00;

}


/* blinkLED blinks a led "repeat" times with a "bTime" interval between on and off */

void blinkLED(unsigned int repeat,unsigned int bTime)

{

for(i=0;i<repeat;i++)

{

digitalWrite(ledPin,HIGH);

delay(bTime);

digitalWrite(ledPin,LOW);

delay(bTime);

}

}


void setup() {

pinMode(EMG_CH1,INPUT);

pinMode(ledPin,OUTPUT);

pinMode(buzzerPin,OUTPUT);

MsTimer2::set(sampleTime, sampling);

MsTimer2::start();

Serial.begin(250000);


/* System calibration */

delay(5000);

/* Calibration step #1: calculate the baseline of the signal during 30 s */

blinkLED(1,500); // LED indicates calibration step #1 start

meanCalc(30000);

blinkLED(1,500); // LED indicates calibration step #1 end

delay(1000);

/* Calibration step #2: calculate the maximum voluntary contraction during 5 s*/

blinkLED(2,500); // LED indicates calibration step #2 start

mvcCalc(5000);

blinkLED(2,500); // LED indicates calibration step #2 end

}


void loop() {

movAv(); // Gets the amplitude of the measured EMG signal


/* If the amplitude of the EMG signal is greater that a 35% of the MVC, the

user is warned with a visual alert (LED) and an audible alarm (buzzer). */

if(emgMovav > 0.35*emgMvc) {

digitalWrite(ledPin, HIGH);

analogWrite(buzzerPin,500); // Adjusts the volume of the buzzer

delayMicroseconds(1275); // Sets the tone of the buzzer

}

else {

digitalWrite(ledPin, LOW);

analogWrite(buzzerPin,0);

delayMicroseconds(1275);

}

// delay(2);

// Serial.println(emgMovav);

}













Previous
Previous

DIY Bruxism Teeth Grinding Devices

Next
Next

Bruxism Update