PPSI262 and SHT21

Hello Arduino community!

I have a problem. I created a PCB with two sensors (SHT21 and PPSI262) and now I'm struggling with programming those two. When I import the library for SHT21 I'm getting wrong readings like -46.85 Celsius and -6 % for humidity. Also I can't find anything about PPSI262 on how to program it.

If You can help me it would be great!

Rewire them in a breadboard like your prototype, see if the readings are correct. If they are, then you're PCB is wrong!

Why have you a PCB with a PPS1262 that you have not prototyped and got code working?

I have another SHT21 which I tried to program without PCB and still doesn't work. I get the same readings.

Regarding PPSI262, You are completely correct, I should have checked the code for it.

OK - you need to provide the schematic & code you have!



There are images of my schematic. I also thought that my schematic is wrong but as I said, connecting only SHT21 to Arduino didn't give me better results.

The library I used: GitHub - SolderedElectronics/SHT21-Arduino-Library: Arduino library for SHT21 - temperature and humidity sensor. With checksum!

I don't know if you get this or if it will help, but I've been trying to get the PPSI262 sensor to work for a while now, and I had a bit of success. Here is my python code - but you should be able to translate it to Arduino code somewhat easily - most of it is just getting the registers set correctly. I still don't have it working exactly like I want, but it's at least doing something useful!

import busio
import board
import time
import ulab

PPSI262_ADR = 0x5B

FIFO_EN = 0
FIFO_EN_MASK = 0x40

ENABLE_ULP = 0
ENABLE_ULP_MASK = 0x20

RW_CONT = 0
RW_CONT_MASK = 0x10

SW_RESET = 0
SW_RESET_MASK = 8

TM_COUNT_RST = 0
TM_COUNT_RST_MASK = 2

SPI_REG_READ = 0
SPI_REG_READ_MASK = 1

LED2STC = 1
LED2STC_MASK = 0xFFFF

LED2ENDC = 2
LED2ENDC_MASK = 0xFFFF

LED1LEDSTC = 3
LED1LEDSTC_MASK = 0xFFFF

LED1LEDENDC = 4
LED1LEDENDC_MASK = 0xFFFF

ALED2STC = 5
ALED2STC_MASK = 0xFFFF

ALED2ENDC = 6
ALED2ENDC_MASK = 0xFFFF

LED3STC = 5
LED3STC_MASK = 0xFFFF

LED3ENDC = 6
LED3ENDC_MASK = 0xFFFF

LED1STC = 7
LED1STC_MASK = 0xFFFF

LED1ENDC = 8
LED1ENDC_MASK = 0xFFFF

LED2LEDSTC = 9
LED2LEDSTC_MASK = 0xFFFF

LED2LEDENDC = 0xA
LED2LEDENDC_MASK = 0xFFFF

ALED1STC = 0xB
ALED1STC_MASK = 0xFFFF

ALED1ENDC = 0xC
ALED1ENDC_MASK = 0xFFFF

LED2CONVST = 0xD
LED2CONVST_MASK = 0xFFFF

LED2CONVEND = 0xE
LED2CONVEND_MASK = 0xFFFF

LED3CONVST = 0xF
LED3CONVST_MASK = 0xFFFF

LED3CONVEND = 0x10
LED3CONVEND_MASK = 0xFFFF

ALED2CONVST = 0xF
ALED2CONVST_MASK = 0xFFFF

ALED2CONVEND = 0x10
ALED2CONVEND_MASK = 0xFFFF

LED1CONVST = 0x11
LED1CONVST_MASK = 0xFFFF

LED1CONVEND = 0x12
LED1CONVEND_MASK = 0xFFFF

ALED1CONVST = 0x13
ALED1CONVST_MASK = 0xFFFF

ALED1CONVEND = 0x14
ALED1CONVEND_MASK = 0xFFFF

PRPCOUNT = 0x1D
PRPCOUNT_MASK = 0xFFFF

TIMEREN = 0x1E
TIMEREN_MASK = 0x100

NUMAV = 0x1E
NUMAV_MASK = 0xF

TIA_GAIN_SEP3_MSB = 0x1F
TIA_GAIN_SEP3_MSB_MASK = 0x4000

TIA_CF_SEP3 = 0x1F
TIA_CF_SEP3_MASK = 0x3800

TIA_GAIN_SEP3_LSB = 0x1F
TIA_GAIN_SEP3_LSB_MASK = 0x700

TIA_GAIN_SEP2_MSB = 0x1F
TIA_GAIN_SEP2_MSB_MASK = 0x40

TIA_CF_SEP2 = 0x1F
TIA_CF_SEP2_MASK = 0x38

