Getting Started

Getting Started with the Protocentral easyEMG Surface EMG Breakout

Last updated Nov 7, 2026

The Protocentral easyEMG is a single-channel surface EMG breakout that gives you the raw muscle waveform over I²C, not just an envelope. This guide takes you from the box to watching a muscle contract, first in the Arduino Serial Plotter and then in the OpenView desktop app, by way of the wiring, the electrodes and the one safety rule that matters most.

Where you’ll end up: raw sEMG (top) and its RMS envelope (bottom) in OpenView, in µV at the electrodes, with effort as a percentage of your recorded maximum contraction (right), during a forearm flex. Seeing it in OpenView, below, shows how.

Research use only. easyEMG is for education, research and experimentation. It is not a medical device and must not be used for diagnosis or monitoring of any medical condition.

Before you put electrodes on anyone

easyEMG has no isolation. With electrodes on a person, the host must run from a battery, or connect through an easyISO isolated Qwiic adapter.

On a mains-powered computer, leakage current through the USB ground drives the reference amplifier to its rail, and you get no EMG at all, not a noisy trace. A laptop on battery is fine, as long as its charger is unplugged.

The same applies to test equipment. A mains-earthed bench scope connects the person wearing the electrodes to earth, so use a battery-powered scope.

Introduction

A contracting muscle produces a small, fast, zero-mean signal at the skin. Many muscle sensors rectify and smooth that signal in hardware and hand you only the envelope, so the waveform underneath is gone. easyEMG keeps it:

  • A TI INA333 instrumentation amplifier takes the difference between two electrodes on the muscle, with a gain of ×11.
  • An RC high-pass at about 20 Hz removes electrode offset and motion baseline.
  • A TI OPA2333 op-amp adds a gain of ×4.7, for ×51.7 in total.
  • A Sallen-Key low-pass limits the band to about 310 Hz.
  • A TI TLA2024 12-bit ADC digitises the result and sends it over I²C.
  • A further OPA2333 stage and a third electrode form a driven reference, which holds the body near the amplifier’s common mode.

The Arduino library computes the RMS envelope in software, so you get the “how hard is this muscle working” number and can still go back to the signal behind it.

Key Features

  • Raw band-limited waveform, read in microvolts at the electrodes.
  • RMS envelope, activation detection and %MVC in the library.
  • Labelled test points: INA OUT, OUT, DRL and VMID, plus a GND point for your probe clip.
  • Two Qwiic / STEMMA QT ports for daisy-chaining, plus a 0.1″ header for 3.3 V or 5 V hosts.
  • Shares a bus with easyECG: easyEMG ships at 0x48 and easyECG at 0x49.
  • Open hardware (CERN-OHL-P v2) and an MIT-licensed library.

What’s in the Box

Protocentral easyEMG kit: the breakout board, a 1×4 header, a 3-lead snap electrode cable with a 3.5 mm plug, and ten disposable snap electrodes

Qty Item
1 Protocentral easyEMG breakout board
1 1×4 0.1″ header (not soldered)
1 3-lead snap electrode cable, 3.5 mm TRS
10 Disposable Ag/AgCl snap electrodes

A Qwiic cable and a host board are not included.

Specifications

Parameter Value
Channels 1 differential sEMG channel, 3 electrodes (E1, E2, REF)
Gain ×51.7 total (×11 in-amp, ×4.7 second stage)
Analog bandwidth About 20 – 310 Hz (−3 dB)
Input range ±4.95 mV; electrode offset tolerance ±145 mV
ADC TI TLA2024, 12-bit, ±0.256 V range
Resolution 2.42 µV per count at the electrodes
Sample rate Set by how fast your host polls; see below
Interface I²C / Qwiic, address 0x48 (0x49 via the ADDR jumper)
Supply 3.3 V on Qwiic; 3.3 – 5 V on the header
Reference current limit 390 kΩ (≤ 4.2 µA into the body)
Board 40.0 × 28.8 mm, 4 × M2 mounting holes

Hardware Overview

Protocentral easyEMG front: two Qwiic ports, the 1×4 header labelled SCL, SDA, VCC and GND, test points labelled INA OUT, OUT, DRL, VMID and GND, the ADDR jumper and the 3.5 mm electrode jack

Test point What you’ll see there
INA OUT The in-amp output, ×11, including the electrode offset
OUT The final signal going into the ADC, ×51.7, centred on VMID
VMID The buffered 1.65 V mid-rail that the signal is centred on
DRL The driven-reference output
GND Ground, for your probe clip

