adafruit/Adafruit_CircuitPython_MLX90640

Unable to get pixels after some time until I reset program, using Raspberry Pi 3B+ (math domain error, More than 4 outlier pixels)

Opened this issue · 0 comments

My Python code:

import board
import busio
import adafruit_mlx90640

class IR_Sensor():

      def get_pixels(self):
             try:
                  i2c = busio.I2C(board.SCL, board.SDA, frequency=400000)
                  mlx = adafruit_mlx90640.MLX90640(i2c)
                  mlx.refresh_rate = adafruit_mlx90640.RefreshRate.REFRESH_4_HZ
                  mlx.getFrame(pixels)
                  self.ir_connected = True
              except Exception as e:
                  self.ir_connected = False
                  pixels = None
                  self.controller.log_error('Could not read from IR Sensor: {}'.format(str(e)), ERR_IR_READING)

I have a SparkFun Qwiik IR Array MLX90640 attached to a Raspberry Pi 3B+ with 15 foot wiring. I have changed the I2C frequency in the Pi to 400,000 Hz. I have this code running in a continuous loop in a thread. The camera works, I'm able to read the pixels and display an image using its values. After some time (2 hours or so), mlx.getFrame() will fail and Exception e will show 'math domain error' and then 'More than 4 outlier pixels.' I can fix this simply by ending the program, then starting it again, and the camera will work again for some time, until I get this error again. I need to be able to have this program run for days/weeks at a time, and resetting the program every time getFrame() fails will not do.

I am unable to figure out if this is an issue with the camera, the Pi, or the code. I'm kind of hoping there is a way programmatically to mimic the actions of me restarting the program/camera without actually restarting.

I can also replicate the 'More than 4 outlier pixels' error by unplugging and plugging the camera back into the Pi. I can unplug and plug back in a handful of times, then after the 4th-8th plug in, the Exception occurs, fixed again by restarting the program.

Edit 1:

While re-reading my post, I may have come up with a programmatic solution that I'm going to test. Every time the exception occurs, I'm going to stop the thread that calls get_pixels(), and in my controller class (which keeps an instance of IR_Sensor) I'm going to assign a new instance of IR_Sensor.

Edit 2:

Edit 1 was not working how I expected, so in conjunction with Edit 1, I added the code below to reset I2C every time the exception occurs. Make sure I2C is currently not in use or the 'modprobe -r i2c_dev' command will not work. I don't think Edit 1 is necessary now, but I'm leaving it in because my program is working.

import os

       os.system('sudo modprobe -r i2c_dev')
       os.system('sudo modprobe -r i2c_bcm2708')

       os.system('sudo modprobe i2c_bcm2708')
       os.system('sudo modprobe i2c_dev')

I left my program on overnight and came back to the camera working correctly. In the span of 17 hours, getFrame() raised the exception 'math domain error' 9 times, once every 30 to 120 minutes. So the camera does not work properly for a few seconds once every 30 to 120 minutes. This is acceptable for my purposes, but I'd rather not have this happen at all.

Edit 3:

The previous method is no longer working and I cannot figure out why.