TIA_GAIN_SEP2_LSB = 0x1F
TIA_GAIN_SEP2_LSB_MASK = 7

ENSEPGAIN = 0x20
ENSEPGAIN_MASK = 0x8000

TIA_GAIN_SEP_MSB = 0x20
TIA_GAIN_SEP_MSB_MASK = 0x40

TIA_CF_SEP = 0x20
TIA_CF_SEP_MASK = 0x38

TIA_GAIN_SEP_LSB = 0x20
TIA_GAIN_SEP_LSB_MASK = 7

IFS_OFFDAC = 0x21
IFS_OFFDAC_MASK = 0x7000

FILTER_BW_0 = 0x21
FILTER_BW_0_MASK = 0x200

TIA_GAIN_MSB = 0x21
TIA_GAIN_MSB_MASK = 0x40

TIA_CF = 0x21
TIA_CF_MASK = 0x38

TIA_GAIN_LSB = 0x21
TIA_GAIN_LSB_MASK = 7

ILED3_LSB = 0x22
ILED3_LSB_MASK = 0xC00000

ILED2_LSB = 0x22
ILED2_LSB_MASK = 0x300000

ILED1_LSB = 0x22
ILED1_LSB_MASK = 0xC0000

ILED3_MSB = 0x22
ILED3_MSB_MASK = 0x3F000

ILED2_MSB = 0x22
ILED2_MSB_MASK = 0xFC0

ILED1_MSB = 0x22
ILED1_MSB_MASK = 0x3F

CONTROL_DYN_TX_0 = 0x23
CONTROL_DYN_TX_0_MASK = 0x100000

ILED_FS = 0x23
ILED_FS_MASK = 0x20000

ENSEPGAIN4 = 0x23
ENSEPGAIN4_MASK = 0x8000

CONTROL_DYN_BIAS = 0x23
CONTROL_DYN_BIAS_MASK = 0x4000

OSC_ENABLE = 0x23
OSC_ENABLE_MASK = 0x200

CONTROL_DYN_TIA = 0x23
CONTROL_DYN_TIA_MASK = 0x10

CONTROL_DYN_ADC = 0x23
CONTROL_DYN_ADC_MASK = 8

PDNRX = 0x23
PDNRX_MASK = 2

PDNAFE = 0x23
PDNAFE_MASK = 1

ILED4_MSB = 0x24
ILED4_MSB_MASK = 0x1F800

ILED4_LSB = 0x24
ILED4_LSB_MASK = 0x600

FIFO_TOGGLE = 0x28
FIFO_TOGGLE_MASK = 0x400000

DESIGN_ID = 0x28
DESIGN_ID_MASK = 0x1FFF80

SDOUT_TRISTATE_D = 0x29
SDOUT_TRISTATE_D_MASK = 0x80000

SDOUT_TRISTATE = 0x29
SDOUT_TRISTATE_MASK = 0x200

LED2VAL = 0x2A
LED2VAL_MASK = 0xFFFFFF

LED3VAL = 0x2B
LED3VAL_MASK = 0xFFFFFF

ALED2VAL = 0x2B
ALED2VAL = 0xFFFFFF

LED1VAL = 0x2C
LED1VAL_MASK = 0xFFFFFF

ALED1VAL = 0x2D
ALED1VAL_MASK = 0xFFFFFF

LED2_MINUS_ALED2VAL = 0x2E
LED2_MINUS_ALED2VAL_MASK = 0xFFFFFF

LED1_MINUS_ALED1VAL = 0x2F
LED1_MINUS_ALED1VAL_MASK = 0xFFFFFF

FILTER_BW_1 = 0x31
FILTER_BW_1_MASK = 0x800000

PD_DISCONNECT = 0x31
PD_DISCONNECT_MASK = 0x400

ENABLE_INPUT_SHORT = 0x31
ENABLE_INPUT_SHORT_MASK = 0x20

PROG_INT2_STC = 0x34
PROG_INT2_STC_MASK = 0xFFFF

PROG_INT2_ENDC = 0x35
PROG_INT2_ENDC_MASK = 0xFFFF

LED3LEDSTC = 0x36
LED3LEDSTC_MASK = 0xFFFF

LED3LEDENDC = 0x37
LED3LEDENDC_MASK = 0xFFFF

CLKDIV_TE = 0x39
CLKDIV_TE_MASK = 7

EARLY_OFFSET_DAC = 0x3A
EARLY_OFFSET_DAC_MASK = 0x100000

POL_OFFDAC_LED2 = 0x3A
POL_OFFDAC_LED2_MASK = 0x80000

I_OFFDAC_LED2_MID_A = 0x3A
I_OFFDAC_LED2_MID_A_MASK = 0x78000

