Reputation: 1
I am quite new to Python. With help of GitHub copilot and some basic programming skills I am trying to run 4 thermal cameras at the same time with at least 4Hz frequency (Ideally 16Hz if possible).
I tried running 4 cameras via TCA9548A multiplexer but the max speed I get is only about 0.5Hz. This is not an option.
As alternative I found that I could create custom 4 buses (default I2C bus is taken by temperature sensor).
As an example I attached the config for bus 3 and further along an example of code for 1 camera. I created bus 3 using following config in config.txt in pi:
dtoverlay=i2c-gpio,bus=3,i2c_gpio_sda=16,i2c_gpio_scl=26
Using i2cdetect I can detect IR camera under 0x33 address on this bus.
The challenge is that when I initialize the cameras I don't get any data from them.
How can I proceed?
Code for 1 camera pull below
import time
import smbus2
import adafruit_mlx90640
import ctypes
class SMBusWrapper:
def __init__(self, bus):
self.bus = smbus2.SMBus(bus)
self.locked = False
def try_lock(self):
if not self.locked:
self.locked = True
return True
return False
def unlock(self):
self.locked = False
def writeto(self, address, buffer, stop=True):
if len(buffer) > 1:
self.bus.write_i2c_block_data(address, buffer[0], list(buffer[1:]))
elif len(buffer) == 1:
self.bus.write_byte(address, buffer[0])
else:
# Handle empty buffer case gracefully
self.bus.write_byte(address, 0)
def readfrom_into(self, address, buffer, stop=True):
chunk_size = 32 # Maximum block length for SMBus
for i in range(0, len(buffer), chunk_size):
chunk = self.bus.read_i2c_block_data(address, 0, min(chunk_size, len(buffer) - i))
buffer[i:i + len(chunk)] = chunk
def writeto_then_readfrom(self, address, buffer_out, buffer_in, out_start=0, out_end=None, in_start=0, in_end=None):
if out_end is None:
out_end = len(buffer_out)
if in_end is None:
in_end = len(buffer_in)
self.writeto(address, buffer_out[out_start:out_end])
self.readfrom_into(address, buffer_in[in_start:in_end])
# Initialize I2C bus 3 using SMBusWrapper
i2c_bus = SMBusWrapper(3)
# Function to scan I2C bus and check for devices
def scan_i2c_bus(bus):
devices = []
for address in range(128):
try:
bus.bus.read_byte(address)
devices.append(address)
except OSError:
pass
return devices
# Scan the I2C bus and print detected devices
detected_devices = scan_i2c_bus(i2c_bus)
print(f"Detected I2C devices: {[hex(device) for device in detected_devices]}")
# Function to initialize the sensor and handle errors
def initialize_sensor(bus):
try:
sensor = adafruit_mlx90640.MLX90640(bus)
sensor.refresh_rate = adafruit_mlx90640.RefreshRate.REFRESH_4_HZ
print("Sensor initialized successfully")
return sensor
except ValueError as e:
print(f"Error initializing sensor: {e}")
return None
# Initialize the MLX90640 sensor on I2C bus 3
sensor = initialize_sensor(i2c_bus)
if sensor:
try:
frame_data = (ctypes.c_uint16 * 834)() # Initialize frame_data with zeros
while True:
print("Getting frame data...")
result = sensor._GetFrameData(ctypes.byref(frame_data)) # Pass frame_data by reference
print("Frame data request result:", result)
if result != 0:
raise RuntimeError(f"Failed to get frame data: {result}")
print("Frame data acquired.")
print(f"Frame data length: {len(frame_data)}")
print(f"Frame data content: {list(frame_data)[:10]}...") # Print first 10 elements for brevity
time.sleep(0.25) # 4Hz acquisition rate
except Exception as e:
print(f"Error acquiring data: {e}")
else:
print("Failed to initialize the sensor")
I get error below
Detected I2C devices: ['0x33']
Traceback (most recent call last):
File "/home/mateusz/ThermalPi_data/ThermalPI/thermal_scripts/pull_one_camera.py", line 73, in <module>
sensor = initialize_sensor(i2c_bus)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/mateusz/ThermalPi_data/ThermalPI/thermal_scripts/pull_one_camera.py", line 64, in initialize_sensor
sensor = adafruit_mlx90640.MLX90640(bus)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/mateusz/ThermalPi_data/ThermalPI/venv/lib/python3.11/site-packages/adafruit_mlx90640.py", line 97, in __init__
self._ExtractParameters()
File "/home/mateusz/ThermalPi_data/ThermalPI/venv/lib/python3.11/site-packages/adafruit_mlx90640.py", line 361, in _ExtractParameters
self._ExtractAlphaParameters()
File "/home/mateusz/ThermalPi_data/ThermalPI/venv/lib/python3.11/site-packages/adafruit_mlx90640.py", line 547, in _ExtractAlphaParameters
alphaTemp[p] = SCALEALPHA / alphaTemp[p]
~~~~~~~~~~~^~~~~~~~~~~~~~
ZeroDivisionError: float division by zero
(venv) (base) mateusz@mmpi:~/ThermalPi_data/ThermalPI $
Upvotes: 0
Views: 31