Please share an example code for ADPD144RI read data from ESP32 or Arduino
ADPD144RI
Not Recommended for New Designs
The ADPD144RI is a highly integrated, photometric front end optimized for photoplethysmography (PPG) detection of blood oxygenation (SpO2) by synchronous...
Datasheet
ADPD144RI on Analog.com
Please share an example code for ADPD144RI read data from ESP32 or Arduino
Hi there,
Please check the thread at the link below:
https://ez.analog.com/optical_sensing/f/q-a/165141/adpd144ri-software-code-example
Regards,
Glen B.
Dear Glen,
I am writing on behalf of Suresh. The github link contains drivers for ADPD10X. It does not contain specifically for ADPD144. Please let us know if there is any other location where specific files for ADPD10X is placed.
In the meantime, We have tried to test our PCB with ADPD144.
We have programmed the register Setting values as suggested in the datasheet and also in engineering Zone forum link: (https://ez.analog.com/optical_sensing/f/q-a/165141/adpd144ri-software-code-example) have been used to program.
Initially, We tried to read the reset values of each register. The values read matched with the expected values provided in Table-13 (Register Listing) of datasheet.
We are using Poling method to read the data. Although, We have used the same register values as suggested in datasheet or Forum, The data observed in the data registers 0x64 to 0x7F are 0x0000.
We also placed the finger on the ADPD1443I, the LED did not turn on also, the data registers still sshowed 0x00000
We have followed the startup sequence suggested in the datasheet. Initially, register 0x10 is written 0x0001 during writing all the registers and later after all the registers are written, register 0x10 is written 0x0002 to enter into normal operation mode.
The register values that we programmed and the values we readout are shown below.
Reg name |
Register Address |
Programmed Values |
Read out Values |
Mode |
0x10 |
0x00000001 |
|
Mode read |
0x10 |
|
0x00000001 |
STATUS |
0x00 |
0x00008000 |
|
int mask |
0x1 |
0x000000ff |
|
int io ctl |
0x2 |
0x00000005 |
|
fifo thresh |
0x6 |
0x00000000 |
|
STATUS |
0x00 |
0x0000ff60 |
|
ID |
0x08 |
|
0x00000416 |
slot |
0x11 |
0x000030a9 |
|
fsample |
0x12 |
0x0000000a |
|
led select |
0x14 |
0x00000116 |
|
num avg |
0x15 |
0x00000330 |
|
ach1 0ff |
0x18 |
0x00003fff |
|
ach2 0ff |
0x19 |
0x00003fff |
|
ach3 0ff |
0x1a |
0x00001ff0 |
|
ach4 0ff |
0x1b |
0x00001ff0 |
|
bch1 0ff |
0x1e |
0x00003fff |
|
bch1 0ff |
0x1f |
0x00003fff |
|
bch1 0ff |
0x20 |
0x00001ff0 |
|
bch1 0ff |
0x21 |
0x00001ff0 |
|
|
0x22 |
0x00003000 |
|
1coarse |
0x23 |
0x00003005 |
|
2coarse |
0x24 |
0x00003007 |
|
ledfine |
0x25 |
0x00000207 |
|
a_m0de |
0x30 |
0x00000319 |
|
a_pulse |
0x31 |
0x00000813 |
|
leddis |
0x34 |
0x00000000 |
|
b_m0de |
0x35 |
0x00000319 |
|
b_pulse |
0x36 |
0x00000813 |
|
ext sync startup |
0x38 |
0x00000000 |
|
a_afe |
0x39 |
0x000021f3 |
|
b_afe |
0x3b |
0x000021f3 |
|
|
0x3c |
0x00003006 |
|
a_gain |
0x42 |
0x00001c36 |
|
a_afe_con |
0x43 |
0x0000ada5 |
|
a_gain |
0x44 |
0x00001c36 |
|
b_afe_con |
0x45 |
0x0000ada5 |
|
clk written |
0x4b |
0x00000080 |
|
clk read |
0x4b |
|
0x00000080 |
alk adjust |
0x4d |
0x0000425e |
|
adc_tim |
0x4e |
0x00000040 |
|
ext sync sel |
0x4f |
0x00002090 |
|
cal enb |
0x50 |
0x00000000 |
|
|
0x52 |
0x00000040 |
|
|
0x54 |
0x00000020 |
|
tia gain |
0x55 |
0x00000000 |
|
|
0x5a |
0x00000010 |
|
dataacc_ctl |
0x5f |
0x00000000 |
|
dataacc_ctl |
0x5f |
0x00000006 |
|
mode written |
0x10 |
0x00000002 |
|
mode read |
0x10 |
|
0x00000002 |
SL0TA_PD1_16BIT read |
0x64 |
|
0x00000000 |
SL0TA_PD2_16BIT read |
0x65 |
|
0x00000000 |
SL0TA_PD3_16BIT read |
0x66 |
|
0x00000000 |
SL0TA_PD4_16BIT read |
0x67 |
|
0x00000000 |
SL0TB_PD1_16BIT read |
0x68 |
|
0x00000000 |
SL0TB_PD2_16BIT read |
0x69 |
|
0x00000000 |
SL0TB_PD3_16BIT read |
0x6a |
|
0x00000000 |
SL0TB_PD4_16BIT read |
0x6b |
|
0x00000000 |
We also have tried to verify with respect to hardware.
The schematic we have used is shown below.
Please let us know if you see any issues. We are unable to get any data (The data registers are reading 0x0000) and LED is also not turning ON when we keep the finger.
Thanks
Hi there,
The ADPD144RI has ADPD103 and LEDs and PDs inside. So the driver for ADPD10x is the right one for ADPD144RI. You can always refer to the ADPD103 datasheet for details of the register map. The formula for CVLED calculation is correct. The 1u + 0.1u caps are OK for VLED. The 1u cap for VREF is also fine.
With regard to register settings, the register 0x5F was set to 0x0006, which prevents the data update. Have you tried to read data from the FIFO? There are a few other registers with nontypical settings in your config. The configure below worked very well. Please try if it works for you.
# ADPD144RI_Config_File
# Register Value
02 0005
06 0000
11 30A9
12 000A
14 0116
15 0330
18 3FFF
19 3FFF
1A 1FF0
1B 1FF0
1E 3FFF
1F 3FFF
20 1FF0
21 1FF0
22 3000
23 3005
24 3007
25 0207
34 0000
30 0319
31 0813
35 0319
36 0813
39 21F3
3B 21F3
3C 3006
42 1C36
43 ADA5
44 1C36
45 ADA5
4E 0040
54 0020
5A 0000
Regards,
Glen B.
Dear Glen,
Thanks for reply, We tried to use the suggested register values and followed steps as per the start up sequence. We are able to observe the data in Registers 0x64 to 0x6b.
However, We are unable to see the LED glow. I believe this is because of the LED pulse width set to 3uSec and pulse period to 19uSec. Please correct me if this is not the correct behavior.
What is the expected voltage across Vref capacitor. When I measured It was 0V. Is this correct.
Since, We are using Internal LEDs, Datasheet mentions, We can measure the voltage LEDX1 and LED X2. The measured value on LEDX1 is 1.68V and LEDX2 is 2V. Are these values correct.
Thanks.
Dear Glen,
We are facing issue with resetting the FIFO contents. When we try to capture data multiple times, We found that, the data in FIFO was not getting updated. Please find the attached Text files 1_Data.txt and 2_DATA.txt. You can see that, data in the data FIFO is the same in both iterations.
Hence, We tried to reset the FIFO based on the steps mentioned in the Startup sequence section.
We have written a application code, to perform read operation for 4 times in a loop. After each read operation, The FIFO is reset and when read operation is performed again in loop the FIFO is resetting properly and new data is getting updated in the FIFO.
However, If We reset the board and then perform the read operation, We are observing the Previously captured data (that was observed before resetting board) is read in the data registers.
Request you to let us know if you see any mistake we are doing.
Please find the snippet below containing data that is read and register settings we are using to clear the FIFO after each read. We have followed the steps provided in startup sequence to clear the FIFO.
Hi there,
The Vref should be at 1.265V. The voltages at LEDX1 and LEDX2 looked fine , meaning there is voltage drops across the integrated red and IR LEDs.
Were you able to see the red LED glowing with the config I posted?
With regard to the FIFO read, I will ask our firmware colleague to comment.
Regards,
Glen
Hi Subbu,
Regarding FIFO read data can you share your code snippet to go through it.
Are you using AdpdDrvReadFifoData() API to readout data from FIFO?
Regards,
Sathishkumar
Hi Subbu,
Regarding FIFO read data can you share your code snippet to go through it.
Are you using AdpdDrvReadFifoData() API to readout data from FIFO?
Regards,
Sathishkumar
Dear Sathish,
Please find the attached source code.
Briefly, We are trying to do the following:
1. Initially, We are programming the registers as per the above configuration file by putting the chip in program mode.
2. After the configuration file is loaded, We are putting device into Normal operation mode (By writing 02 to Register 0x10).
3. We are reading the data stored in registers 0x64 to 0x6b.
4. After reading, We are clearing the FIFO and trying to read the data again.
We also need clarification on the following.
In this code snippet.
https://github.com/analogdevicesinc/adpd-drivers/blob/master/ADPD10xx/examples/example188.c
/* Clear the FIFO */
AdpdDrvRegWrite(0x10, 0);
AdpdDrvRegWrite(0x5F, 1);
AdpdDrvRegWrite(0x00, 0x80FF);
AdpdDrvRegWrite(0x5F, 0);
According to the above code snippet, 0 is written to 0x10, which puts the chip in to standby mode and later the register programming is done to clear FIFO.
But, As per the startup sequence mentioned in datasheet, From Normal Operation mode, To clear the FIFO, We need to put the chip in to program mode and then enter necessary register values to clear FIFO and later we need to program 0x10 with 0x2 to put the device into read mode.
We would like to understand, the difference between the procedure followed in example188.c and approach suggested in datasheet to clear FIFO.
Thanks
Hi Subbu,
I would suggest two change, since your are not using driver API's.
AdpdDrvGetParameter() This API will give the available bytes in the FIFO. we need to ensure that required data's are accumulated in FIFO before reading it.
Regarding FIFO clear mechanism you can follow the data sheet sequence. In driver file we are following same sequence as mentioned in data sheet.
Regards,
Sathishkumar K
1.
The FIFO read API is modified to enable FIFO clock before reading
AdpdDrvRegWrite(0x0010, 0x0001);
AdpdDrvRegWrite(0x005f, 0x0001);
AdpdDrvRegWrite(0x005f, 0x0001);
AdpdDrvRegWrite(0x0010, 0x0002);
#define ADPDDrv_SUCCESS (0) #define ADPDDrv_ERROR (-1) #define ADPD_I2C_ADDRESS (0x64) #include <uart_debug.h> void main(void) { uint32_t LoopCnt = 0; uint8_t value[16] = {0}; uint16_t nAdpdFifoLevelSize = 64, nAdpdDataSetSize; uint16_t nLoopLim = 16; uint16_t nAdpdDataSetSize = 8; uint16_t nRetValue = 0; AdpdDrvInit(); while (1) { nRetValue = AdpdDrvReadFifoData(&value[0], nAdpdDataSetSize); if (nRetValue == ADPDDrv_SUCCESS) { for (LoopCnt = 0; LoopCnt < nLoopLim; LoopCnt += 2) { UART_Print("%u ", (value[LoopCnt] << 8) | value[LoopCnt + 1]); nAdpdFifoLevelSize = nAdpdFifoLevelSize - nAdpdDataSetSize; } } } } int16_t AdpdDrvReadFifoData(uint8_t *pnData, uint16_t nDataSetSize) { uint8_t nGetFifoData, nAddr; nAddr = 0x60; AdpdDrvRegWrite(0x0010, 0x0001); AdpdDrvRegWrite(0x005f, 0x0001); AdpdDrvRegWrite(0x005f, 0x0001); AdpdDrvRegWrite(0x0010, 0x0002); if (ADPD_I2C_TxRx((uint8_t *) &nAddr, pnData, nDataSetSize) != HAL_OK) return ADPDDrv_ERROR; return ADPDDrv_SUCCESS; } bool ADPD_I2C_TxRx(unsigned char* pTxData, unsigned char* pRxData, unsigned int Size) { HAL_I2C_Master_Transmit(&hi2c2, (uint16_t)(ADPD_I2C_ADDRESS << 1), (uint8_t *)pTxData, Size, 100); return (HAL_STATUS_t)HAL_I2C_Master_Receive(&hi2c2, (uint16_t)(ADPD_I2C_ADDRESS << 1), pRxData, Size, 100); } int16_t AdpdDrvRegWrite(uint16_t nAddr, uint16_t nRegValue) { uint8_t anI2cData[3]; anI2cData[0] = (uint8_t)nAddr; anI2cData[1] = (uint8_t)(nRegValue >> 8); anI2cData[2] = (uint8_t)(nRegValue); if (ADPD_I2C_Transmit((uint8_t *)anI2cData, 3) != ADI_HAL_OK) return ADPDDrv_ERROR; return ADPDDrv_SUCCESS; } AdpdDrvInit() { //Init code }
2.
I will add the API to check the available FIFO bytes before reading the FIFO data. I will update this code and share.
I was having indefinite loop to read the data. This code was shared above.
Now I have changed the indefinite loop - while (1) to read the fifo data, based on the bytes of data available to readdata size.
Now after adding this API - AdpdDrvGetParameter(), I could only get 128-bytes of data.
I could see only 4 reads and each read gets us 32 byte of Data (Total 128-BYTES) . After each read fifo reset is happening, but after the board is power cycled, We could still read the cached data and that is the same data we have received before power cycle.
Hi there,
I have updated the code and attached as main_v3.rft, can run this code to get the data from FIFO
Thank You Satish. I will test this and get back to you.
Satish, This started giving continuous data, but I still see the FIFO not getting cleared. Are there any more debugging points for me to debug? I have re-verified the init part again and please find attached the init code. Please do let me know, if this is correct.
Hi,
In the AdpdDrvInit() function AdpdDrvRegWrite(0x0010, 0x0002); sample mode register is set as running mode.
Just remove that line in AdpdDrvInit() function, this sample mode setting will take care in AdpdDrvSetOperationMode() API.
There is no need to clear the FIFO after putting device into sample mode, every FIFO read will clear the bytes which have read it out.