POL_OFFDAC_AMB1 = 0x3A
POL_OFFDAC_AMB1_MASK = 0x4000

I_OFFDAC_LED2_MID_B = 0x3A
I_OFFDAC_LED2_MID_B_MASK = 0x3C00

POL_OFFDAC_LED1 = 0x3A
POL_OFFDAC_LED1_MASK = 0x200

I_OFFDAC_LED2_MID_C = 0x3A
I_OFFDAC_LED2_MID_C_MASK = 0x1E0

POL_OFFDAC_LED3 = 0x3A
POL_OFFDAC_LED3_MASK = 0x10

I_OFFDAC_LED3_MID = 0x3A
I_OFFDAC_LED3_MID_MASK = 0xF

POL_OFFDAC_AMB2 = 0x3A
POL_OFFDAC_AMB2_MASK = 0x10

I_OFFDAC_AMB2_MID = 0x3A
I_OFFDAC_AMB2_MID_MASK = 0xF

THR_DET_LOW_CODE = 0x3B
THR_DET_LOW_CODE_MASK = 0xFFFFFF

THR_DET_HIGH_CODE = 0x3C
THR_DET_HIGH_CODE_MASK = 0xFFFFFF

WM_MODE = 0x3D
WM_MODE_MASK = 0x80000

THR_DET_PHASE_SEL_BIT_7 = 0x3D
THR_DET_PHASE_SEL_BIT_7_MASK = 0x8000

THR_DET_PHASE_SEL_BIT_6 = 0x3D
THR_DET_PHASE_SEL_BIT_6_MASK = 0x4000

THR_DET_PHASE_SEL_BIT_5 = 0x3D
THR_DET_PHASE_SEL_BIT_5_MASK = 0x2000

THR_DET_PHASE_SEL_BIT_4 = 0x3D
THR_DET_PHASE_SEL_BIT_4_MASK = 0x1000

THR_DET_PHASE_SEL_BIT_3 = 0x3D
THR_DET_PHASE_SEL_BIT_3_MASK = 0x800

THR_DET_PHASE_SEL_BIT_2 = 0x3D
THR_DET_PHASE_SEL_BIT_2_MASK = 0x400

THR_DET_PHASE_SEL_BIT_1 = 0x3D
THR_DET_PHASE_SEL_BIT_1_MASK = 0x100

THR_DET_PHASE_SEL_BIT_8 = 0x3D
THR_DET_PHASE_SEL_BIT_8_MASK = 0x80

FIFO_EN_DEC = 0x3D
FIFO_EN_DEC_MASK = 0x40

DEC_EN = 0x3D
DEC_EN_MASK = 0x20

THR_DET_EN = 0x3D
THR_DET_EN_MASK = 0x10

DEC_FACTOR = 0x3D
DEC_FACTOR_MASK = 0xE

THR_DET_PHASE_SEL_BIT_0 = 0x3D
THR_DET_PHASE_SEL_BIT_0_MASK = 1

I_OFF_DAC_LED2_LSB_EXT = 0x3E
I_OFF_DAC_LED2_LSB_EXT_MASK = 0x1000

I_OFF_DAC_AMB_LSB_EXT = 0x3E
I_OFF_DAC_AMB_LSB_EXT_MASK = 0x800

I_OFF_DAC_LED1_LSB_EXT = 0x3E
I_OFF_DAC_LED1_LSB_EXT_MASK = 0x400

I_OFF_DAC_LED3_LSB_EXT = 0x3E
I_OFF_DAC_LED3_LSB_EXT_MASK = 0x100

I_OFF_DAC_LED2_MSB = 0x3E
I_OFF_DAC_LED2_MSB_MASK = 0x80

I_OFF_DAC_LED2_LSB = 0x3E
I_OFF_DAC_LED2_LSB_MASK = 0x40

I_OFF_DAC_AMB_MSB = 0x3E
I_OFF_DAC_AMB_MSB_MASK = 0x20

I_OFF_DAC_AMB_LSB = 0x3E
I_OFF_DAC_AMB_LSB_MASK = 0x10

I_OFF_DAC_LED1_MSB = 0x3E
I_OFF_DAC_LED1_MSB_MASK = 8

I_OFF_DAC_LED1_LSB = 0x3E
I_OFF_DAC_LED1_LSB_MASK = 4

I_OFF_DAC_LED3_MSB = 0x3E
I_OFF_DAC_LED3_MSB_MASK = 2

I_OFF_DAC_LED3_LSB = 0x3E
I_OFF_DAC_LED3_LSB_MASK = 1

