melexis / mlx90640-library

MLX90640 library functions
Apache License 2.0
232 stars 186 forks source link

MLX90640 and RaspberryPi4-Pythonscript: cannot get sensor data for above 4Hz #67

Open mbobinger opened 4 years ago

mbobinger commented 4 years ago

Dear Melexis-fellows

I know this is not a question specifically related to this library but to the MLX90640 and I've tried some things already. I've followed the MLX90640 tutorial from Adafruit on an RPI4 and all code examples work fine for me: https://github.com/adafruit/Adafruit_CircuitPython_MLX90640/

However, as soon as I try to set: mlx.refresh_rate = adafruit_mlx90640.RefreshRate.REFRESH_16_HZ the refresh rate to higher than 4Hz, tried for 8, 16, 32 and 64Hz, I receive the following error msg (please also see attached IMG):

`raise RuntimeError("Too many retries") RuntimeError: Too many retries

%Run mlx90640.py MLX addr detected on I2C ['0x1627', '0x8e69', '0x187'] Traceback (most recent call last): File "/home/pi/FTP/code/mlx90640/mlx90640.py", line 16, in mlx.getFrame(frame) File "/usr/local/lib/python3.7/dist-packages/adafruit_mlx90640.py", line 143, in getFrame status = self._GetFrameData(mlx90640Frame) File "/usr/local/lib/python3.7/dist-packages/adafruit_mlx90640.py", line 172, in _GetFrameData raise RuntimeError("Too many retries") RuntimeError: Too many retries`

20200511_mlx90640_adafruit

This error has been discussed previously: https://github.com/melexis/mlx90640-library/issues/57 and was already somehow addressed by Melexis in an update.

And on the adafruit forum: https://forums.adafruit.com/viewtopic.php?f=19&p=808699

The problem seems to be clearly that the sensor status can not be requested: `def _GetFrameData(self, frameData): dataReady = 0 cnt = 0 statusRegister = [0] controlRegister = [0]

    while dataReady == 0:
        self._I2CReadWords(0x8000, statusRegister)
        dataReady = statusRegister[0] & 0x0008
        # print("ready status: 0x%x" % dataReady)

    while (dataReady != 0) and (cnt < 5):
        self._I2CWriteWord(0x8000, 0x0030)
        # print("Read frame", cnt)
        self._I2CReadWords(0x0400, frameData, end=832)

        self._I2CReadWords(0x8000, statusRegister)
        dataReady = statusRegister[0] & 0x0008
        # print("frame ready: 0x%x" % dataReady)
        cnt += 1

    if cnt > 4:
        raise RuntimeError("Too many retries")`

Changing the bus speeds of I2C from 0.8MHz to 1.5Mhz didn't help either (nor lowering of course): i2c = busio.I2C(board.SCL, board.SDA, frequency=15000000)

Please have a look at my setup, I've used long and then short SDA, SCL wires to avoid crosstalk - didn't help. Always 8Hz was the limit. 20200510_mlx_90640_rpi_setup2 20200510_mlx_90640_rpi_setup1pg

Thank you!

mlx-kva commented 4 years ago

I have 4 comments:

mbobinger commented 4 years ago

Thank you mlx-kva! After setting the baudrate for I2C in /boot/config.txt, the 16Hz setting of the adafruit library worked for me. I'm now switching to your library as it obviously makes more sense to use the manufacturer library :). I haven't added the decoupling capacitors, which I will also do now.

To my knowledge, RPI uses 1.8kOhm pullups on SDA and SCL, which seems a bit low to me: https://elinux.org/RPi_Low-level_peripherals

I'll move on with the prototyping and keep you posted. More people seem to have had problems with the i2c bus.

Zhang-xie commented 1 year ago

Hi @mbobinger, I am working on using raspberry pi to read the sensor's data. However, I can only get the data on 8 Hz refresh rates. I want to know the details of your solution. Thank you so much.