I am working on a robot, and am in the process of connecting to the hardware through python on a raspberry pi. All of my mini test programs work, but I am having issues merging them into 1 class that contains all hardware interactions. Everything works except the Picamera2 camera. Please see class below. Running this directly through idle as the main class works no problem. Calling this class and making an object in another results in the error
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.
Class code
#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)
Test program that crashes with the error mentioned above
from utils.HardwareUtils import Hardware
soxHardware = Hardware()
I am also willing to refactor this entire section to make it more friendly, and know that there are probably some bad practices in it. I have used python as a scripting language extensively, but not as an object oriented language
i`ve tested your code. its OK:
import time
#for camera
from picamera2 import Picamera2
class Hardware:
def __init__(self):
#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 takeImage(self,path):
self.picam2.capture_file(path)
if __name__ == '__main__':
hardware=Hardware()
hardware.takeImage("img.png")
the error usually appears when u didnt close (picam2.close()) camera from the last use of it.