AVG_LED2_MINUS_ALED2VAL = 0x3F
AVG_LED2_MINUS_ALED2VAL_MASK = 0xFFFFFF

AVG_LED1_MINUS_ALED1VAL = 0x40
AVG_LED1_MINUS_ALED1VAL_MASK = 0xFFFFFF

INT_MUX3 = 0x42
INT_MUX3_MASK = 0xC00000

INT_MUX2 = 0x42
INT_MUX2_MASK = 0x300000

FIFO_EARLY = 0x42
FIFO_EARLY_MASK = 0x7C000

REG_WM_FIFO = 0x42
REG_WM_FIFO_MASK = 0x3FC0

REG_FIFO_PERIOD = 0x42
REG_FIFO_PERIOD_MASK = 0x3FC0

INT_MUX1 = 0x42
INT_MUX1_MASK = 0x30

FIFO_PARTITION = 0x42
FIFO_PARTITION_MASK = 0xF

LED4LEDSTC = 0x43
LED4LEDSTC_MASK = 0xFFFF

LED4LEDENDC = 0x44
LED4LEDENDC_MASK = 0xFFFF

TG_PD1STC = 0x45
TG_PD1STC_MASK = 0xFFFF

TG_PD1ENDC = 0x46
TG_PD1ENDC_MASK = 0xFFFF

TG_PD2STC = 0x47
TG_PD2STC_MASK = 0xFFFF

TG_PD2ENDC = 0x48
TG_PD2ENDC_MASK = 0xFFFF

TG_PD3STC = 0x49
TG_PD3STC_MASK = 0xFFFF

TG_PD3ENDC = 0x4A
TG_PD3ENDC_MASK = 0xFFFF

EN_PROG_OUT1 = 0x4B
EN_PROG_OUT1_MASK = 0x100

CONTROL_DYN_VCM = 0x4B
CONTROL_DYN_VCM_MASK = 8

CONTROL_DYN_DLDO = 0x4B
CONTROL_DYN_DLDO_MASK = 4

CONTROL_DYN_ALDO = 0x4B
CONTROL_DYN_ALDO_MASK = 2

CONTROL_DYN_BG = 0x4B
CONTROL_DYN_BG_MASK = 1

TRIPLE_PD_ENABLE = 0x4E
TRIPLE_PD_ENABLE_MASK = 0x10

DUAL_PD_ENABLE = 0x4E
DUAL_PD_ENABLE_MASK = 8

SHORT_ALDO_TO_DLDO_IN_DEEP_SLEEP = 0x50
SHORT_ALDO_TO_DLDO_IN_DEEP_SLEEP_MASK = 0x20

CONTROL_DYN_TX_1 = 0x50
CONTROL_DYN_TX_1_MASK = 8

MASK_FIFO_RDY = 0x51
MASK_FIFO_RDY_MASK = 0x200

FORCE_FIFO_OFFSET = 0x51
FORCE_FIFO_OFFSET_MASK = 0x100

FIFO_OFFSET_TO_FORCE = 0x51
FIFO_OFFSET_TO_FORCE_MASK = 0xFF

DATA_RDY_STC = 0x52
DATA_RDY_STC_MASK = 0xFFFF

DATA_RDY_ENDC = 0x53
DATA_RDY_ENDC_MASK = 0xFFFF

MASK_PPG = 0x54
MASK_PPG_MASK = 0x7000

MASK1_PPG = 0x54
MASK1_PPG_MASK = 0x1C0

MASK2_PPG = 0x54
MASK2_PPG_MASK = 0x38

MASK3_PPG = 0x54
MASK3_PPG_MASK = 7

PROG_INT1_STC = 0x57
PROG_INT1_STC_MASK = 0xFFFF

PROG_INT1_ENDC = 0x58
PROG_INT1_ENDC_MASK = 0xFFFF

EN_AMB_LOOP = 0x60
EN_AMB_LOOP_MASK = 0x800

CHOOSE_AMB_PHASE = 0x60
CHOOSE_AMB_PHASE_MASK = 0x600

FREEZE_LOOP = 0x60
FREEZE_LOOP_MASK = 0x20

HYST_LOOP = 0x60
HYST_LOOP_MASK = 0x18

DYN_TIA_STC = 0x64
DYN_TIA_STC_MASK = 0xFFFF

DYN_TIA_ENDC = 0x65
DYN_TIA_ENDC_MASK = 0xFFFF

DYN_ADC_STC = 0x66
DYN_ADC_STC_MASK = 0xFFFF

DYN_ADC_ENDC = 0x67
DYN_ADC_ENDC_MASK = 0xFFFF

DYN_CLK_STC = 0x68
DYN_CLK_STC_MASK = 0xFFFF

