Chips to Measure ECG and PPG with Temporal Correlation

By: Don Elloway

Abstract: Pulse Arrival Time (PAT) is a useful medical parameter which can be correlated to physical attributes like artery hardness and changes in blood presser. Accurate PAT measurements require good temporal correlation between Electrocardiography (ECG) and Photoplethysmography (PPG) data. This application note presents a two chip solution using the MAX30003 ECG analog front end and the MAX86171 PPG optical pulse oximeter.


To accurately measure pulse arrival time (PAT) using synchronized electrocardiography (ECG) and photoplethysmography (PPG) measurements, the two-chip solution described in this application note establishes a ±5µs temporal correlation between the ECG and PPG signals. This document discusses the hardware configuration and detailed register configuration settings that allow the two chips to acquire data synchronously. Also covered in detail is how to adjust for temporal-sampling offsets between the ECG and PPG data samples with respect to a selected ECG-filter group delay and PPG settling and integration times.

This two-chip solution uses the MAX30003 as the ECG analog front end (AFE) and the MAX86171 to optically obtain a PPG signal. The MAX30001 can also be used.

System Overview

Figure 1 shows the PAT measurement system, which consists of a 32,768Hz crystal input to the MAX30003 ECG AFE, a MAX86171 PPG with sampling triggered by a MAX30003 synchronization output pulse, and a microcomputer unit (MCU) to configure registers and read data from the FIFOs over a 3-wire SPI.

PAT measurement system.Figure 1. PAT measurement system.

To achieve system temporal synchronization, configure the MAX30003 interrupt registers to generate a synchronization pulse after each ECG sample is placed in its data FIFO. The MAX86171 wakes up with each ECG synchronization pulse and acquires a sample. After the PPG completes a measurement and sets its FIFO interrupt, the MCU reads the ECG and PPG FIFO data registers over the SPI. This process is repeated at the sample rate selected for the MAX30003 ECG.

Figure 2 shows the system timing. Although the MAX86171 internal timing is driven by its internal fast (10MHz) and slow (32kHz) clock signals, these clocks systematically reset each time a synchronization pulse wakes up the device. The one sigma clock jitter between the ECG sync out signal and the PPG clock system is measured at less than 300ns.

System timing.Figure 2. System timing.

Hardware Configuration

A single synchronization signal and the shared 3-wire SPI signals connect the ECG and PPG devices. Each device also has its own SPI chip-select signal from the MCU and a FIFO ready signal connected to the MCU. The MAX30003 FIFO interrupt signal uses INTB, and the synchronization output signal is setup on INTB2. Connecting the synchronization pulse to the MCU can be useful depending on how you set up the firmware. The MAX86171 has the synchronization signal connected to its TRIG input, and the FIFO interrupt signal is set up on INT1.

The MAX86171 is also configured for SPI communications by pulling the I2C_SPI pin high. For the scope of this application note, a single LED is driven by LED1_DRV, and the photodiode is connected to PD1_IN. Different LED and photodiode configurations can also be used but require different register configuration settings than the settings used here. Refer to the MAX30003 and MAX86171 data sheets for application-specific capacitor values. Figure 3 shows the hardware configuration, but power-supply decoupling caps are not shown in the circuit.

Hardware configuration.Figure 3. Hardware configuration.


The MAX30003 is a single-biopotential channel that provides ECG waveforms and detects heart rate.

The MAX30003 ECG AFE can be configured for different sample frequencies, signal gain, digital high- and low-pass filter corner frequencies, and input impedance. For this application note, the following parameters have been selected:

  • Sample Rate = 512sps
  • Gain = 20V/V
  • Digital high-pass filter (DHPF) = bypass
  • Digital low-pass filter (DLPF) = bypass
  • Input Impedance (RBIAS) = 100MΩ

Lead-on and lead-off detection are also disabled for simplicity.

ECG Measurement Considerations

The most important consideration in using the MAX30003 ECG AFE in a synchronized data-acquisition system is understanding how the digital filter-group delay affects the time delay associated with each data sample placed in the ECG FIFO. For each of the different sampling rates listed in Table 1, the digital filter-group delay is a set number of 32kHz clock cycles. The number of 32kHz clock cycles is also different depending on weather the DHPF is active or in bypass mode. Depending on what clock is selected, there is also a systematic delay of 1.003ms or 1.020ms associated with the ADC sampling when the FMSTR clock is configured for 32,768Hz or 32,000Hz, respectfully.

Table 1 lists the calculated ECG sample delays (tECG_DELAY). These delays are referenced to the falling edge of the synchronization pulse, which occurs immediately after an ECG sample is placed in the FIFO (30µs) and immediately before the ECG FIFO flag is set (15µs). In practice, these delays have a measured typical standard deviation of 3µs.

Table 1. ECG Sample Delay (tECG_DELAY)

DLPF Setting FMSTR CLOCK = 32000Hz FMSTR CLOCK = 32768Hz
500sps Delay (ms) 250sps
Delay (ms)
Delay (ms)
Delay (ms)
Delay (ms)
Delay (ms)
Delay (ms)
Delay (ms)
Bypass 21.333 92.333 39.833 106.333 20.839 90.172 38.906 103.844
40Hz 33.333 116.333 69.833 154.333 32.558 113.610 68.203 150.719
100Hz 33.333 116.333 X X 32.558 113.610 X X
150Hz 33.333 X X X 32.558 X X X

X = Setting not allowed.

The ECG time-delay values in Table 1 were determined and verified by generating an input pulse and then looking at the output data. To obtain a measurement accuracy greater than the sample rate, multiple sets of pulses can be generated that have an additional 5µs delay with respect to the ECG synchronization pulse. Using the data, a set of output data is constructed with 5µs time steps to calculate the time from the center of the input pulse to the center of the output pulse. This can be done for several pulse widths in each configuration. The standard deviation of the delay for different pulse-width measurements is less than 5µs for all ECG configurations.

Table 2 shows the data for an ECG sample rate of 512sps with the DLPF set to bypass. The input-pulse-center-to-output-pulse-center data is averaged to obtain the average delay of 20.839ms with a standard deviation of 4.1µs.

Table 2. ECG Pulse Delay Measurement Data

Input Pulse Width (µs) Input-Pulse-Center-to-Output-Pulse-Center Delay (ms)
100 20.835
500 20.834
1000 20.835
1953 20.842
3906 20.843
5859 20.844
7812 20.843
9765 20.842
15624 20.837

ECG Register Configuration

Table 3 lists the MAX30003 registers to configure to set up the ECG to generate the signaling for synchronous operation with the MAX86171. Any registers not listed are assumed to be in their default state after a software reset.

If the state of the registers is unknown, send a software reset before configuring the registers. For the MAX30003, write 0x000000 to register 0x08 (SW_RST).

To start the ECG data sampling, there are three register commands that must be sent after the PPG has been configured. See the Startup Sequence section for more details.

Table 3. ECG Register Configuration

Address Data Configuration Description
0x02 0x800001 EN_EINT = 1b Set INTB to EINT (ECG FIFO Interrupt)
INTB_TYPE = 01b CMOS driver
0x03 0x000201 SAMP = 1b Set INTB2 to Sync pulse out.
INTB2_TYPE = 01b CMOS driver
0x04 0x000000; EFIT = 0000b FIFO interrupt when one word in FIFO
SAMP_IT = 00b Generate one sync pulse for each data sample
0x10 0x000007 FMSTR = 00b Master clock frequency set to 32768Hz
EN_ECG = 0b Disable ECG (this bit starts the ECG sampling when set)
RBIASP = 1b ECGP is connected to VMID through RBIAS
RBIASN = 1b ECGN is connected to VMID through RBIAS
0x14 0x000000 OPENP = 0b Close ECGP mux switch
OPENN = 0b Close ECGN mux switch


0x000000 RATE** = 00b Sample at 512sps
GAIN = 00b Gain set to 20V/V
DHPF = 0b Digital high-pass filter set to bypass
DLPF = 00b Digital low-pass filter set to bypass

