Skip to main content

How to use a EMG Muscle Sensor

What is an EMG Muscle Sensor?

An EMG (Electromyography) muscle sensor is a device that measures the electrical activity produced by muscles when they contract. It detects the small voltage changes that occur when muscle fibres are activated by motor neurons, and converts this data into an electrical signal that can be analysed or used to control other devices.

In this tutorial, we are using the MikroElektronika EMG Click board.

Wiring

  1. 5V to 5V (Power)
  2. AN to A0 (Signal)
  3. GND to GND (Ground)

Where to put the electrodes

In this tutorial, we will place the 3 electrodes as below. When the forearm is relax in the table, builtin LED will be off. When the forearm is flexed like this, the muscleElectrode.png

Get Started

This example will print the BPM on the serial monitor and blink the builtin LED to indicate each beat.

#define SAMPLE_RATE 500
#define INPUT_PIN A0

// envelopeee buffer size
// High value -> smooth but less responsive
// Low value -> not smooth but responsive
#define BUFFER_SIZE 64

// EMG Threshold value, !!!!need to change!!!!
// Check by plotting EMG envelopee data on Serial plotter
#define EMG_THRESHOLD 60

int circular_buffer[BUFFER_SIZE];
int data_index, sum;

void setup() {
  // Serial connection begin
  Serial.begin(115200);
  pinMode(13, OUTPUT);

}

void loop() {

  static unsigned long past = 0;
  unsigned long present = micros();
  unsigned long interval = present - past;
  past = present;
  static long timer = 0;
  timer -= interval;

  // Sample and get envelope
  if(timer < 0) {
    timer += 1000000 / SAMPLE_RATE;
    
    int sensor_value = analogRead(INPUT_PIN);  // RAW EMG Values
    int signal = EMGFilter(sensor_value); // Filtered EMG
    int envelope = getEnvelope(abs(signal));

    if (envelope > EMG_THRESHOLD) {
    digitalWrite(13, HIGH);
    } else {
    digitalWrite(13, LOW);
    }

    Serial.print(signal);
    Serial.print(",");
    Serial.println(envelope); //modify thershold based 

  }
}

// envelope detection algorithm
int getEnvelope(int abs_emg){
  sum -= circular_buffer[data_index];
  sum += abs_emg;
  circular_buffer[data_index] = abs_emg;
  data_index = (data_index + 1) % BUFFER_SIZE;
  return (sum/BUFFER_SIZE) * 2;
}

float EMGFilter(float input)
{
  float output = input;
  {
    static float z1, z2; // filter section state
    float x = output - 0.05159732*z1 - 0.36347401*z2;
    output = 0.01856301*x + 0.03712602*z1 + 0.01856301*z2;
    z2 = z1;
    z1 = x;
  }
  {
    static float z1, z2; // filter section state
    float x = output - -0.53945795*z1 - 0.39764934*z2;
    output = 1.00000000*x + -2.00000000*z1 + 1.00000000*z2;
    z2 = z1;
    z1 = x;
  }
  {
    static float z1, z2; // filter section state
    float x = output - 0.47319594*z1 - 0.70744137*z2;
    output = 1.00000000*x + 2.00000000*z1 + 1.00000000*z2;
    z2 = z1;
    z1 = x;
  }
  {
    static float z1, z2; // filter section state
    float x = output - -1.00211112*z1 - 0.74520226*z2;
    output = 1.00000000*x + -2.00000000*z1 + 1.00000000*z2;
    z2 = z1;
    z1 = x;
  }
  return output;
}