DYN_CLK_ENDC = 0x69
DYN_CLK_ENDC_MASK = 0xFFFF

DEEP_SLEEP_STC = 0x6A
DEEP_SLEEP_STC_MASK = 0xFFFF

DEEP_SLEEP_ENDC = 0x6B
DEEP_SLEEP_ENDC_MASK = 0xFFFF

REG_POINTER_DIFF = 0x6D
REG_POINTER_DIFF_MASK = 0xFF

EN_DRV2_LED4 = 0x72
EN_DRV2_LED4_MASK = 0x80

EN_DRV2_LED3 = 0x72
EN_DRV2_LED3_MASK = 0x40

EN_DRV2_LED2 = 0x72
EN_DRV2_LED2_MASK = 0x20

EN_DRV2_LED1 = 0x72
EN_DRV2_LED1_MASK = 0x10

DIS_DRV1_LED4 = 0x72
DIS_DRV1_LED4_MASK = 8

DIS_DRV1_LED3 = 0x72
DIS_DRV1_LED3_MASK = 4

DIS_DRV1_LED2 = 0x72
DIS_DRV1_LED2_MASK = 2

DIS_DRV1_LED1 = 0x72
MASK_DIS_DRV1_LED1 = 1


current_fifo_toggle = 0
last_fifo_read = time.monotonic()

sample_count = 1
samples_to_average = 6
internal_osc_freq = 128000
clock_divisor = 1
pulse_rep_freq = 150


## legacy testing/proofing code
CSR_ADRS = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x31, 0x34, 0x35, 0x36, 0x37, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4E, 0x50, 0x51, 0x52, 0x53, 0x54, 0x57, 0x58, 0x60, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6D, 0x72]

# Get thewhole 24-bit value of a register by it's address
def readcsr(i2c, addr):
    readcsr = bytearray(3)
    i2c.writeto_then_readfrom(PPSI262_ADR, bytes([addr]), readcsr)
    value = int.from_bytes(readcsr, 'big')
    return value

# Set thewhole 24-bit value of a register by it's address
def writecsr(i2c, addr, value):
    writecsr = ((addr << 24) + value).to_bytes(4, 'big')
    i2c.writeto(PPSI262_ADR, writecsr)

# Read out the entire contents of the device's registers
def dumpcsrs(i2c):
    for address in CSR_ADRS:
        print(hex(address), ":", (readcsr(i2c, address)))




# Returns the index, counting from 0, of the least significant set bit in `x`.
def ffs(x):
    return (x&-x).bit_length()-1

# Invert the bits in a 24-bit (or otherwise specified) number
def bit_not(n, numbits=24):
    return (1 << numbits) - 1 - n

# Get the value of a specific register by it's name and mask
def register_get(i2c, addr, mask, shift=True):
    readcsr = bytearray(3)
    i2c.writeto_then_readfrom(PPSI262_ADR, bytes([addr]), readcsr)
    value = (int.from_bytes(readcsr, 'big') & mask)
    if (shift == True):
        value = value >> ffs(mask)
    return value

# Set the value of a specific register by it's name and mask
def register_set(i2c, addr, mask, value):
    old_value = register_get(i2c, addr, 0xFFFFFF, False)
    old_value = old_value & bit_not(mask)
    value = old_value | (value << ffs(mask))
    writecsr = ((addr << 24) | value).to_bytes(4, 'big')
    i2c.writeto(PPSI262_ADR, writecsr)

# Preform a software reset
def sw_reset(i2c):
    register_set(i2c, SW_RESET, SW_RESET_MASK, 1)

# read the FIFO
def read_fifo(i2c):
    global current_fifo_toggle, sample_count, samples_to_average, pulse_rep_freq, last_fifo_read
    """
    # wait until the FIFO is ready
    new_fifo_toggle = register_get(i2c, FIFO_TOGGLE, FIFO_TOGGLE_MASK)
    if (current_fifo_toggle == None):
        current_fifo_toggle = new_fifo_toggle

    while (current_fifo_toggle == new_fifo_toggle):
        new_fifo_toggle = register_get(i2c, FIFO_TOGGLE, FIFO_TOGGLE_MASK)
    current_fifo_toggle = new_fifo_toggle
    #time.sleep(0.0001)
    """
    time_now = time.monotonic()
    while (last_fifo_read > time_now):
        time_now = time.monotonic()
    last_fifo_read = time_now + samples_to_average/pulse_rep_freq

    # Force the FIFO read pointer to the beginning of the data
    #register_set(i2c, FORCE_FIFO_OFFSET, FORCE_FIFO_OFFSET_MASK, 1)
    #register_set(i2c, FIFO_OFFSET_TO_FORCE, FIFO_OFFSET_TO_FORCE_MASK, 0)

    led2_values = []
    led1_values = []

    readcsr = bytearray(6 * sample_count)
    i2c.writeto_then_readfrom(PPSI262_ADR, bytes([0xFF]), readcsr)

    for i in range(sample_count):
        j = i * 6
        led2_values.append(int.from_bytes(readcsr[j:(j+3)], 'big'))
        led1_values.append(int.from_bytes(readcsr[(j+3):(j+6)], 'big'))

    return [led1_values, led2_values]


