树莓派硬件类中初始化Picamera2失败问题排查
问题:树莓派Picamera2跨模块实例化类时初始化失败
在树莓派上开发Python机器人,将所有硬件交互整合到Hardware类后,除Picamera2外其他硬件均正常工作。直接在IDLE中运行该类文件无问题,但在其他模块中实例化类时抛出以下错误:
Traceback (most recent call last): File "/home/sox/Documents/Sox/main.py", line 6, in <module> soxHardware = Hardware() File "/home/sox/Documents/Sox/utils/HardwareUtils.py", line 72, in __init__ self.picam2 = Picamera2() File "/usr/lib/python3/dist-packages/picamera2/picamera2.py", line 249, in __init__ raise RuntimeError("Camera __init__ sequence did not complete.") RuntimeError: Camera __init__ sequence did not complete.
相关代码
Hardware类代码
#NOTE: ALL FUNCTIONS CAN BE BYPASSED #Just call the object directly #import time import board import digitalio import time #for battery import smbus import struct #for gyro import adafruit_mpu6050 #for touch import adafruit_mpr121 #for servoDriver from adafruit_pca9685 import PCA9685 from adafruit_motor import servo #for camera from picamera2 import Picamera2 class Hardware: def __init__(self): #setup all IO ports self.ledRed = digitalio.DigitalInOut(board.D11) self.ledGreen = digitalio.DigitalInOut(board.D9) self.ledBlue = digitalio.DigitalInOut(board.D10) self.ledEars = digitalio.DigitalInOut(board.D22) self.ledLaser = digitalio.DigitalInOut(board.D27) self.speakerMute = digitalio.DigitalInOut(board.D17) #set port direction as output self.ledRed.direction = digitalio.Direction.OUTPUT self.ledGreen.direction = digitalio.Direction.OUTPUT self.ledBlue.direction = digitalio.Direction.OUTPUT self.ledEars.direction = digitalio.Direction.OUTPUT self.ledLaser.direction = digitalio.Direction.OUTPUT self.speakerMute.direction = digitalio.Direction.OUTPUT #i2c setup i2c = board.I2C() # uses board.SCL and board.SDA #gyro self.gyro = adafruit_mpu6050.MPU6050(i2c, 0x69) #touch self.touch = adafruit_mpr121.MPR121(i2c) #servoDriver pca = PCA9685(i2c) pca.frequency = 50 self.servo0 = servo.Servo(pca.channels[0]) #battery self.I2C_ADDR = 0x36 self.bus = smbus.SMBus(1) # 0 = /dev/i2c-0 (port I2C0), 1 = /dev/i2c-1 (port I2C1) #set up camera self.picam2 = Picamera2() camera_config = self.picam2.create_preview_configuration() self.picam2.configure(camera_config) self.picam2.start() time.sleep(2) def readVoltage(self): read = self.bus.read_word_data(self.I2C_ADDR, 2) swapped = struct.unpack("<H", struct.pack(">H", read))[0] voltage = swapped * 1.25 /1000/16 return voltage def readCapacity(self): read = self.bus.read_word_data(self.I2C_ADDR, 4) swapped = struct.unpack("<H", struct.pack(">H", read))[0] capacity = swapped/256 return capacity def laser(self, status): self.ledLaser.value = status return True def flashlight(self, status): self.ledRed.value = status self.ledGreen.value = status self.ledBlue.value = status return True def ears(self, status): self.ledEars.value = status return True def muteSpeaker(self, status): self.speakerMute.value = status return True def checkBatteryStatus(self): print(self.readVoltage()) print(self.readCapacity()) return True def readGyro(self): print("Acceleration: X:%.2f, Y: %.2f, Z: %.2f m/s^2" % (self.gyro.acceleration)) print("Gyro X:%.2f, Y: %.2f, Z: %.2f rad/s" % (self.gyro.gyro)) print("Temperature: %.2f C" % self.gyro.temperature) print("") def getTouch(self, index): return self.touch[index].value def getTouchArray(self): array = [False]*12 for i in range(12): array[i] = self.touch[i].value return array def takeImage(self,path): self.picam2.capture_file(path) if __name__ == '__main__': hardware=Hardware() hardware.checkBatteryStatus() hardware.readGyro() print(hardware.getTouch(0)) print(hardware.getTouchArray()) hardware.takeImage("img.png") while True: hardware.servo0.angle = 0 time.sleep(1) hardware.servo0.angle = 180 time.sleep(1)
测试报错代码
from utils.HardwareUtils import Hardware soxHardware = Hardware()
解决方法
1. 延迟相机初始化
将相机初始化从__init__方法中移出,延迟到第一次使用相机时再执行,避免类导入阶段的资源竞争:
修改Hardware类的相关代码:
class Hardware: def __init__(self): # 其他硬件初始化代码保持不变... # 暂时不初始化相机 self.picam2 = None def _init_camera(self): """内部相机初始化方法""" if self.picam2 is None: self.picam2 = Picamera2() camera_config = self.picam2.create_preview_configuration() self.picam2.configure(camera_config) self.picam2.start() time.sleep(2) def takeImage(self, path): # 使用相机前先确保已初始化 self._init_camera() self.picam2.capture_file(path)
2. 确保主程序的正确执行上下文
将类实例化放在主程序的if __name__ == '__main__':块中,避免模块导入时意外执行初始化:
修改测试代码:
from utils.HardwareUtils import Hardware if __name__ == '__main__': soxHardware = Hardware()
3. 检查环境变量与权限
- 确保运行程序的用户属于
video组(相机访问权限),执行命令:
然后重启会话生效。sudo usermod -aG video $USER - 如果是无桌面环境运行,手动设置
DISPLAY环境变量:import os os.environ['DISPLAY'] = ':0'
4. 更新Picamera2版本
旧版本可能存在初始化bug,执行以下命令更新:
sudo apt update && sudo apt install --upgrade python3-picamera2
内容的提问来源于stack exchange,提问作者Collin
相关产品推荐
相关产品推荐

