polarofficial / polar-ble-sdk

Repository includes SDK and code examples. More info https://polar.com/en/developers
Other
474 stars 153 forks source link

What do the PPG channels represent. #202

Closed KennethEvans closed 1 year ago

KennethEvans commented 2 years ago

Platform your question concerns:

Device:

Description: I know that the PPG data consist of 4 channels, one of which is ambient. However I do not know what the numbers represent. I wrote an app to display the four values. I was surprised to find they are all roughly constant.

I was expecting (and want) something like the plot on my pulse oximeter or on plots I see on sites, such as Wikipedia, that discuss PPG.

300px-PVC_detectionUsing_PGG

How do I convert these signals into something that looks like top graph on that image. I would like something comparable to the ECG output from the SDK for the H10 or the third graph in the image; that is, a replacement for the ECG waveform as expected from a PPG device like the OH1 or Verity Sense.

It has been stated elsewhere that the ambient channel should be subtracted from each of the other channels, and that they are in raw units, not anything physical. Is there some significance to the other 3 individual channels, or can they be summed or averaged?

I am not an expert on signal processing.

Thanks.

JOikarinen commented 2 years ago

Hi @KennethEvans,

However I do not know what the numbers represent.

  • PPG signal doesn't have agreed unit. It is raw value, each manufacturer having the own scale for the value. Because of autogain feature in PolarOH1 and Polar Verity Sense there can be jumps in PPG signal during measurements. That is discussed in previous issue, see the Spikes in Polar PPG Sensor values #152 (comment)

I wrote an app to display the four values. I was surprised to find they are all roughly constant.

  • here is short section of PPG0 signal I just recorded by Polar Verity Sense: Polar Verity Sense channel 0
  • from that data the peak to peak time is roughly 1333ms = 45bpm
  • you shall see something like that received from PPG0, PPG1 and PPG2 channels

It has been stated elsewhere that the ambient channel should be subtracted from each of the other channels, and that they are in raw units, not anything physical.

  • That's my current understanding. I will double check this from PPG data experts.
JOikarinen commented 2 years ago
  • That's my current understanding. I will double check this from PPG data experts.
  • ambient channel represents the background noise caused by other light sources, so it can be used to remove the background noise from ppg channels
KennethEvans commented 2 years ago

Thank you for the detailed reply. That helps.

If I were getting data like in your plot, I wouldn't have asked the question.

This is what I get for a Verity Sense. (It is under clothing, which should reduce the ambient.) The numbers are taken from the log for the demo and plotted in a spreadsheet. That should eliminate any coding errors of mine. This is for around 3500 samples, plotted vs. sample number (at 135 Hz). PPG Values

There is a huge DC component. I also plotted the data for 300 samples (more like yours) divided by the average for those samples. That begins to look like what one would want, apart from the drift. (It also looks like about two heartbeats per second, which wouldn't be right. Playing with computers doesn't get me that excited.) PPG Values AC

KennethEvans commented 2 years ago

I apologize, I meant to subtract the average to get the AC component. Note it is a small percentage of the signal. PPG Values AC2 .

KennethEvans commented 2 years ago

OK, I am getting somewhat reasonable results by subtracting a running average of the last n samples. n = 50 seems good. n = 135 gives too much variation. The problem is it's very susceptible to arm motion. I'm not sure how useful what I have now is as an app.

I am interested in why you get much cleaner results, and, of course, how to get around these issues, in particular the susceptibility to motion.

This is a screenshot. Note it is fairly regular until I moved my arm. If I moved it more strongly, it would be worse. Running average is over 50 samples. Higher gives more noise and more variation. (I am plotting the sum of the channels minus 3 times the ambient, scaled to fit .)

In addition the peaks are indicating a HR about twice what it actually is.

Screenshot_20211011-123118_KENet PPG

JOikarinen commented 2 years ago

one note:

KennethEvans commented 2 years ago

one note:

That's unfortunate. Coding with branches to handle specific devices and firmwares is hard to maintain and easily broken.

Is there a way to know what sampling rate you're actually getting without doing something like counting how many samples you get in some time period. Obviously the plotting is going to be wrong if you get something that wasn't requested or expected.

JOikarinen commented 2 years ago

Is there a way to know what sampling rate you're actually getting without doing something like counting how many samples you get in some time period. Obviously the plotting is going to be wrong if you get something that wasn't requested or expected.

You shall expect to get the data with sampling rate you have requested stream. Unfortunately there is two known issue, and both of them are related to PPG, one with Polar Verity Sense and another with OH1

KennethEvans commented 2 years ago

You shall expect to get the data with sampling rate you have requested stream. Unfortunately there is two known issue, and both of them are related to PPG, one with Polar Verity Sense and another with OH1

So I guess the answer to my question is there is no way to tell what sampling rate you will actually get (for PPG). I fixed it to use the first two packets to get a time interval. The actual sampling rate is 10^9 * nPackets2 / interval, rounded off.

However the real problem is that the data are very susceptible to motion (on top of the fact there is a large DC component). I don't find the results useful for an app that does the PPG equivalent of an ECG, what I want.

Since the device is also collecting accelerometer, gyro, and magnetometer data, presumably they are needed to get something sensible. I doubt this algorithm will be shared, but it would be nice if something equivalent to an ECG waveform were available directly.

JOikarinen commented 2 years ago

So I guess the answer to my question is there is no way to tell what sampling rate you will actually get (for PPG).

  • unfortunately because the known issues on OH1 and Polar Verity Sense you cannot trust on the frequency you request the PPG streams
  • so I see only two options: either you calculate the frequency from received PPG timestamps, was that something which is not suitable in your application? Or the dummy approach, using the known frequencies, which are 130Hz for OH1 and 55Hz for Polar Verity Sense.

However the real problem is that the data are very susceptible to motion (on top of the fact there is a large DC component). I don't find the results useful for an app that does the PPG equivalent of an ECG, what I want.

  • the motion is the core problem with the optical heart rate measurement. There is no other help provided by SDK than the PPI, which is not exactly what you want, right? Of course the PPI is also sensitive for the motion, so the motion problem is still existing in PPI stream.
KennethEvans commented 2 years ago

was that something which is not suitable in your application?

No, that's what I did (see my reply).

There is no other help provided by SDK than the PPI

That has the problem in #197.

Thanks for your help. The problem is not with the SDK.

arezomar commented 1 year ago

Hi there, I am writing my final university year dissertation on validity of Polar H10 and Verity. I had the same intial question as kenneth, although I am struggling to find an answer. why do we get 3 different channels(PPG0, PPG1, PPG2) and what does each channel mean? what do they represent? Thanks

beatrizbonafini commented 1 year ago

https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7085621/

This article explains the data recovered by the ppg sensors. Each channel represents: green, red and infrared light transmitted to the skin tissue and the data is captured by its receptor.

PChiericoUPV commented 2 months ago

Hello I would like to understand if the PPG signal is inverted, as the systolic phase seems to be consistent with the literature only when I invert the signal on the Y-axis. Additionally, regarding the three PPG channels, does Ch0 represent a combination of the six measurements?