*The settings for register 0x15 differ depending on the sample rate, gain, and filter settings chosen.
**The MAX30001 uses the bits ECG_RATE[1:0] and the MAX30003 uses the bits RATE[1:0] for this configuration.


The MAX86171 optical pulse oximeter is an ultra-low-power, dual channel, optical data-acquisition system with 9 LED drive outputs. In addition, two independent 19.5-bit ADCs utilize internal ambient-light cancelation circuitry, which is ideal for measuring PPG.

In this application note, the MAX86171 is configured to sample each time a falling edge occurs at the TRIG input pin. When in external trigger mode, the MAX86171 measurement circuity is in sleep mode until a trigger input is received. When a trigger occurs, the device wakes up, takes a measurement, puts the data in the FIFO, generates an interrupt, and then goes back to sleep.

The MAX86171 measurement circuity does not need to be awake while communicating over SPI.

PPG Measurement Considerations

The MAX86171 PPG is configured to wake up and acquire a sample after each synchronization pulse is generated by the ECG. A random clock jitter occurs between the ECG and PPG because the internal clocks of the PPG run asynchronously to the 32,768Hz crystal that drives the ECG. This clock jitter between the ECG and PPG has been measured to be less than ±0.3µs. The clock jitter is systematically related to the start of the PPG 10MHz fast clock after the ECG synchronization pulse triggers the PPG to wake up and is typically less than two PPG fast-clock cycles or 0.2µs.

In central difference mode (CDM), the PPG reads the ambient background light immediately before and after the LED measurement. The average of these two ambient light measurements is subtracted from the LED measurement.

The PPG expected time delay (tPPG_DELAY) is the time between the falling edge of the ECG synchronization trigger pulse and the center of the LED integration time. The PPG internal clocks have a maximum accuracy error of less than 1%. So if the maximum tPPG_DELAY is 526µs, the maximum accuracy error is 5.26µs. The actual error varies from device to device and, if desired, can be measured and corrected to be 0.2% accurate using the FR_Clock_Frequency_Select (0x15) register settings. When properly tuned, the maximum error during the longest integration setting is less than 1.1µs. Figure 4 shows the tPPG_DELAY timing.

tPPG_DELAY timing.Figure 4. tPPG_DELAY timing.

Table 4 shows the tPPG_DELAY for each possible combination of LED settling and LED integration times. The times are based on the required number of internal fast and slow clock cycles by the internal PPG state machine for measuring, and a clock accuracy of 0% error is assumed. In this application note, only the registers for measurement 1 are used, and the pulse width is the sum of the settling time and the integration time set by the MEAS1 configuration registers. The register (0x19) MEAS1_Configuration_1 is used to configure the integration time, MEAS1_TINT, and the register (0x1B) MEAS1_Configuration_3 is used to configure the settling time, MEAS1_LED_SETLNG.

Table 4. PPG Expected Time Delay (tPPG_DELAY)

Measurement 1 Configuration Register Settings Settling Time (µs) Integration Time (µs) Pulse Width (µs) tPPG_Delay (µs)
(0x1B) Meas1 Configuration 3 (0x19) Meas1 Configuration 1
0x00 0x00 6 14.6 20.6 354
0x00 0x08 6 29.2 35.2 377
0x00 0x10 6 58.6 64.6 420
0x00 0x18 6 117.1 123.1 508
0x50 0x00 12 14.6 26.6 360
0x50 0x08 12 29.2 41.2 383
0x50 0x10 12 58.6 70.6 426
0x50 0x18 12 117.1 129.1 514
0xA0 0x00 18 14.6 32.6 366
0xA0 0x08 18 29.2 47.2 388
0xA0 0x10 18 58.6 76.6 432
0xA0 0x18 18 117.1 135.1 520
0xF0 0x00 24 14.6 38.6 372
0xF0 0x08 24 29.2 53.2 364
0xF0 0x10 24 58.6 82.6 438
0xF0 0x18 24 117.1 141.1 526

PPG Register Configuration

Table 5 lists the MAX86171 registers to configure to properly slave the MAX86171 to the MAX30003 synchronization pulse with minimum ECG-to-PPG sample time jitter. Any registers not listed are assumed to be in their default state after a software reset.