Protocentral easyEMG back: the signal chain printed as a block diagram, from ESD and RF protection through the in-amp, 20 Hz high-pass, ×4.7 gain stage and 310 Hz low-pass to the 12-bit ADC, with the note Battery or isolated host only

I²C address

The board ships at 0x48. To move it to 0x49, cut the bridge on the ADDR jumper and bridge the 0x49 side, then construct the library object with easyEMG emg(EASYEMG_I2C_ADDR_ALT);.

Wiring

Option 1 — Qwiic (solderless)

Connect a Qwiic / STEMMA QT cable from your board’s Qwiic port to either port on easyEMG. That’s all: the cable carries power, ground, SDA and SCL. The Qwiic port runs at 3.3 V.

Protocentral easyEMG connected by a Qwiic cable to a Qwiic port on an I²C shield, on an Arduino-format host board, with the electrode cable plugged into its 3.5 mm jack

On some boards the Qwiic port is a second I²C bus. On an Arduino UNO R4 WiFi, for example, it’s Wire1, so call emg.begin(Wire1); and Wire1.setClock(400000);.

Option 2 — I²C over the 0.1″ header

No Qwiic port? easyEMG needs only two I²C lines plus power and ground. Solder the included header and wire it up:

easyEMG pin Arduino Uno / Nano ESP32 (default I²C) Raspberry Pi Pico Raspberry Pi
VCC 5V 3.3V 3V3 OUT (pin 36) 3V3 (pin 1)
GND GND GND GND (pin 38) GND (pin 6)
SDA A4 GPIO21 GP4 (pin 6) GPIO2 (pin 3)
SCL A5 GPIO22 GP5 (pin 7) GPIO3 (pin 5)

SCL is the square pad. The header takes 3.3 – 5 V and has its own regulator and level shifting, so a 5 V Arduino can drive it directly. On the Pico and the Raspberry Pi, use the MicroPython driver rather than the Arduino library.

Through easyISO

For a mains-powered host, connect the host to the IN side of an easyISO and easyEMG to the OUT side. No code changes are needed. See the easyISO guide.

Placing the electrodes

Plug the cable into the 3.5 mm jack and snap a fresh electrode onto each lead. Each muscle uses the same three leads:

Lead Colour Jack contact Where it goes
E1 Green Sleeve On the belly of the muscle
E2 Red Ring On the belly of the muscle, next to E1 and in line with the muscle
REF Yellow Tip On a bone close to the muscle, with no muscle under it

Start with the biceps. It’s the largest muscle here and the easiest to load, so it should give the clearest bursts. Move on to the forearm once you’ve seen a good signal.

Biceps

Electrode placement on the biceps, shown on the left arm from the front: E1 and E2 one above the other on the fullest part of the biceps, in line with the arm, and REF on the bony point on the inner side of the elbow

  1. Sit with your elbow bent to about 90° and your forearm resting on a table.
  2. Press your palm up against the underside of the table and feel for the fullest part of the biceps. It’s about a third of the way up from the elbow crease towards the shoulder.
  3. Put E1 and E2 on that spot, one above the other, in line with the arm. Keep the pads close together without overlapping.
  4. Put REF on the bony point on the inner side of your elbow.

To test it: rest for five seconds, then curl a water bottle or press up against the table for five seconds. Repeat a few times. The raw trace should burst when you lift, and settle when you stop.

Forearm

Electrode placement on the forearm flexors, shown on the left forearm from the front: E1 and E2 on the inner forearm about a third of the way down from the elbow, and REF on the bony knob on the little-finger side of the wrist

  1. Rest your forearm on a table, palm up.
  2. Clench your fist and feel for the muscle that bulges on the inner forearm, about a third of the way down from the elbow crease towards the wrist.
  3. Put E1 and E2 on that bulge, in a line running from the inner elbow towards the middle of the wrist. Keep the pads close together without overlapping.
  4. Put REF on the bony knob on the little-finger side of your wrist.

To test it: rest for five seconds, then clench your fist for five seconds. Repeat a few times. Several muscles sit close together here, so moving your fingers or wrist changes the signal too. That’s normal.

Getting a clean signal

  • Wipe the skin with alcohol and let it dry before you stick anything on.
  • Give the gel a minute or two to settle.
  • Press REF firmly onto the bone. Most noisy traces come down to electrode contact.
  • Tape the cable to your arm, so it can’t tug on the snaps when you move.
  • Keep your arm still and supported between contractions, and relax fully when you zero the baseline.
  • Re-zero with calibrateBaseline() each time you move the electrodes.

Installing the library

  1. In the Arduino IDE, open Tools → Manage Libraries.
  2. Search for ProtoCentral easyEMG and click Install.

Or download the library from GitHub and use Sketch → Include Library → Add .ZIP Library. It has no other dependencies.

Your first sketch

#include <Wire.h>
#include "ProtoCentral_easyEMG.h"

easyEMG emg;

void setup() {
    Serial.begin(115200);

    if (!emg.begin()) {
        Serial.println("easyEMG not found - check wiring and I2C address (0x48).");
        while (1) delay(1000);
    }
    Wire.setClock(400000);

    // Relax the muscle for this: it zeroes the resting offset.
    emg.calibrateBaseline();
    emg.setEnvelopeWindow(64);
}

void loop() {
    float envelope = emg.readEnvelope();   // uV RMS: "how hard is this muscle working"

    Serial.print("Raw_uV:");
    Serial.print(emg.lastMicrovolts(), 1);
    Serial.print(",Envelope_uV:");
    Serial.println(envelope, 1);
}

Disconnect the charger if you’re on a laptop, upload the sketch with the muscle relaxed, then open Tools → Serial Plotter at 115200 baud.

Reading the trace

At rest you should see a small, fuzzy trace close to zero. Clench your fist or flex the muscle and the raw trace bursts, while the envelope rises and falls with your effort.

As a rough guide, in µV RMS at the electrodes:

Condition Envelope
Good electrodes, relaxed 5 – 15
Light contraction About 100
Strong contraction About 1000

Absolute microvolts use the design gain of ×51.7. Activation thresholds set from your own noise floor and %MVC are ratios, so they don’t depend on it.

Sample rate

easyEMG has no data-ready pin, so the rate is set by how fast your host polls I²C. A rate of fs only captures signal up to fs / 2, and the analog band runs to about 310 Hz. For the whole band, use a 32-bit board and call Wire.setClock(400000). An 8-bit Arduino or a Python host runs slower, which narrows the usable band, though the envelope still tracks effort. 04.EnvelopeRMS and 07.Diagnostics print your own rate.

The envelope window is counted in samples, so it depends on that rate. Aim for 50 – 200 ms, and use envelopeWindowMillis() to convert.

Mains hum

There’s deliberately no 50/60 Hz notch in hardware, because mains sits inside the EMG band and removing it costs real signal. Fix the cause first: fresh electrodes, REF on bone, and a host that isn’t on mains. Even on a battery-powered laptop, room lighting can put hum on the body at two and three times the mains frequency (100 and 150 Hz on 50 Hz mains) rather than at the mains frequency itself.

If you still need it, the library notches it in software. setNotch() removes the fundamental only. setMainsNotch() notches every harmonic up to 0.45 times the sample rate (450 Hz at 1000 SPS), 6 Hz wide at 50/60 Hz and 2 Hz wide on the rest, and 06.OpenView uses it by default. Both need your exact sample rate and a paced loop, as 06.OpenView and 07.Diagnostics show.

Seeing it in OpenView

OpenView is our desktop app for live plotting and recording. It shows the raw sEMG and its RMS envelope as two strips, in µV at the electrodes, with your effort as a percentage of your maximum contraction beside them.

  1. Install OpenView 3.4 or later. Earlier versions have no easyEMG profile and can’t read this stream. Keep your laptop on battery with the charger unplugged.
  2. Open File → Examples → ProtoCentral easyEMG → 06.OpenView. Its mains notch is set for 50 Hz, so change MAINS_HZ to 60 if that’s your mains frequency. Upload it.
  3. Close any Serial Monitor or Serial Plotter window, because they hold the port.
  4. In OpenView, open Connect, choose USB and select easyEMG Breakout.
  5. Record your maximum contraction: see Effort and your MVC below. The sketch also runs this step by itself after every reset, and opening the serial port resets some boards, so relax as you connect.

Effort and your MVC

Microvolts vary from person to person, muscle to muscle and even with where you stick the pads, so a raw envelope can’t tell you how hard you’re working. Effort can. It’s your envelope as a percentage of your maximum voluntary contraction (MVC), the strongest contraction you can make:

Effort (%MVC) = envelope ÷ MVC × 100

The envelope here is the one OpenView plots: the RMS of the last 128 ms of signal, smoothed over about 120 ms. The MVC is the highest value of that same envelope while you contract as hard as you can. Relaxed reads a few percent; a strong contraction reads close to 100.

