Post Go back to editing

My PPG is always noisy, and unable to read FIFO

Category: Software
Product Number: ADPD4101
Software Version: 1.0

I'm using an arduino to read data from ADPD4101 via I2C, I'm able to toggle the LEd's increase and decrese brightness but unable to read PPG from IN1 which connected to a PD and PD connected to VC1 

#include <Wire.h>
#define ADPD_ADDR 0x24

// System registers
#define REG_SYS_CTL 0x000F
#define REG_SW_RESET 0x8000 // bit15 = SW_RESET
#define REG_OSC_1M_EN 0x0002 // bit1 = 1 MHz oscillator enable
#define REG_AFE_EN 0x0001 // bit0 = AFE state‑machine enable

// Pattern/timing registers
#define REG_OPMODE 0x0010
#define REG_LED_POW12_A 0x0105 // Red LED Verified
#define REG_LED_POW34_A 0x0106 // Green LED Verified
#define REG_COUNTS_A 0x0107
#define REG_PERIOD_A 0x0108
#define REG_LED_PULSE_A 0x0109 // Brightness verified
#define REG_PATTERN_A 0x010D

// PD1 registers
#define REG_INPUT_A 0x0100
#define REG_SLOT_EN 0x0110 // FULL Data Format Register
#define REG_FIFO_COUNT 0x0006
#define REG_FIFO_DATA 0x0005

// Chip ID
#define REG_CHIP_ID 0x0008


// Sampling Frequency
#define TS_FREQ_H 0x000E
#define TS_FREQ_L 0x000D

#define REG_FIFO_COUNT 0x0006
#define REG_FIFO_DATA 0x002F


void setup() {
Serial.begin(115200);
Wire.begin();
delay(100);

writeReg(0x0009, 0x0080); //0009 0080 # 32MHz trim - trim your own clock
writeReg(0x000B, 0x02B2); //000B 02B2 # 1MHz trim - trim your own clock
writeReg(0x000C, 0x0012); //000C 0012 # 32kHz trim - trim your own clock
writeReg(0x000D, 0x2710); //000D 2710 # 100 Hz
writeReg(0x000F, 0x0006); //000F 0006 # enable 1MHz osc
writeReg(0x0020, 0x0004); //0020 0004 # in1 connected to vc1 during sleep, everything else floating
writeReg(0x0021, 0x0000); //0021 0000 # all inputs single ended, vc1 set to Vdd during sleep
writeReg(0x0022, 0x0003); //0022 0003 # gpio0 is output, inverted
writeReg(0x0023, 0x0002); //0023 0002 # intx to gpio0
writeReg(0x0014, 0x8000); //0014 8000 # fifo thresh interrupt to intx
writeReg(0x0006, 0x00FF); //0006 00FF # fifo threshold 128 bytes


//## timeslot A - continuous connect mode
//
writeReg(0x0100, 0x0000);//0100 0000 # Rin = 500, tsA offset = 0, skip subsample
writeReg(0x0101, 0x40DA);//0101 40DA # path = TIA + BPF + INT + ADC
writeReg(0x0102, 0x0001);//0102 0001 # IN1 to channel 1, others disconnected
writeReg(0x0103, 0x5002);//0103 5002 # precondition inputs to TIA_Vref, VC1 active state = V_delta
writeReg(0x0104, 0x03C0);//0104 03C0 # Rf = 200k Rint = 400k
writeReg(0x0105, 0x0017);//0105 0017 # 38 mA on LED1A
writeReg(0x0106, 0x0000);//0106 0000
writeReg(0x0107, 0x0104);//0107 0104 # 4 pulses
writeReg(0x0108, 0x0000);//0108 0000 # period set by automatic period of continuous connect mode
writeReg(0x0109, 0x0610);//0109 0210 # led width= 2us led offset=16 us
writeReg(0x010A, 0x0003);//010A 0003 # integrator width=3 us
writeReg(0x010B, 0x0210);//010B 0210 # integrator offset=16.5 us - ADJUST FINE OFFSET
writeReg(0x010C, 0x010C);//010C 0001 # no modulation
writeReg(0x0110, 0x0003);//0110 0003 # signal size = 3 bytes
writeReg(0x011D, 0x0099);//010D 0099 # -++- int pattern
writeReg(0x011E, 0x0000);//010E 0000 # NO OFFSET - review if needed
writeReg(0x011F, 0x0000);//010F 0000 # NO OFFSET - review if needed
writeReg(0x0112, 0x0000);//0112 0000 # no decimation

// 3) TIA Gain set to 500kΩ
uint16_t val_04 = readReg(0x0104);
val_04 &= ~0x0003;
val_04 |= 0x0001; // 0b01 = 500 kΩ gain
writeReg(0x0104, 0x0300); //TIME SLOT A

//writeReg(REG_LED_POW12_A, 0x0A00); // LED1A & LED2A RED and IR LED SLOT A
//writeReg(0x0125, 0x0A0A); // SLOT B RED IR
writeReg(REG_LED_POW34_A, 0x0005); // Greeen LED SLOT A
//writeReg(0x0126, 0x000A); // Green LED SLOT B
Serial.println("LED currents x mA");


writeReg(0x00B0, 0x0010); // By fourm

uint16_t Imp_status = readReg(0x00B0);
Serial.print("Status of IMP byte "); Serial.println(Imp_status);

writeReg(0x0010, 0x0001); // OPMODE: Enable Slot A only


}


void loop() {

uint16_t Full_signal = readReg(0x002F); // bits [15:0]

//uint16_t status_fifo = readReg(0x0000);

//// Check for overflow or underflow
//if (status_fifo & (1 << 13) || status_fifo & (1 << 14)) {
// writeReg(0x0000, (1 << 15)); // CLEAR_FIFO = 1
//}


uint16_t low = readReg(0x0030); // bits [15:0]
uint16_t high = readReg(0x0031) ; // bits [23:16] only
uint16_t low_B = readReg(0x0038); // bits [15:0]
uint16_t high_B = readReg(0x0039) ; // bits [23:16] only
uint32_t sample_B = ((uint32_t)high_B << 16) | low_B;


uint8_t dark_high = readReg(0x0035);
uint8_t dark_low = readReg(0x0034);

uint32_t sample_dark = ((uint32_t)dark_high << 16) | dark_low;

uint32_t sample = ((uint32_t)high << 16) | low;

uint32_t PPG = sample - sample_dark;


//Serial.print(Full_signal);Serial.println(",");
uint16_t Imp_status = readReg(0x00B0);
Serial.print("Status of IMP byte "); Serial.println(Imp_status);

//Serial.print(high); Serial.print(","); Serial.print(low);Serial.print(",");
//Serial.print(dark_high); Serial.print(","); Serial.println(dark_low);

//Serial.println(sample);
delay(10);

} here is my arduino code, readReg and writeReg are functions to read or write data from a specific register of ADPD4101 and I read 16 as the output for reading 0x00B0. Please help 

I'm using reflective PPG setup where my PD's and LED are on the same surface 

Before You Switch


Switching languages will make ADI Explorer unavailable. Resume your session by switching back to English and reopening ADI Explorer.