Четыре тепловизионные камеры MLX90640 на 4 нестандартных шинах Raspberry Pi 5BPython

Программы на Python
Ответить
Anonymous
 Четыре тепловизионные камеры MLX90640 на 4 нестандартных шинах Raspberry Pi 5B

Сообщение Anonymous »

Я новичок в Python. С помощью второго пилота GitHub и некоторых базовых навыков программирования я пытаюсь запустить 4 тепловизионные камеры одновременно с частотой не менее 4 Гц (в идеале, если возможно, 16 Гц).
Я попробовал запустить 4 камеры. через мультиплексор TCA9548A, но максимальная скорость, которую я получаю, составляет всего около 0,5 Гц. Это не вариант.
В качестве альтернативы я обнаружил, что могу создать 4 собственные шины (шина I2C по умолчанию используется датчиком температуры).
В качестве примера прикрепил конфиг для 3 шины и далее по примеру кода для 1 камеры. Я создал шину 3, используя следующую конфигурацию в config.txt в pi:
dtoverlay=i2c-gpio,bus=3,i2c_gpio_sda=16,i2c_gpio_scl=26

Используя i2cdetect, я могу обнаружить ИК-камеру по адресу 0x33 на этой шине.
Проблема в том, что при инициализации камер я не получаю какие-либо данные от них.
Как мне действовать?
Код для 1 камеры приведен ниже
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")

Я получаю ошибку ниже
Detected I2C devices: ['0x33']
Traceback (most recent call last):
File "/home/mateusz/ThermalPi_data/ThermalPI/thermal_scripts/pull_one_camera.py", line 73, in
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 $


Подробнее здесь: https://stackoverflow.com/questions/793 ... erry-pi-5b
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»