If the state of the registers is unknown, send a software reset before configuring the registers by writing 0x01 to register 0x0C (System Configuration).

Table 5. PPG Register Configuration

Address Data Configuration Description
0x09 0xFF FIFO_A_FULL = 0xFF Set for FIFO full flag when there is one byte in the FIFO
0x0A 0x18 FLUSH_FIFO = 1b Reset PPG FIFO
FIFO_STAT_CLR = 1b Clear FIFO full flag on FIFO data read

AND with 0xCF

OR with 0x1A
Clear SYNC_MODE by ANDing with 0xCF, leave all other bits in the previous state, and then set the following bits.  
SYNC_MODE = 01b Sync on external pulse
PPG2_PWRDN = 1b Power down Optical Channel 2
SHDN = 1b Set PPG in shutdown mode
0x0D 0x01 MEAS1_EN = 1b Enable Measurement 1
0x0E 0x00 ALC_Disable = 0b ALC (ambient light correction) is enabled
COLLECT_RAW_DATA = 0b Do not collect dark current
MEAS1_CONFIG_SEL = 0b MEAS1 used only for MEAS1, not MEAS2 thru MEAS9
0x0F 0x55 PD4_BIAS = 01b
PD3_BIAS = 01b
PD2_BIAS = 01b
PD1_BIAS = 01b
Set all photodiode bias to a range of 0pF to 125pF (POR default)
0x10 0x00 INT2_FCFG = 00b Disable INT2
TRIG_ICFG = 0b Set TRIG input triggers on falling edge
0x11 0x04 INT2_OCFG = 00b Set INT2 output to open drain
INT1_OCFG = 10b Set INT1 output to Active Low and Drive High when not active
0x15 0x20 FR_CLK_SEL = 1b Set the internal frame clock to 32768Hz
FR_CLK_FINE_TUNE = 00000b Set clock trim to 0%
0x18 0x10 MEAS1_AMB = 0b Turn off ambient measurement
MEAS1_DRVC = 01b Select LED3_DRV pin for LED Driver C
MEAS1_DRVB = 00b Select LED2_DRV pin for LED Driver B
MEAS1_DRVA = 00b Select LED1_DRV pin for LED Driver A
0x19 0x00 MEAS1_PPG2_PDSEL = 0b Set PD2_IN input on optical channel 2
MEAS1_PPG1_PDSEL = 0b Set PD1_IN input on optical channel 1
MEAS1_TINT = 00b Set Measure 1 integration time to 14.6µs
MEAS1_AVER = 000b Set Measure 1 average to one sample (no averaging)
0x1A 0x0F MEAS1_SINC3_SEL = 0b Use COI3 decimation filter. Turn off SINC3 filter.
MEAS1_FILT_SEL = 0b Set ambient light rejection to central difference method
MEAS1_LED_RGE = 00b Set LED current range for 0mA to 32mA
MEAS1_PPG2_ADC_RGE = 11b Set PD2 Range to 32µA full scale
MEAS1_PPG1_ADC_RGE = 11b Set PD1 Range to 32µA full scale
0x1B 0x50 MEAS1_PD_SETLNG = 01b Set 12µs photodiode settling time
MEAS1_LED_SETLNG = 01b Set 12µs LED settling time
PPG2_DACOFF = 00b PPG2 DAC offset current set to 0
PPG1_DACOFF = 00b PPG1 DAC offset current set to 0
0x1C 0x20 MEAS1_DRVA_PA = 0x20 Set Drive A current to 4mA
0x1D 0x00 MEAS1_DRVB_PA = 0x00 Set Drive B current to 0mA
0x1E 0x00 MEAS1_DRVC_PA = 0x00 Set Drive C current to 0mA
0x78 0x80 A_FULL_EN1 = 1b Enable A_FULL_EN status bit to be output on INT1. When A_FULL_BIT is asserted, INT1 is activated.

Startup Sequence

