Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
14rallen opened this issue Dec 19, 2022 · 1 comment

Comments

@14rallen
Copy link

14rallen commented Dec 19, 2022

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.

@kevinjwalters
Copy link

kevinjwalters commented Aug 6, 2024

I get this after maybe 10 minutes of running on a PyPortal (now set to 3.3V power on 4 pin connector) with a 20cm lead to a (Pimoroni) MLX90640 with a fresh library. I'm running at 4Hz setting. I'm reading it at about 1.6Hz as my display updates take a while.

The math domain error is at line 311

Sx = math.sqrt(math.sqrt(Sx)) * self.ksTo[1]

I'd guess some bad data comes back and a negative value ends up going into that square root function.

I'm going to try catching the ValueError , pause for a bit and then retry as a workaround...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants