Home

Guide no. 90

Three electrodes, an AD8232 module and Arduino UNO: the heart's trace on the Serial Plotter and an estimate of the heart rate. For learning, not for health checks.

By Ada Intelisano · informaticait.it technical team

Download the PDF (A4, 5 pages) Free to print and share, without changes — CC BY-ND 4.0
In short
  • The AD8232 amplifies and filters the heart's very weak electrical signal; Arduino reads it on A0.
  • It is not a medical device: no diagnosis, no health checks. If you have any concerns, see a doctor.
  • Electrodes on the body only with Arduino running on batteries or connected to a laptop with the charger unplugged.
  • The Serial Plotter draws the trace; the beats per minute it calculates are only an indication.
Time: one hourLevel: next stepsBefore: guides no. 21 and 36

With every beat the heart produces an electrical impulse that reaches the skin, very faint. The AD8232 amplifies it and cleans it up, and Arduino draws it on the Serial Plotter. It helps you understand how an electrocardiogram works, and nothing more.

First of all: safety
  • This is not a medical device. SparkFun and DFRobot say so on their module pages: it is not for diagnosis or treatment. So no checks on your health or anyone else's, and no reading the trace for signs about the heart: if in doubt, see a doctor. Analog Devices notes that real medical equipment follows specific safety standards.
  • Electrodes on the body only when everything runs on batteries: Arduino connected to a laptop with the charger unplugged, or to a 9 V battery. Never a desktop PC, never a laptop while it is charging, and no other cable to anything that is plugged into the mains (a monitor, a USB hub with its own power supply).
  • Why: with the gel, the electrodes make very good contact with the skin. With the circuit connected to the 230 V mains, usually nothing happens, but in rare cases a current loop forms through the mains, and the person wearing the electrodes is part of it. That is why SparkFun recommends a battery, and M5Stack prints on its ECG module that you should use an isolated power supply.
With the electrodes on: nothing connected to the mainsUNOAD8232electrodesunpluggedYes: laptop on batteryUNOAD8232electrodes230 V socketNo: plugged into the mainsinformaticait.it
With the electrodes on:nothing connected to the mainsUNOAD8232electrodesunpluggedYes: laptop on batteryUNOAD8232electrodes230 V socketNo: plugged into the mainsinformaticait.it

1The parts

  • the SparkFun SEN-12650 module, which comes without pins: solder a row of six pins into the holes from GND to SDN (guide no. 70). With it, the SparkFun CAB-12970 cable and three disposable electrodes;
  • or the AD8232 kit: same board and same pins, with the cable and electrodes in the box;
  • Arduino UNO with its USB cable, five female-to-male jumper wires, and a laptop that can run on its battery.

2How it works and how to wire it

This is a single-lead ECG: it measures the voltage between the right arm (RA) and the left arm (LA); the third electrode (RL, right leg) helps the AD8232 keep the noise down. The SparkFun board follows the Analog Devices “cardiac monitor” circuit: the signal is made 1100 times larger, and only frequencies between 0.5 and 40 Hz get through. OUTPUT swings around 1.65 V, which Arduino reads as about 340 (our calculation).

The wiring: five wires between the module and ArduinoSCLSDAAREFGND131211109876543210IOREFRESET3.3V5VGNDGNDVINDIGITAL (PWM ~)POWERANALOG INUNOAD8232ACPZGND3.3vOUTPUTLO-LO+SDNRLLARAAD8232Heart MonitorLEDsparkfun3.3VGNDA0 A1 A2RALARLto theelectrodesArduino UNOSparkFun SEN-12650 (AD8232)3.3v → 3.3VGND → GNDOUTPUT → A0LO+ → A1LO− → A2SDN stays freeinformaticait.it
  • 3.3v → 3.3V, never to 5V: the AD8232 works from 2 to 3.5 V and can take 3.6 V at most.
  • LO+ → A1, LO− → A2: they go up to 3.3 V when LA (LO+) or RA (LO−) comes off. A digital pin on the UNO is only sure to see a “high” from 3 V up (ATmega328P datasheet), so we read them with analogRead: about 675 (our calculation) with the electrode off, almost 0 with the electrode on.
  • SDN stays free (a resistor on the board keeps the chip on). Never connect it to a pin on the UNO: the UNO's 5 V is more than the chip can take.

3The sketch

// The heart's signal with the AD8232 and Arduino UNO. For learning only: this is NOT
// a medical device. Electrodes on the body only when everything runs on batteries.
#include <Arduino.h>

const bool HAS_LO = true;  // false for the DFRobot SEN0213 (LO+ and LO- not available)
const byte EVERY = 10;     // one line to the Plotter every 10 readings (IDE 1.8: use 1)
const int MARGIN = 100;    // how far the R peak must rise above the average (adjust it)

long sum;                  // moving average of the readings, multiplied by 64
unsigned long lastRead, lastBeat;
bool above = false;        // is the signal already above the threshold?
int bpm = 0, highest = 0;
byte counted = 0;

void setup() {
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);       // the L LED blinks at every beat
  sum = analogRead(A0) * 64L;
  lastRead = micros();
}