# Initialize the sensor
def init_sensor(i2c):
    global current_fifo_toggle, sample_count, samples_to_average, internal_osc_freq, clock_divisor, pulse_rep_freq

    # reset the device
    sw_reset(i2c)

    time.sleep(0.01)


    # Divide the clock
    if (clock_divisor >= 16):
        register_set(i2c, CLKDIV_TE, CLKDIV_TE_MASK, 7)
        clock_divisor = 16
    elif (clock_divisor >= 8):
        register_set(i2c, CLKDIV_TE, CLKDIV_TE_MASK, 6)
        clock_divisor = 8
    elif (clock_divisor >= 4):
        register_set(i2c, CLKDIV_TE, CLKDIV_TE_MASK, 5)
        clock_divisor = 4
    elif (clock_divisor >= 2):
        register_set(i2c, CLKDIV_TE, CLKDIV_TE_MASK, 4)
        clock_divisor = 2
    else:
        register_set(i2c, CLKDIV_TE, CLKDIV_TE_MASK, 0)
        clock_divisor = 1

    clock_freq = internal_osc_freq / clock_divisor
    tick_period = 1000000 / clock_freq
    prf_count = int(clock_freq / pulse_rep_freq) - 1


    # get the current value of FIFO_TOGGLE (it alternates between 1 and 0 as FIFO_RDY is triggered)
    current_fifo_toggle = None #register_get(i2c, FIFO_TOGGLE, FIFO_TOGGLE_MASK)

    register_set(i2c, NUMAV, NUMAV_MASK, int(samples_to_average - 1))  # Set the ADC output to be the average of [samples_to_average] samples

    # Setup LED current drivers and switching
    register_set(i2c, ILED_FS, ILED_FS_MASK, 1)             # Set the full-scale output of the LED current driver to 100mA (set to 0 for 50mA)
    register_set(i2c, EN_DRV2_LED1, EN_DRV2_LED1_MASK, 1)   # Enable the second current dirver for LED1 (Green)
    register_set(i2c, EN_DRV2_LED2, EN_DRV2_LED2_MASK, 1)   # Enable the second current dirver for LED1 (IR)

    # Green LED (LED1) - Should output 150mA according to datasheet
    register_set(i2c, ILED1_MSB, ILED1_MSB_MASK, 63)        # LED1's current to 100mA * 2 drivers = 200mA (high bits)
    register_set(i2c, ILED1_LSB, ILED1_LSB_MASK, 3)         # LED1's current to 100mA * 2 drivers = 200mA (low bits)

    # IR LED (LED2) - Should output 100 mA according to datasheet
    register_set(i2c, ILED2_MSB, ILED2_MSB_MASK, 63)        # LED2's current to 75mA * 2 drivers = 150mA (high bits)
    register_set(i2c, ILED2_LSB, ILED2_LSB_MASK, 3)         # LED2's current to 75mA * 2 drivers = 150mA (low bits)

    # Turn off LED3 and LED4 - Not needed because they are off by default
    #register_set(i2c, ILED3_MSB, ILED3_MSB_MASK, 0)        # LED3's current to OFF (high bits)
    #register_set(i2c, ILED3_LSB, ILED3_LSB_MASK, 0)        # LED3's current to OFF (low bits)
    #register_set(i2c, ILED4_MSB, ILED4_MSB_MASK, 0)        # LED4's current to OFF (high bits)
    #register_set(i2c, ILED4_LSB, ILED4_LSB_MASK, 0)        # LED4's current to OFF (low bits)

    # Determine the sampling rate for the sensor (relative to the PRF?) - all 4 should be set to idential values
    register_set(i2c, MASK_PPG, MASK_PPG_MASK, 0b0)         # 3 bits wide - no idea what this does.
    register_set(i2c, MASK1_PPG, MASK1_PPG_MASK, 0b0)
    register_set(i2c, MASK2_PPG, MASK2_PPG_MASK, 0b0)
    register_set(i2c, MASK3_PPG, MASK3_PPG_MASK, 0b0)

    # Set the TIA (trans-impedence amplifier) gain
    register_set(i2c, TIA_GAIN_LSB, TIA_GAIN_LSB_MASK, 0b011)  # 3-bits (LSB) - resistor value
    register_set(i2c, TIA_GAIN_MSB, TIA_GAIN_MSB_MASK, 0)      # 1-bit (MSB)
    register_set(i2c, TIA_CF, TIA_CF_MASK, 0b000)              # 3-bits - capacitor value

    # Setup the FIFO
    register_set(i2c, FIFO_PARTITION, FIFO_PARTITION_MASK, 5)  # store (LED2—Ambient2), (LED1—Ambient1) ADC values
    register_set(i2c, REG_FIFO_PERIOD, REG_FIFO_PERIOD_MASK, sample_count) # retain [sample_count] sample cycles
    register_set(i2c, FIFO_EN, FIFO_EN_MASK, 1)                # turn on the FIFO



    active_phase_start = int(520 / tick_period) + 1

    led_on_width = int(70 / tick_period) + 1
    sampling_start_delay = int(30 / tick_period) + 1
    sampling_width = int(35 / tick_period) + 1
    convert_start_delay = led_on_width + 2
    convert_width = int((56.5 * samples_to_average + 72) / tick_period) + 16 #+ 4

    phase_width = convert_start_delay + convert_width + 4 #+ led_on_width

    phase_0_start = 0 + active_phase_start
    phase_1_start = phase_width * 1 + active_phase_start
    phase_2_start = phase_width * 2 + active_phase_start
    phase_3_start = phase_width * 3 + active_phase_start

    ##  TODO:
    #   If active_phase_end is greater than the PRF count, throw an error
    #   Set up deep sleep behavior options
    #   Set up external oscillator options

    dont_activate = prf_count + 16

    # Set the sensor to run a 500Hz PRF (Pulse Repetition Frequency) cycle
    register_set(i2c, PRPCOUNT, PRPCOUNT_MASK, prf_count)

    register_set(i2c, ENABLE_ULP, ENABLE_ULP_MASK, 1)

    register_set(i2c, LED2LEDSTC, LED2LEDSTC_MASK, phase_0_start)
    register_set(i2c, LED2LEDENDC, LED2LEDENDC_MASK, phase_0_start + led_on_width)
    register_set(i2c, LED2STC, LED2STC_MASK, phase_0_start + sampling_start_delay)
    register_set(i2c, LED2ENDC, LED2ENDC_MASK, phase_0_start + sampling_start_delay + sampling_width)
    register_set(i2c, LED2CONVST, LED2CONVST_MASK, phase_0_start + convert_start_delay)
    register_set(i2c, LED2CONVEND, LED2CONVEND_MASK, phase_0_start + convert_start_delay + convert_width)

    register_set(i2c, LED3LEDSTC, LED3LEDSTC_MASK, dont_activate)      # Don't turn on
    register_set(i2c, LED3LEDENDC, LED3LEDENDC_MASK, dont_activate)    # Don't turn on
    register_set(i2c, ALED2STC, ALED2STC_MASK, phase_1_start + sampling_start_delay)
    register_set(i2c, ALED2ENDC, ALED2ENDC_MASK, phase_1_start + sampling_start_delay + sampling_width)
    register_set(i2c, ALED2CONVST, ALED2CONVST_MASK, phase_1_start + convert_start_delay)
    register_set(i2c, ALED2CONVEND, ALED2CONVEND_MASK, phase_1_start + convert_start_delay + convert_width)

    register_set(i2c, LED1LEDSTC, LED1LEDSTC_MASK, phase_2_start)
    register_set(i2c, LED1LEDENDC, LED1LEDENDC_MASK, phase_2_start + led_on_width)
    register_set(i2c, LED1STC, LED1STC_MASK, phase_2_start + sampling_start_delay)
    register_set(i2c, LED1ENDC, LED1ENDC_MASK, phase_2_start + sampling_start_delay + sampling_width)
    register_set(i2c, LED1CONVST, LED1CONVST_MASK, phase_2_start + convert_start_delay)
    register_set(i2c, LED1CONVEND, LED1CONVEND_MASK, phase_2_start + convert_start_delay + convert_width)

    register_set(i2c, LED4LEDSTC, LED4LEDSTC_MASK, dont_activate)      # Don't turn on
    register_set(i2c, LED4LEDENDC, LED4LEDENDC_MASK, dont_activate)    # Don't turn on
    register_set(i2c, ALED1STC, ALED1STC_MASK, phase_3_start + sampling_start_delay)
    register_set(i2c, ALED1ENDC, ALED1ENDC_MASK, phase_3_start + sampling_start_delay + sampling_width)
    register_set(i2c, ALED1CONVST, ALED1CONVST_MASK, phase_3_start + convert_start_delay)
    register_set(i2c, ALED1CONVEND, ALED1CONVEND_MASK, phase_3_start + convert_start_delay + convert_width)


    register_set(i2c, DATA_RDY_STC, DATA_RDY_STC_MASK, phase_3_start + convert_start_delay + convert_width + 6)
    register_set(i2c, DATA_RDY_ENDC, DATA_RDY_ENDC_MASK, phase_3_start + convert_start_delay + convert_width + 7)

    # Active phase start and end timings
    register_set(i2c, DYN_TIA_STC, DYN_TIA_STC_MASK, 0)
    register_set(i2c, DYN_TIA_ENDC, DYN_TIA_ENDC_MASK, dont_activate)
    register_set(i2c, DYN_ADC_STC, DYN_ADC_STC_MASK, 0)
    register_set(i2c, DYN_ADC_ENDC, DYN_ADC_ENDC_MASK, dont_activate)
    register_set(i2c, DYN_CLK_STC, DYN_CLK_STC_MASK, 0)
    register_set(i2c, DYN_CLK_ENDC, DYN_CLK_ENDC_MASK, dont_activate)

    # Deep sleep behavior
    #register_set(i2c, CONTROL_DYN_TIA, CONTROL_DYN_TIA_MASK, 0)
    #register_set(i2c, CONTROL_DYN_ADC, CONTROL_DYN_ADC_MASK, 0)
    #register_set(i2c, CONTROL_DYN_ALDO, CONTROL_DYN_ALDO_MASK, 0)
    #register_set(i2c, CONTROL_DYN_DLDO, CONTROL_DYN_DLDO_MASK, 0)
    #register_set(i2c, SHORT_ALDO_TO_DLDO_IN_DEEP_SLEEP, SHORT_ALDO_TO_DLDO_IN_DEEP_SLEEP_MASK, 1)

    # Deep sleep phase start and end timings
    register_set(i2c, DEEP_SLEEP_STC, DEEP_SLEEP_STC_MASK, dont_activate)    # Don't go into deep sleep
    register_set(i2c, DEEP_SLEEP_ENDC, DEEP_SLEEP_ENDC_MASK, dont_activate)  # Don't go into deep sleep

    # Enable the internal oscillator
    register_set(i2c, OSC_ENABLE, OSC_ENABLE_MASK, 1)    # Turn on the internal oscillator



