树莓派连接OV5642 SPI摄像头MicroPython代码报EIO错误求助
树莓派OV5642 SPI摄像头MicroPython代码I2C读取错误排查
我编写了用于树莓派连接OV5642 SPI摄像头的MicroPython代码,运行后出现I/O错误。已确认摄像头连接正常(官方CircuitPython代码可正常运行),怀疑是对readfrom_into的调用理解有误,寻求解决提示。
我的MicroPython代码
import machine import time as utime from OV5642_reg import * OV5642=1 BMP =0 JPEG=1 RAW =2 OV5642_CHIPID_HIGH=0x300a OV5642_CHIPID_LOW=0x300b class ArducamClass(object): def __init__(self,Type): self.CameraMode=JPEG self.CameraType=Type self.SPI_CS = machine.Pin(5, mode=machine.Pin.OUT, value=1) self.I2cAddress=0x3c self.spi = machine.SPI(0, baudrate=4000000,polarity=0,phase=0,bits=8, sck=machine.Pin(2), mosi=machine.Pin(3), miso=machine.Pin(4)) self.i2c = machine.I2C(0, scl=machine.Pin(9), sda=machine.Pin(8), freq=1000000) print(self.i2c.scan()) self.Spi_write(0x07,0x80) utime.sleep(0.1) self.Spi_write(0x07,0x00) utime.sleep(0.1) def Camera_Detection(self): while True: if self.CameraType==OV5642: self.I2cAddress=0x3c self.wrSensorReg16_8(0xff,0x01) id_h=self.rdSensorReg16_8(OV5642_CHIPID_HIGH) id_l=self.rdSensorReg16_8(OV5642_CHIPID_LOW) if((id_h==0x56)and(id_l==0x42)): print('CameraType is OV5642') break else: print('Can\'t find OV5642 module') utime.sleep(1) def Set_Camera_mode(self,mode): self.CameraMode=mode def wrSensorReg16_8(self,addr,val): buffer=bytearray(3) buffer[0]=(addr>>8)&0xff buffer[1]=addr&0xff buffer[2]=val self.iic_write(buffer) def rdSensorReg16_8(self,addr): buffer=bytearray(2) rt=bytearray(1) buffer[0]=(addr>>8)&0xff buffer[1]=addr&0xff self.iic_write(buffer) self.iic_readinto(rt) return rt[0] def iic_write(self, buf, *, start=0, end=None): if end is None: end = len(buf) self.i2c.writeto(self.I2cAddress, buf[start:end]) def iic_readinto(self, buf, *, start=0, end=None): if end is None: end = len(buf) print(buf[start:end]) print(self.I2cAddress) self.i2c.readfrom_into(self.I2cAddress, buf[start:end]) def Spi_write(self,address,value): maskbits = 0x80 buffer=bytearray(2) buffer[0]=address | maskbits buffer[1]=value self.SPI_CS.value(0) self.spi_write(buffer) self.SPI_CS.value(1) def spi_write(self, buf, *, start=0, end=None): if end is None: end = len(buf) self.spi.write(buf[start:end]) mycam = ArducamClass(OV5642) mycam.Camera_Detection()
运行错误信息
Traceback (most recent call last): File "<stdin>", line 89, in <module> File "<stdin>", line 33, in Camera_Detection File "<stdin>", line 58, in rdSensorReg16_8 File "<stdin>", line 71, in iic_readinto OSError: [Errno 5] EIO
解决提示
- 修正I2C读取逻辑
MicroPython中分开调用writeto和readfrom_into会发送停止位,而OV5642读取寄存器要求使用重复起始位。改用writeto_then_readfrom方法自动处理该流程:
def rdSensorReg16_8(self, addr): buffer = bytearray(2) buffer[0] = (addr >> 8) & 0xff buffer[1] = addr & 0xff rt = bytearray(1) self.i2c.writeto_then_readfrom(self.I2cAddress, buffer, rt) return rt[0]
同时可删除原有的iic_readinto方法。
降低I2C频率
代码中I2C频率设为1MHz,部分传感器无法稳定支持。将初始化时的freq=1000000改为freq=400000(标准高速模式),提升兼容性。验证I2C地址
确认self.i2c.scan()输出包含0x3c,若没有,检查接线或确认OV5642的实际I2C地址(部分硬件配置下为0x3d)。简化调试
临时在rdSensorReg16_8中加入打印,确认寄存器地址和读取结果:
print(f"Reading register: {hex(addr)}") print(f"Read value: {hex(rt[0])}")
内容的提问来源于stack exchange,提问作者Andrea Anatra
相关产品推荐
相关产品推荐

