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 shown below. When the forearm is relaxed on the table, the built-in LED will be off. When the forearm is flexed, the built-in LED will be on. muscleElectrode.png

Get Started

#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;
}

Adjust the code

#define EMG_THRESHOLD 60 The number 60 here needs to be adjusted based on who is using it and where is the electrodes.

After uploading the above code, you can open the Serial Plotter. Look at the Orange line (or the smoother line), this is when my forearm is relaxed, and the number is about 30.

serialPlotter_relaxed.png

This is when my forearm is flexed, and the number is over 60. serialPlotter_flexed.png

You will need to adjust the threshold based on your own measurement.