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 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 there,
Did you set register 0x10 to 0x0002 after you loaded the config to start the data acquisition? The LEDs glow only when the ADPD144RI is in sample mode.
When LEDX1/LEDX2 are on, there is forward voltage across the LED(s), depending on the current. Please note that the LEDX1 and LEDX2 are current sink and only turned on during the LED pulses. The voltage at the LEDX1 and LEDX2 pins should be close to VLED when the LEDX1/LEDX2 are off.
Regards,
Glen B.
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.
Dear Glen,
Yes, We have set the register 0x10 to 0x0002 after the configuration is loaded. Although, We have done this, the LEDs are not glowing. I have measured the 3V, 1.8V supplies, They are fine.
Can you share the sample data that is expected when We load the suggested configuration both in open condition and when finger is placed over the device.
What is the maximum value of pulse width that we can set..?
Hi there,
I have updated the code and attached as main_v3.rft, can run this code to get the data from FIFO
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.