This is the MAX30001 library for Arduino. It attempts to be complete and supports impedance spectroscopy.
This library has been validated for ECG, continuous BIOZ, combined ECG+BIOZ, internal calibration paths, and the refactored nonblocking BIOZ scan flow that is driven through setup...(), start(), and repeated update().
Impedance Spectroscopy: Internal 1 kOhm resistor scan validation working across the full 128 kHz down to 125 Hz scan range. External known-load validation is still required before calling library production ready.
Installation
Install the library in Arduino IDE or clone the GitHub repository into your Arduino libraries folder.
Dependencies
This driver depends on
Quick Start
Using Arduino-style setup() / loop() with setup + start/update/stop:
#include <Arduino.h>
#include "logger.h"
const uint8_t AFE_CS_PIN = 10;
const int AFE_INT1_PIN = 2;
const int AFE_INT2_PIN = -1;
MAX30001G afe(AFE_CS_PIN, AFE_INT1_PIN, AFE_INT2_PIN);
bool measurementRunning = false;
void setup() {
currentLogLevel = LOG_LEVEL_DEBUG;
Serial.begin(115200);
afe.begin();
afe.setupECGandBIOZ(
1, 2, true,
0, 1,
1, 0,
8000, 8000, 0.0,
true, false, false
);
}
void loop() {
bool userRequestedStart = false;
bool userRequestedStop = false;
if (userRequestedStart && !measurementRunning) {
afe.start();
measurementRunning = true;
}
if (userRequestedStop && measurementRunning) {
afe.stop();
measurementRunning = false;
}
if (!measurementRunning) {
return;
}
if (afe.update()) {
float value = 0.0f;
Serial.print("ECG [mV]: ");
Serial.println(value, 3);
}
Serial.print("BIOZ [ohm]: ");
Serial.println(value, 3);
}
Serial.print("RR [ms]: ");
Serial.println(value, 1);
if (value > 0.0f) {
Serial.print("HR [bpm]: ");
Serial.println(60000.0f / value, 1);
}
}
}
}
MAX30001G device driver class used by Arduino sketches.
Definition: max30001g.h:34
RingBuffer< float, 16 > RTOR_data
Definition: max30001g_globals.cpp:15
RingBuffer< float, 128 > BIOZ_data
Definition: max30001g_globals.cpp:14
RingBuffer< float, 128 > ECG_data
Definition: max30001g_globals.cpp:13
BIOZ spectroscopy uses the same configure/start/update lifecycle, but setupBIOZScan(...) only configures the scan. Call start() once, then keep calling update() until a spectrum becomes available in BIOZ_spectrum.
Main Sketch
The sketch that reflects the latest driver organization most closely is examples/MAX30001G/MAX30001G.ino.
It is an interactive serial utility for exercising the current driver layers, switching modes, applying settings, running health checks, and validating scan/calibration flows from one sketch.
When you open the serial monitor and type ?, the sketch prints this help menu:
================================================================================
| MAX30001G ECG and Bio-Impedance Program |
| 2026 Urs Utzinger & GPT |
================================================================================
| GENERAL COMMANDS | DATA COMMANDS |
|----------------------------------------|-------------------------------------|
| ?: help screen | z: toggle data display on/off |
| s: show current settings | c: reset sample counter |
| h: run health check | (: save config snapshot |
| i: print device info | ): restore config snapshot |
| r: print all registers | p: print config registers |
| t: print status registers | f: FIFO reset |
|========================================|=====================================|
| OPERATION MODES (auto-stop previous) | START/STOP |
|----------------------------------------|-------------------------------------|
| m1: ECG mode | .: toggle start/stop |
| m2: BIOZ mode | >: start measurement |
| m3: ECG + BIOZ mode | <: stop measurement |
| m4: ECG calibration | |
| m5: BIOZ calibration | |
| m6: BIOZ internal cal | |
| m7: BIOZ external cal | |
| m8: BIOZ scan | |
|========================================|=====================================|
| ECG SETTINGS | BIOZ SETTINGS |
|----------------------------------------|-------------------------------------|
| Es<n>: speed (0-2) Es1 | Bs<n>: speed (0-1) Bs0 |
| Eg<n>: gain (0-3) Eg2 | Bg<n>: gain (0-3) Bg1 |
| El<n>: leads (2 or 3) El3 | Ba<n>: analog HPF (0-7) Ba1 |
| Er<n>: R-to-R (0=off,1) Er1 | Bd<n>: digital LPF(0-3) Bd1 |
| | Bh<n>: digital HPF(0-3) Bh0 |
| | Bf<n>: frequency Hz Bf8000 |
| | Bc<n>: current nA Bc8000 |
| | Bp<n>: phase deg Bp0 |
| | Bl<n>: lead bias (0=off,1) Bl1 |
| | Bo<n>: lead-off (0=off,1) Bo0 |
| | Bw<n>: wires (2 or 4) Bw2 |
|========================================|=====================================|
| SCAN SETTINGS | CALIBRATION SETTINGS |
|----------------------------------------|-------------------------------------|
| Sa<n>: averages (1-8) Sa8 | Cr<n>: internal resistor Cr1000 |
| Sf<n>: fast mode (0=off,1) Sf0 | Cm<n>: cal modulation(0-3) Cm0 |
| Sr<n>: full range (0=off,1) Sr0 | Cf<n>: mod frequency(0-4) Cf3 |
| Si<n>: source (0=ext,1=int) Si0 | |
| Sp<n>: phase rng (0=full,1) Sp0 | |
| Sh<n>: int AHPF (255,0-7) Sh255 | |
| St<n>: settle (1-64) St24 | |
| Sc<n>: cur settle (1-64) Sc24 | |
|========================================|=====================================|
| LOG LEVEL | SPECIAL |
|----------------------------------------|-------------------------------------|
| l0: none (silent) | w: software reset |
| l1: errors only | y: synchronize |
| l2: warnings | k: clear latched status flags |
| l3: info (default) | a: apply current settings (re-setup)|
| l4: debug (verbose) | |
================================================================================
Examples:
m1 - Switch to ECG mode
Eg3 - Set ECG gain to 160 V/V (level 3)
Bf40000 - Set BIOZ frequency to 40 kHz
. - Start/stop measurement
z - Toggle continuous data display
Example Sketches
The maintained example sketches match the current driver structure:
examples/ECG/ECG.ino: continuous ECG using setupECG(...), start(), and repeated update()
examples/BIOZ/BIOZ.ino: continuous fixed-frequency BIOZ using setupBIOZ(...)
examples/ECGandBIOZ/ECGandBIOZ.ino: simultaneous ECG and BIOZ using setupECGandBIOZ(...)
examples/BIOZScan/BIOZScan.ino: external nonblocking BIOZ spectroscopy using setupBIOZScan(...)
examples/BIOZScan_Internal/BIOZScan_Internal.ino: internal-resistor scan validation using the same scan-owned state machine
examples/BIOZScan_Internal_Fast/BIOZScan_Internal_Fast.ino: fast reduced-phase internal-resistor full-spectrum validation
examples/Hardware_HealthCheck/Hardware_HealthCheck.ino: startup communication and hardware checks
examples/MAX30001G/MAX30001G.ino: interactive serial test program covering mode switches, setup helpers, calibration, scan control, and register inspection
examples/ECG_FIFOInterruptValidation/ECG_FIFOInterruptValidation.ino: ECG FIFO interrupt and ECG_data validation
examples/BIOZ_FIFOInterruptValidation/BIOZ_FIFOInterruptValidation.ino: BIOZ FIFO interrupt and BIOZ_data validation
examples/ECGandBIOZ_FIFOInterruptValidation/ECGandBIOZ_FIFOInterruptValidation.ino: combined FIFO drain validation
examples/BIOZ_Internal_ImpedanceCalibration/BIOZ_Internal_ImpedanceCalibration.ino: internal BIST point measurements outside the scan flow
examples/BIOZ_External_ImpedanceCalibration/BIOZ_External_ImpedanceCalibration.ino: external known-load impedance calibration
examples/BIOZ_SignalCalibration/BIOZ_SignalCalibration.ino and examples/ECG_SignalCalibration/ECG_SignalCalibration.ino: internal signal-generator calibration paths
Documentation
Hardware with MAX30001G
Contributing
- Urs Utzinger, 2025-2026
- GPT, 2025- 2026
License
See LICENSE.
Block Diagram of MAX 30001G
The MAX30001G is a highly integrated analog front end that consists of a differential ECG channel with optional right-leg drive. It employs standard high-pass and low-pass filters, an instrumentation amplifier, and an analog-to-digital converter.
The impedance unit consists of a current driver, analog high-pass filter, and phase-shifted demodulator to measure impedance from 128kHz down to 125Hz modulation frequency at varying phase shifts. Internal-BIST validation shows coherent full-spectrum scans with dynamic AHPF selection, but the low-frequency end still rolls off below about 1kHz and external known-load validation is still required for production scan calibration.
Input MUX ECG
Besides ESD protection, the input MUX can detect lead-off and lead-on conditions. In addition, it can switch input electrode polarity and correct common-voltage bias on the subject. Input can be turned off and replaced with an internal signal generator for testing purposes.
Input MUX BIOZ
Similar to the ECG input MUX, the BIOZ input MUX has ESD protection as well as lead-on and lead-off detection. Besides input signal calibration, a programmable resistor can be measured internally as simulated impedance.