How to use a EMG Muscle Sensor
What is aan HeartEMG RateMuscle Sensor?
HeartAn RateEMG Sensor(Electromyography) muscle sensor is a plug-and-playdevice sensorthat 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 easilybe incorporateanalysed liveor heart-rateused datato intocontrol projects.other devices.
In this tutorial, we are using the lab,MikroElektronika weEMG offerClick the Ear-clip/Finger-clip Heart Rate Sensor fromboard.
Seeed Studio.

For other popular heart rate sensors that look like below, we found it to be tricky to use. The user cannot press on the sensor too hard or too soft, otherwise you will get very unstable reading.
Wiring
Red5V to 5V (Power)YellowAN to A0 (Signal)BlackGND 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


Get Started
This example will print the BPM on the serial monitor and blink the builtin LED to indicate each beat.
int#define PulseSensorPurplePinSAMPLE_RATE =500
A0;#define INPUT_PIN A0
// Pulseenvelopeee Sensorbuffer connected to analog pin A0
int LED = LED_BUILTIN;size
// On-boardHigh LEDvalue int-> Thresholdsmooth =but 550;less responsive
// ThresholdLow forvalue detecting-> anot heartbeatsmooth intbut Signal;responsive
#define BUFFER_SIZE 64
// HoldsEMG rawThreshold analogvalue, reading!!!!need boolto PulseDetected = false;change!!!!
// TrueCheck whenby aplotting beatEMG isenvelopee detecteddata unsignedon longSerial lastBeatTimeplotter
=#define 0;EMG_THRESHOLD //60
Timeint (ms)circular_buffer[BUFFER_SIZE];
ofint thedata_index, last beat
float BPM = 0; // Calculated Beats Per Minutesum;
void setup() {
pinMode(LED,// OUTPUT);Serial connection begin
Serial.begin(115200);
pinMode(13, OUTPUT);
}
void loop() {
// Read the sensor
Signal = analogRead(PulseSensorPurplePin);
// Check if signal crosses the threshold upward (beat detected)
if (Signal > Threshold && !PulseDetected) {
PulseDetected = true; // mark that we’re in a beatstatic unsigned long currentTimepast = millis(0;
unsigned long present = micros();
unsigned long deltainterval = currentTimepresent - lastBeatTime;past;
ifpast (lastBeatTime= >present;
static long timer = 0;
timer -= interval;
// Sample and get envelope
if(timer < 0) {
/timer += 1000000 / skipSAMPLE_RATE;
firstint beat (no interval yet)
BPMsensor_value = 60000.0 / delta; // 60000 ms per minute
Serial.print("BPM: ");
Serial.println(BPM);
}
lastBeatTime = currentTime;
digitalWrite(LED, HIGH)analogRead(INPUT_PIN); // flashRAW LEDEMG onValues
beat
}
// Whenint signal goes back below threshold, reset for next detection
if (Signal < Threshold && PulseDetected) {
PulseDetected = false;
digitalWrite(LED, LOW);
}
// Small non-blocking pause (optional for stability)
// Just ensures serial output isn’t too fast
static unsigned long lastPrint = 0;
if (millis() - lastPrint > 20) {
//Serial.print("Signal: ");
//Serial.println(Signal);
lastPrint = millis();
}
}
This example will print your heart rate on the Serial Potter, you will see somthing similar to the hospital machine.
// Variables
int PulseSensorPurplePin = 0; // Pulse Sensor PURPLE WIRE connected to ANALOG PIN 0
int LED = LED_BUILTIN; // The on-board Arduion LED
int Signal; // holds the incoming raw data. Signal value can range from 0-1024
int Threshold = 540; // Determine which Signal to "count as a beat", and which to ingore.
// The SetUp Function:
void setup() {
pinMode(LED,OUTPUT)EMGFilter(sensor_value); // pinFiltered thatEMG
willint blinkenvelope to= your heartbeat!
Serial.begin(115200)getEnvelope(abs(signal));
//if Set's(envelope up> Serial Communication at certain speed.
}
// The Main Loop Function
void loop()EMG_THRESHOLD) {
SignaldigitalWrite(13, = analogRead(PulseSensorPurplePin); // Read the PulseSensor's value.
// Assign this value to the "Signal" variable.
Serial.println("Signal " + String(Signal)); // Send "reading " followed by the Signal value to Serial Plotter.
if(Signal > Threshold){ // If the signal is above "550", then "turn-on" Arduino's on-Board LED.
digitalWrite(LED,HIGH);
} else {
digitalWrite(LED,13, LOW);
}
Serial.print(signal);
Serial.print(",");
Serial.println(envelope); //modify Else,thershold the sigal must be below "550", so "turn-off" this LED.based
}
delay(20)}
// 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;
}


