adafruit / Adafruit_CircuitPython_MLX90640

A pure Python MLX90640 driver
MIT License
65 stars 20 forks source link

i2c.write_then_readinto slows down frame rate after running the library for a couple seconds at 64Hz #29

Open Stephane3296 opened 2 years ago

Stephane3296 commented 2 years ago

I have been trying to get the sensor to run as close to 60hz as possible however I have recently run into a problem. After modifying the library a little bit using the code from chimajero in (https://github.com/adafruit/Adafruit_CircuitPython_MLX90640/issues/22), I have managed a frame rate of roughly 57 FPS, however, after a few seconds, this frame rate drops slowly down to the '30s. I narrowed the code down to the _I2CReadWrods function and the line, i2c.write_then_readinto(), taking the most time and slowing down the rest of the program. This can be seen in the Line Profiler data shown below.

I know next to nothing about the i2c bus or how to interact with it so if anyone has any idea what may be happening, or how to speed up this process, it would be greatly appreciated. If you need any more clarification or need the code for the slightly modified library I would be glad to provide it.

Thank you!

Edit: Another thing to note is that when the end value is changed in i2c.write_then_readinto(addrbuf, inbuf, in_end=read_words * 2) to a smaller value under 300 (I used 256 as its just 768/3, end=256) the frame rate stayed the same and did not lower leading me to believe the problem is the amount of data taken from the i2c bus. This is just my guess.

Line Profiler Data within the first 5 seconds. before 5 seconds

Line Profiler Data after around 5 seconds has passed. After 5 seconds

tekktrik commented 2 years ago

Any luck with using a higher I2C frequency? https://docs.circuitpython.org/en/latest/shared-bindings/busio/index.html#busio.I2C If it is something to do with the I2C comms, that might help, but just a potshot.

Stephane3296 commented 2 years ago

I have the I2C frequency set to 1000000 Hz (1 MHz) in my Raspberry Pi 4 4Gb, sudo nano /boot/config.txt folder. The line of code looks like this dtparam=i2c_arm=on,i2c_arm_baudrate=1000000. I also have the line of code that sets the frequency in the code shown here, i2c = busio.I2C(board.SCL, board.SDA, frequency=1000000) # setup I2C

I'll give it a shot upping it to 1.2 MHz and ill max out at 1.5MHz, I'll edit this comment with the results shortly.

Results: The problem still occurs when I increase the frequency to 1.5MHz using the i2c= code mentioned above.

Potential workaround for my specific condition: My goal is to use the sensor to measure brake rotor temperature on a car, not every pixel of the sensor will be reading the rotor temperature due to its positioning. If I were to reduce the number of pixels read to under 256 (My calculated limit ish). Then I could use it at its highest FPS. This will need alot of tinkering with the library but I feel like it can get done.

I don't want to resort to this as I would like to figure out how to use all the sensor pixels at a high frame rate for other potential applications and incase anyone else needs this kind of speed for their projects, but my workaround is like a last resort.