Recording it

The MVC tile in OpenView walks you through it, and the board’s LED shows the same steps:

Step MVC tile LED What to do
1 Relax… Off Keep the muscle relaxed for 2 seconds. The filters settle, and the last second is measured as your resting level
2 Contract hard now On Contract as hard as you can and hold it until the LED goes out, 5 seconds later
3 Recorded Off Done. Effort now reads against this MVC
Recording an MVC in OpenView: Relax…, then Contract hard now for 5 seconds, then Recorded. Effort then reads against that MVC and falls back as the arm relaxes.

Press Record MVC in OpenView to run it again at any time. The button sends the character m to the board, so typing m in the Serial Monitor does the same when OpenView isn’t connected.

To get a good MVC:

  • Hold against something that doesn’t move. For the forearm, grip a rolled towel or push your palm up against the underside of a table. Contracting against resistance without moving the joint (an isometric contraction) gives the strongest, steadiest signal, and movement adds artefact.
  • Build up over the first second, then hold. The highest point counts, so there’s no need to jerk.
  • Record it again whenever you move or replace the electrodes. The MVC belongs to that placement on that muscle, so compare effort within a session, not between days.

When an MVC is refused

A reference taken from a relaxed or barely tensed muscle would make every later reading several hundred percent. So the sketch refuses an MVC that’s below 100 µV or below 5 times your resting level. The tile shows Too weak: try again, the LED blinks for 2 seconds, and the previous MVC stays in use. Until one is recorded, the tile reads Not recorded and effort reads 0%.

With MVC_AUTO_RAISE on, the default, a later contraction that’s stronger than your MVC becomes the new MVC, so effort never goes over 100% and a weak reference corrects itself on your first hard contraction. A movement artefact that big would raise it too. For measurements, set MVC_AUTO_RAISE to false and record the MVC carefully. If effort ever reads over 100%, OpenView shows it in amber with Above your MVC: record it again.

Settings

Change these at the top of 06.OpenView:

Setting Default What it does
RECORD_MVC true Run the MVC step after every reset
MVC_SETTLE_MS 2000 Relax time before the LED lights; the last second sets the resting level
MVC_RECORD_MS 5000 How long the LED stays lit for the contraction
MVC_MIN_UV 100 Smallest MVC accepted, in µV
MVC_MIN_REST_RATIO 5 Smallest MVC accepted, as a multiple of the resting level
MVC_AUTO_RAISE true Let a stronger contraction become the new MVC
MVC_COMMAND 'm' Character that runs the step again

In your own sketch, record the peak envelope yourself, pass it to setMVC() in µV, and read effort with readPercentMVC(), as 04.EnvelopeRMS does. That example takes a simple 5-second peak, without the resting check.

Other examples

Find these under File → Examples → ProtoCentral easyEMG:

Example What it does
01.BasicReading Raw counts and microvolts
02.SerialPlotter Muscle activity in the Serial Plotter
03.Calibration Baseline zeroing and your resting noise floor
04.EnvelopeRMS RMS envelope, MVC recording, %MVC and a live sample-rate readout
05.MuscleActivation_LED Flex to light an LED, with an auto-set threshold
06.OpenView Streams to the OpenView desktop app (3.4 or later); select the easyEMG Breakout profile
07.Diagnostics I²C scan, config read-back, ADC check, sample rate and a notch comparison

Troubleshooting

Start with 07.Diagnostics. Flat, noisy and dead traces can look alike, and this sketch tells them apart.

Symptom Likely cause What to try
“easyEMG not found” Wiring, or a different address Check the cable and run 07.Diagnostics. The board ships at 0x48
No EMG, trace pinned Mains-powered host Unplug the charger, or use an easyISO
Huge signal that rails the ADC Electrode not attached Floating inputs act as antennas. Check all three snaps and pads
Noisy trace, small envelope change Electrode contact Use fresh pads, alcohol-wiped dry skin, and REF firmly on bone
Mains hum that a notch doesn’t remove Unpaced sampling The notch needs your exact rate. See 07.Diagnostics
Effort far above 100%, or MVC tile says Too weak MVC recorded from a relaxed or barely tensed muscle Press Record MVC, relax for 2 s, then contract as hard as you can while the LED is lit
Effort stays at 0% No MVC recorded yet Press Record MVC, or reset the board and follow the LED
Large, steady reading that never varies Stale baseline Relax, then call calibrateBaseline() again after every electrode change

Where next