void loop() {
  if (micros() - lastRead < 4000) return;        // one reading every 4 ms
  lastRead += 4000;
  int value = analogRead(A0);                    // OUTPUT of the module
  sum += value - sum / 64;                       // the average follows the baseline
  int threshold = sum / 64 + MARGIN;
  unsigned long now = millis();
  // LO+ (A1) and LO- (A2): about 675 if an electrode is off, almost 0 if it is on
  if (HAS_LO && (analogRead(A1) > 400 || analogRead(A2) > 400)) {
    value = threshold = bpm = 0;                 // on the Plotter: flat line at zero
  } else if (!above && value > threshold) {      // R peak: one beat
    above = true;
    unsigned long interval = now - lastBeat;
    if (interval > 300) {                        // under 0.3 s it is not a new beat
      if (interval < 2000) bpm = 60000UL / interval;
      lastBeat = now;
    }
  } else if (value < threshold) {
    above = false;
  }
  digitalWrite(LED_BUILTIN, now - lastBeat < 100);   // on for 0.1 s
  // the highest reading of each group goes to the Plotter, so the R peak is not lost
  if (counted == 0 || value > highest) highest = value;
  if (++counted < EVERY) return;
  counted = 0;
  Serial.print(F("ECG:"));         Serial.print(highest);
  Serial.print(F(",Threshold:"));  Serial.print(threshold);
  Serial.print(F(",BPM:"));        Serial.println(bpm);
}

Arduino reads OUTPUT 250 times a second: above the threshold (the average plus MARGIN) there is an R peak and the L LED lights up. The Plotter gets one line every ten readings because the one in IDE 2, as its source code shows, displays only the last 50 lines: two seconds. With the old IDE 1.8 (500 lines), set EVERY = 1.

4Where the electrodes go

SparkFun gives two placements: forearms and right thigh (A) or chest near the shoulders and right side above the hip (B); the closer they are to the heart, the better. On the SparkFun cable RA is black, LA blue, RL red: other cables differ, so check the labels.

Where the electrodes go (SparkFun positions)RALARLRALARLA. forearms and right thighB. chest and right hipthe person faces you: their right is on your leftinformaticait.it
  • Snap the leads onto the electrodes before you stick them on.
  • Clean, dry skin: hair does not conduct.
  • New electrodes for every session: once used, they no longer make good contact.
  • Check that RA and LA are on the correct side of the heart.
  • Keep still and relaxed, and breathe normally.

5Watch the trace

Charger unplugged, sketch uploaded, electrodes on: open the Serial Plotter (Tools menu or the button at the top right) at 115200 baud.

One beat on the Plotter: P wave, QRS complex, T wavethresholdPRQST0.8 sexample: 60 ÷ 0.8 = 75 beats per minuteindicative shape, not a recordinginformaticait.it

The P wave is the impulse that starts in the atria. In the QRS complex, with the R peak, the ventricles pump the blood: it is the “beep” of hospital monitors, as SparkFun puts it. The T wave comes when they relax.

✓ What you should seeA tall, narrow peak at every beat, with the orange threshold just below the tips. The L LED on the Arduino and the LED in the heart on the SparkFun board blink in time.
If it doesn't work
  • Flat line at zero: an electrode has come off.
  • Messy trace: you are moving, tensing your muscles or breathing hard; try moving the electrodes a little.
  • Lots of dense noise: DFRobot suggests touching something metal (static electricity).

6Beats per minute: an exercise

One beat passes between two R peaks: 800 milliseconds make 60,000 ÷ 800 = 75 per minute. That is the calculation behind the BPM column (it ignores peaks closer than 0.3 s and gaps longer than 2 s). The threshold should sit halfway up the R peaks, above the T waves: lower or raise MARGIN until it does.

Warning
  • The number is only an indication: movement, tall T waves or an electrode coming loose throw it off. It is there to show how a heart rate is counted: do not compare it with a medical device and do not draw conclusions from it.

7The other modules

  • AD8232 kit: same board, same pins, same sketch. Unlabeled snaps? Use a multimeter: in the SparkFun schematic the plug tip is RL, the ring LA, the sleeve RA.
  • DFRobot SEN0213 (with cable and electrodes): 3.3 to 6 V, 5 V recommended. VCC to 5V, GND to GND, A to A0; LO+ and LO− are not on the connector, so HAS_LO = false.
M5Stack ECG Module13.2 (M034): it stacks under an M5Stack Core, not on an Arduino UNO. An STM32 already counts the beats and sends them over serial at 115200 bps; the part that touches the person is isolated. 5 V only; official example on GitHub (M5-ProductExampleCodes, Module/ECG). The safety rules stay the same.
Try it yourself
  • Compare placements A and B, then clench your fist.
  • With the 9 V battery, watch the L LED.
✓ What you learned
  • the AD8232 amplifies and filters the signal;
  • two R peaks give an estimate of the heart rate;
  • electrodes on the body only on batteries.
Sources: Analog Devices, AD8232 datasheet Rev. D · SparkFun, SEN-12650: product page, hookup guide, Eagle files v10; cable CAB-12970; MyoWare manual AT-04-001 · DFRobot, SEN0213 wiki · M5Stack, ECG Module13.2 · Arduino, Serial Plotter, analogRead(), arduino-serial-plotter-webapp 0.2.0 · Microchip, ATmega328P · informaticait guides no. 21, 36 and 70

Useful products

Other guides

All our guides →
Loading...
Back to top