def start_sensor(i2c):
    # start the timer to begin operation
    register_set(i2c, TIMEREN, TIMEREN_MASK, 1)

def stop_sensor(i2c):
    # start the timer to begin operation
    register_set(i2c, TIMEREN, TIMEREN_MASK, 0)


i2c = busio.I2C(scl=board.GP21, sda=board.GP20)
i2c.try_lock()

init_sensor(i2c)

time.sleep(0.1)

start_sensor(i2c)
readings = [[],[], []]

start_time = time.monotonic()

#for i in range(300):
avg1 = 0
avg0 = 0
count_total = 0

last_reading = [[0,0,0],[0,0,0]]

for i in range(30):
    sensor_output = read_fifo(i2c)
    avg1 = sensor_output[1][0]
    avg0 = sensor_output[0][0]
    last_reading[0].append(sensor_output[0][0])
    last_reading[0].pop(0)
    last_reading[1].append(sensor_output[1][0])
    last_reading[1].pop(0)

while True:
    count_total = count_total + 1
    if (count_total > 20):
        count_total = 20
    sensor_output = read_fifo(i2c)
    
    last_reading[0].append(sensor_output[0][0])
    last_reading[0].pop(0)
    last_reading[1].append(sensor_output[1][0])
    last_reading[1].pop(0)

    avg0 = (avg0 * count_total + sensor_output[0][0]) / (count_total + 1)
    avg1 = (avg1 * count_total + sensor_output[1][0]) / (count_total + 1)

    print((ulab.numpy.mean(last_reading[0]) - avg0,  + (ulab.numpy.mean(last_reading[1]) - avg1) * 10))
    #readings[0].append(sensor_output[0])
    #readings[1].append(sensor_output[1])
    #readings[2].append([time.monotonic() - start_time] * sample_count)


time.sleep(0.05)

stop_sensor(i2c)

print("sensor output")
print(readings)


## Dump out everything before and after software reset
#
#dumpcsrs(i2c)
#sw_reset(i2c)
#dumpcsrs(i2c)


i2c.unlock()
i2c.deinit()

@matzelectronics Which board did you used while making this project? Also, Can you share any schematic related to it.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.