After configuring the MAX30003 and MAX86171 for synchronized data acquisition, perform the following steps each time the system data acquisition starts to ensure proper temporal correlation between the ECG and PPG data sets:

  1. Reset PPG FIFO.
  2. Take PPG out of shutdown mode. The PPG is configured to take a sample each time a synchronization pulse is received from the ECG and waits for the first ECG synchronization pulse to occur.
  3. Before starting the ECG, perform the following:
    1. Send an ECG SYNCH command to the SYNCH (0x09) register to resynchronize all ECG internal timing.
    2. Send a reset command to the FIFO_RST (0x0A) register to reset the ECG FIFO.
  4. Set the ECG_EN bit in the ECG CNFG_GEN (0x10) register. Immediately after this bit is set, the ECG starts sampling at the data rate that is set in the CNFG_ECG (0x15) register.

PPG Startup

Before starting the ECG, use the commands in Table 6 to set the PPG to sample after each ECG synchronization pulse.

Table 6. PPG Startup Register Command Sequence

Address Data Comment
0x0A OR with 0x10 Set FLUSH_FIFO = 1b to reset the PPG FIFO.
0x0C AND with 0xFD Clear the SHDN bit to take the PPG out of shutdown mode.

ECG Startup

After the PPG startup commands are sent, start ECG sampling using the commands in Table 7. These commands must be executed in the order listed.

Table 7. ECG Startup Register Command Sequence

Address Data Comment
0x09 0x000000 Internal clock synchronization command.
0x0A 0x000000 Reset FIFO command.
0x10 OR with 0x080000 EN_ECG = 1b to enable ECG sampling.

When started, the system continuously acquires data at the selected ECG sample rate until the EN_ECG bit in the ECG CNFG_GEN (0x10) register is cleared.

Data Collection and Temporal Correlation

While the system is continuously acquiring data, the ECG and PPG FIFOs need to be read after each data pair is placed in the respective FIFO. It is important that the ECG data FIFO is not read until the PPG completes measurement because the small current signal generated by the PPG photodiode is susceptible to switching transitions on the SPI lines. The PPG FIFO Ready interrupt goes low immediately after the PPG completes measurement. If data is not read after each measurement, it becomes difficult to manage the reading of multiple samples from the FIFOs and to guarantee that there is no SPI activity during the PPG measurement time.

Adjust the ECG and PPG data pairs based on the delay times to make meaningful pulse arrival time (PAT) measurements. The ECG data sample read after a given ECG synchronization pulse at time tSYNCH represents an ECG measurement at time tECG. tECG is the ECG measurement time before the synchronization pulse, which is expressed as tECG = tSYNCH – tECG_DELAY. The PPG data sample read after the same ECG synchronization pulse represents a PPG measurement at time tPPG. tPPG is the measurement time after the synchronization pulse falling edge, which is expressed as tPPG = tSYNCH + tPPG_DELAY.

Figure 5 shows the relationship between tECG and tPPG.

tPPG_DELAY timing.Figure 5. Data pair delay timing.

The time difference between the ECG and PPG data pair is determined by subtracting tECG from tPPG as follows:


This is the sum of the ECG and PPG delays defined in Table 1 and Table 4.

To time-correlate the ECG and PPG data pair, read from the FIFOs after each measurement at time tSAMPLE. Assume that the ECG timestamp is equal to tSAMPLE. To determine the PPG timestamp, add tSAMPLE and the time-delay sum.


for a given ECG PPG data pair.

Converting Raw ECG Data to ECG Millivolts

Each ECG sample word read from the ECG FIFO consists of 3 data bytes. The lower 6 bits contain tags, which can be used to verify the quality of the data. Assuming that the 3-data-byte word is read into a 3-byte character array called data, the most significant byte is in data[0], and the least significant byte is in data[2], the following C code can be used to convert the raw data word into ADC counts:

data[2] = data[2]>>6; // shift data right 6 bits to remove data tags
ADC_count = data[0] × 1024 + data[1] × 4 + data[2];
If (ADC_count > 131072) ADC_count = ADC_count – 262144;// 2's complement

To convert the ADC count to millivolts, use the following equation:
ECG_mv = 1000 × ADC_count / (217 × Gain)
where Gain is the ECG gain of 20V/V, 40V/V, 80V/V or 160V/V selected by the register 0x15.
Refer to the MAX30003 data sheet for more details on the ECG data-word format.

