Help with AS7331 on I2C

Hello, I’m trying to use the AS7331 UV sensor on my R7 Plus, with no success.
The same sensor works fine when connected to Flipper Zero (so it is not a problem with the senor), but on OpenMV it simply cannot produce a “data ready” value (drdy flag always False). If I force printing the readings, I get overflow-like values.

I suspect I have a problem with registry writing during initialization. Indeed, the following code tries to write then read registers, but fails getting the same values.

from machine import SoftI2C, Pin
import time

# Sensor I2C Address
AS7331_ADDR = 0x74

# Configuration registers
CTRL_REG = 0x01
CREG1 = 0x02  # Gain
CREG2 = 0x03  # Temps d'intégration (tconv)
CREG3 = 0x04  # Horloge interne (cclk)
ID_REG = 0x0D

# Parameters to test
GAIN = 0x00    # Gain 1x
TCONV = 0x01   # integration 0.25 ms
CCLK = 0x00    # default clock

# Initialization I2C 
i2c = SoftI2C(sda=Pin("P5"), scl=Pin("P4"))

def reset_and_configure(gain, tconv, cclk):
    # Reset
    i2c.writeto_mem(AS7331_ADDR, CTRL_REG, b'\x80')
    time.sleep_ms(150)
    # ID Verification
    dev_id = i2c.readfrom_mem(AS7331_ADDR, ID_REG, 1)[0]
    print("Device ID:", hex(dev_id))
    # Configuration
    i2c.writeto_mem(AS7331_ADDR, CREG1, bytes([gain]))
    i2c.writeto_mem(AS7331_ADDR, CREG2, bytes([tconv]))
    i2c.writeto_mem(AS7331_ADDR, CREG3, bytes(cclk))
    # verification
    print("Gain:", i2c.readfrom_mem(AS7331_ADDR, CREG1, 1)[0])
    print("Tconv:", i2c.readfrom_mem(AS7331_ADDR, CREG2, 1)[0])
    print("Cclk:", i2c.readfrom_mem(AS7331_ADDR, CREG3, 1)[0])

reset_and_configure(0x09, 0x80, 0x00)  # Exemple: gain 512x, int. 128ms

Output:

Device ID: 0xff
Gain: 33
Tconv: 0
Cclk: 255

I tried with both pyb and machine libraries (I2C and SoftI2C classes), always with the same result.

Do you have any hint to help me?

Best regards,
Angelo

Do you have pull ups on the I2C lines?

Yes. The sensor spec show 10k pullup resistors (and in doubt, I soldered other 10k resistors in a second sensor, with the same result → both work on Flipper Zero, not on OpenMV).

I tried also several frequencies, cable change (I use 10cm long wires). Also tried P7 and P8 using SoftI2C.

Is there a way to try a c library (such as the one from Sparkfun with some modifications)?

Sounds like an electrical issue. I’d try to scan the bus first:

See if the address you expect responds.

There are no issues with I2C support on the board. It not working is something else.

Well, I currently gave up on using AS7331 with OpenMV. After successfully trying the sensor on Flipper Zero and on a ESP8266, I believe the problem comes from my code.

Indeed, ESP8266 can rely on the SparkFun library that does all the “low level talk”, and Flipper Zero has its own library version based on SparkFun.

While I tried to port the library to Micropython, my knowledge is insufficient. LLMs like ChatGPT or Perplexity cannot produce a working version either…

So, I’m forced to wait until someone else publishes a working code.
If you have it, please send me a message :star_struck:

Did you try the scan() command as I mentioned?

yes, I see the device, with the same address used in ESP8266.
Reading both Sparkfun library and the specs, the initialization sequence is quite complex, so probably the fault is on my lack of hability to program it. I’ll give a try later, during the summer break.