Overview
The AD8232 ECG Module is a low-power, single-lead heart rate monitor front end built around Analog Devices' AD8232 integrated signal conditioning block. It amplifies, filters, and cleans up the tiny bioelectric signals your heart produces — typically in the millivolt range — so your microcontroller's analog input can read them directly. The result is a clean, Arduino-friendly ECG waveform that you can plot, log, or stream over Wi-Fi.
This module runs on 3.3V and draws under 200 uA, making it an excellent fit for battery-powered wearables and fitness monitors. Three electrode pads — Right Arm (RA), Left Arm (LA), and Right Leg (RL) — connect via a 3.5 mm audio jack on the board and a standard sensor cable. On-board Leads-Off detection (LO+ / LO-) tells your code when an electrode falls off so you can pause the waveform cleanly.
The AD8232 is the go-to sensor for DIY ECG monitors, biomedical prototyping courses, and HRV (heart-rate variability) experiments. It pairs nicely with Arduino for serial plotting, ESP32 for Wi-Fi dashboards, and Raspberry Pi for more advanced DSP work.
At a Glance
Specifications
| Parameter | Value |
| IC | Analog Devices AD8232 |
| Operating Voltage | 3.3V (2.0V - 3.5V supported by IC) |
| Supply Current | 170 uA (typical) |
| Output Type | Single-ended analog, rail-to-rail |
| Output Reference (VREF) | ~1.65V (mid-supply bias) |
| Gain | ~100 V/V (with on-board filter network) |
| Frequency Response | ~0.5 Hz - 40 Hz (heart-rate band) |
| Common-Mode Rejection | 80 dB (DC to 60 Hz) |
| Electrode Connection | 3.5 mm TRS audio jack (RA, LA, RL) |
| Leads-Off Detection | Digital LO+ and LO- outputs (active HIGH when detached) |
| SDN (Shutdown) | Active LOW — tie HIGH for normal operation |
| Operating Temperature | -40 to +85 C |
| Dimensions | 36 x 33 mm (typical breakout) |
Pinout Diagram
The AD8232 module has nine labelled pins. Left header (pins 1-6) — microcontroller side: GND, 3.3V (power in), OUTPUT (analog ECG waveform), LO- and LO+ (leads-off detection outputs), and SDN (shutdown, active LOW). Top header (pins 7-9) — electrode side: RL (Right Leg, driven reference), LA (Left Arm), RA (Right Arm). These three electrode lines are also broken out on the on-board 3.5 mm audio jack so you can plug in a standard pre-terminated electrode cable. For a basic read you only need 4 wires to your MCU: GND, 3.3V, OUTPUT, and (optionally) LO+ for leads-off.
Wiring Guide
Arduino Wiring
On an Arduino Uno or Nano, power the AD8232 from the 3.3V pin — never 5V. The OUTPUT pin is analog, so connect it to any analog input (A0 is the standard choice). LO+ and LO- are digital flags for leads-off detection.
| AD8232 Pin | Arduino Pin |
|---|---|
| GND | GND |
| 3.3V | 3.3V |
| OUTPUT | A0 |
| LO- | Digital Pin 11 |
| LO+ | Digital Pin 10 |
| SDN | Leave open (pulled HIGH on board) |
ESP32 Wiring
The ESP32 is a natural fit for the AD8232 — both run at 3.3V, so you can wire OUTPUT directly to an ADC-capable GPIO. Use one of the ADC1 channels (GPIO 32-39), because ADC2 is reserved when Wi-Fi is active.
| AD8232 Pin | ESP32 Pin |
|---|---|
| GND | GND |
| 3.3V | 3.3V |
| OUTPUT | GPIO 34 (ADC1_CH6) |
| LO- | GPIO 32 |
| LO+ | GPIO 33 |
| SDN | Leave open or tie to 3.3V |
Raspberry Pi Wiring
The Raspberry Pi has no built-in analog input, so you'll need an external ADC (like the MCP3008 over SPI) to read the AD8232's OUTPUT pin. Power the AD8232 from the Pi's 3.3V rail and share GND with both the Pi and the ADC.
| AD8232 Pin | Raspberry Pi Pin |
|---|---|
| GND | Pin 6 (GND) |
| 3.3V | Pin 1 (3.3V) |
| OUTPUT | MCP3008 CH0 (via SPI) |
| LO- | Pin 11 (GPIO 17) |
| LO+ | Pin 13 (GPIO 27) |
| SDN | Leave open |
sudo raspi-config (Interface Options > SPI) before running the Python example. You'll need an MCP3008 (or similar) ADC because the Raspberry Pi does not have any native analog input pins.
Raspberry Pi Pico Wiring
The Pico has three analog inputs (GP26, GP27, GP28) that are perfect for reading the AD8232's output. Power the module from the Pico's 3V3 pin.
| AD8232 Pin | Pico Pin |
|---|---|
| GND | GND |
| 3.3V | 3V3 (Pin 36) |
| OUTPUT | GP26 / ADC0 (Pin 31) |
| LO- | GP15 (Pin 20) |
| LO+ | GP14 (Pin 19) |
| SDN | Leave open |
Code Examples
Arduino
// AD8232 ECG Module - Arduino Example
// Prints raw ECG samples for the Arduino Serial Plotter.
// OUTPUT -> A0, LO+ -> D10, LO- -> D11
const int OUTPUT_PIN = A0;
const int LO_PLUS = 10;
const int LO_MINUS = 11;
void setup() {
Serial.begin(9600);
pinMode(LO_PLUS, INPUT);
pinMode(LO_MINUS, INPUT);
}
void loop() {
// Leads-off detection: either line goes HIGH when an electrode is disconnected
if (digitalRead(LO_PLUS) == HIGH || digitalRead(LO_MINUS) == HIGH) {
Serial.println(0); // Plot a flat line while leads are off
} else {
int ecg = analogRead(OUTPUT_PIN); // 0 - 1023 on Arduino
Serial.println(ecg);
}
// ~200 Hz sample rate
delay(5);
}
Raspberry Pi (Python)
#!/usr/bin/env python3
# AD8232 ECG Module - Raspberry Pi Example (via MCP3008 ADC)
# Install: pip3 install spidev gpiozero
# AD8232 OUTPUT -> MCP3008 CH0
# LO+ -> GPIO 27, LO- -> GPIO 17
import spidev
import time
from gpiozero import DigitalInputDevice
LO_PLUS = DigitalInputDevice(27)
LO_MINUS = DigitalInputDevice(17)
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 1_350_000
def read_adc(channel):
# MCP3008 single-ended read
r = spi.xfer2([1, (8 + channel) << 4, 0])
return ((r[1] & 3) << 8) | r[2]
print("AD8232 ECG Demo (Ctrl+C to stop)")
try:
while True:
if LO_PLUS.value or LO_MINUS.value:
print(0) # leads off
else:
ecg = read_adc(0) # 0 - 1023
print(ecg)
time.sleep(0.005) # ~200 Hz
except KeyboardInterrupt:
print("\nStopped by user")
finally:
spi.close()
Raspberry Pi Pico (MicroPython)
# AD8232 ECG Module - Pico MicroPython Example
# OUTPUT -> GP26 (ADC0), LO+ -> GP14, LO- -> GP15
from machine import ADC, Pin
import time
ecg = ADC(Pin(26))
lo_plus = Pin(14, Pin.IN)
lo_minus = Pin(15, Pin.IN)
print("AD8232 ECG Demo")
while True:
if lo_plus.value() or lo_minus.value():
print(0) # leads off
else:
raw = ecg.read_u16() # 0 - 65535
print(raw >> 4) # scale down to 0 - 4095 (12-bit)
time.sleep_ms(5) # ~200 Hz
ESP32 (MicroPython)
# AD8232 ECG Module - ESP32 MicroPython Example
# OUTPUT -> GPIO 34 (ADC1_CH6), LO+ -> GPIO 33, LO- -> GPIO 32
from machine import ADC, Pin
import time
ecg = ADC(Pin(34))
ecg.atten(ADC.ATTN_11DB) # read full 0 - 3.3V range
ecg.width(ADC.WIDTH_12BIT) # 0 - 4095
lo_plus = Pin(33, Pin.IN)
lo_minus = Pin(32, Pin.IN)
print("AD8232 ECG Demo")
while True:
if lo_plus.value() or lo_minus.value():
print(0) # leads off
else:
print(ecg.read()) # 0 - 4095
time.sleep_ms(5) # ~200 Hz