Converting Raw PPG Data Words to PPG Counts

Each PPG-sample word read from the PPG FIFO consists of 3 data bytes. The upper 5 bits of the most significant byte contain automatic ranging information and are masked with zeros before converting to counts. Assuming that the 3-data-byte word is read into a 3-byte character array called data, the most significant byte is in data[0], and the least significant byte is in data[2], the following line of C code can be used to convert the 3-byte raw data word into PPG counts:

PPG_count = (data[0]&0x07) × 65536 + data[1] × 256 + data[2];

PPG_count is proportional to the amount of light collected from the LED driven by the PPG device during the LED integration time. The absolute magnitude of the counts is dependent on many variables and has no absolute reference.

Because the PPG data is typically recovered as an approximated 1Hz AC signal riding on a large, slowly moving (0.2Hz) background signal, the PPG data is usually displayed with the background signal removed. The easiest way to remove the background signal is to subtract the PPG signal value of sample n from a one second running average of the PPG signal. The running average is centered on sample n (i.e., the average spans from 0.5 seconds before to 0.5 seconds after sample n).

Refer to the MAX86171 data sheet for more details on the PPG data-word format.

PAT Data-Correlation Example

Table 8 shows an example of raw data-pair samples and their corresponding time-corrected correlation for each data sample. The correction assumes ECG sampling at 512sps with the DLPF bypassed and the PPG set for 24µs-settling time and 117µs-integration time. These settings require an ECG-delay adjustment of 20.839ms and a PPG-delay adjustment of 526µs giving a total ECG-to-PPG offset of 21.365ms, which was calculated as follows:

tPPG_DELAY + tECG_DELAY = 0.526ms + 20.839ms = 21.365ms

Data sampled at 512sps results in consecutive samples separated by 1.953125ms. As shown in Table 8, the PPG samples for each data pair are assigned a sample time that is 21.365ms after the ECG time. ECG time is assumed to be n × 1.953125ms, where n is the sample index.

Table 8. PAT Data-Sample-Pair Time-Correlation Example

Raw Data Pairs Time-Corected Data Pairs
0 -308 305513 0.0000 -308 21.3650 305513
1 -230 305560 1.9531 -230 23.3181 305560
2 -94 305542 3.9063 -94 25.2713 305542
3 38 305554 5.8594 38 27.2244 305554
4 236 305561 7.8125 236 29.1775 305561
5 462 305567 9.7656 462 31.1306 305567
6 606 305588 11.7188 606 33.0838 305588
7 800 305592 13.6719 800 35.0369 305592
8 1101 305599 15.6250 1101 36.9900 305599
9 1358 305594 17.5781 1358 38.9431 305594
10 1621 305589 19.5313 1621 40.8963 305589
11 1971 305583 21.4844 1971 42.8494 305583
12 2255 305619 23.4375 2255 44.8025 305619
13 2322 305622 25.3906 2322 46.7556 305622
14 2143 305636 27.3438 2143 48.7088 305636
15 1780 305651 29.2969 1780 50.6619 305651
16 1270 305647 31.2500 1270 52.6150 305647
17 543 305645 33.2031 543 54.5681 305645
18 -273 305652 35.1563 -273 56.5213 305652
19 -872 305635 37.1094 -872 58.4744 305635
20 -1201 305660 39.0625 -1201 60.4275 305660


In a real-world solution of a test subject, Figure 6 shows actual data with wet ECG electrodes placed on the chest to measure Lead II and PPG data taken from a finger on the left hand. The ECG counts have been converted to millivolts, and the PPG counts have been high-pass filtered to remove the DC component of the signal by subtracting each PPG sample from a one-second-wide running average.

ECG and PPG correlated data plot.Figure 6. ECG and PPG correlated data plot.

There are many different methods to calculate PAT, so the reader must decide on which method best meets their needs. This application note shows hardware and register configurations to obtain ECG and PPG data that is typically time correlated to a standard deviation of less than 5µs.