Raspberry Pi Pico连接20x4 I2C LCD出现OSError: [Errno 5] EIO求助
Raspberry Pi Pico连接20x4 I2C LCD触发OSError: [Errno 5] EIO的问题解决
错误信息
OSError: [Errno 5] EIO
已多次检查接线、重新插拔,问题仍未解决,网上未找到完整可行的解决方案。
触发错误的代码片段
def setup(): i2c = I2C(0, sda=Pin(8), scl=Pin(9), freq=400000) I2C_ADDR = i2c.scan()[0] lcd = I2cLcd(i2c, I2C_ADDR, 4, 20) lcd.custom_char(1, bytearray([0x1F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])) lcd.custom_char(3, bytearray([0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03])) lcd.custom_char(5, bytearray([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F])) lcd.custom_char(7, bytearray([0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18])) return lcd, clock, buzzer
LCD驱动库代码(i2cLcd.py)
import utime import gc from lcd_api import LcdApi from machine import I2C # PCF8574 pin definitions MASK_RS = 0x01 # P0 MASK_RW = 0x02 # P1 MASK_E = 0x04 # P2 SHIFT_BACKLIGHT = 3 # P3 SHIFT_DATA = 4 # P4-P7 class I2cLcd(LcdApi): #Implements a HD44780 character LCD connected via PCF8574 on I2C def __init__(self, i2c, i2c_addr, num_lines, num_columns): self.i2c = i2c self.i2c_addr = int(hex(i2c_addr)) self.i2c.writeto(self.i2c_addr, bytes([0])) utime.sleep_ms(20) # Allow LCD time to powerup # Send reset 3 times self.hal_write_init_nibble(self.LCD_FUNCTION_RESET) utime.sleep_ms(5) # Need to delay at least 4.1 msec self.hal_write_init_nibble(self.LCD_FUNCTION_RESET) utime.sleep_ms(1) self.hal_write_init_nibble(self.LCD_FUNCTION_RESET) utime.sleep_ms(1) # Put LCD into 4-bit mode self.hal_write_init_nibble(self.LCD_FUNCTION) utime.sleep_ms(1) LcdApi.__init__(self, num_lines, num_columns) cmd = self.LCD_FUNCTION if num_lines > 1: cmd |= self.LCD_FUNCTION_2LINES self.hal_write_command(cmd) gc.collect() def hal_write_init_nibble(self, nibble): # Writes an initialization nibble to the LCD. # This particular function is only used during initialization. byte = ((nibble >> 4) & 0x0f) << SHIFT_DATA self.i2c.writeto(self.i2c_addr, bytes([byte | MASK_E])) self.i2c.writeto(self.i2c_addr, bytes([byte])) gc.collect() def hal_backlight_on(self): # Allows the hal layer to turn the backlight on self.i2c.writeto(self.i2c_addr, bytes([1 << SHIFT_BACKLIGHT])) gc.collect() def hal_backlight_off(self): #Allows the hal layer to turn the backlight off self.i2c.writeto(self.i2c_addr, bytes([0])) gc.collect() def hal_write_command(self, cmd): # Write a command to the LCD. Data is latched on the falling edge of E. byte = ((self.backlight << SHIFT_BACKLIGHT) | (((cmd >> 4) & 0x0f) << SHIFT_DATA)) self.i2c.writeto(self.i2c_addr, bytes([byte | MASK_E])) self.i2c.writeto(self.i2c_addr, bytes([byte])) byte = ((self.backlight << SHIFT_BACKLIGHT) | ((cmd & 0x0f) << SHIFT_DATA)) self.i2c.writeto(self.i2c_addr, bytes([byte | MASK_E])) self.i2c.writeto(self.i2c_addr, bytes([byte])) if cmd <= 3: # The home and clear commands require a worst case delay of 4.1 msec utime.sleep_ms(5) gc.collect() def hal_write_data(self, data): # Write data to the LCD. Data is latched on the falling edge of E. byte = (MASK_RS | (self.backlight << SHIFT_BACKLIGHT) | (((data >> 4) & 0x0f) << SHIFT_DATA)) self.i2c.writeto(self.i2c_addr, bytes([byte | MASK_E])) self.i2c.writeto(self.i2c_addr, bytes([byte])) byte = (MASK_RS | (self.backlight << SHIFT_BACKLIGHT) | ((data & 0x0f) << SHIFT_DATA)) self.i2c.writeto(self.i2c_addr, bytes([byte | MASK_E])) self.i2c.writeto(self.i2c_addr, bytes([byte])) gc.collect()
排查与修复方案
验证I2C设备扫描结果:修改setup函数,先确认扫描到的设备列表,避免空列表导致索引错误,同时确认地址正确性:
def setup(): i2c = I2C(0, sda=Pin(8), scl=Pin(9), freq=400000) devices = i2c.scan() print(f"扫描到的I2C设备地址: {[hex(d) for d in devices]}") if not devices: raise RuntimeError("未检测到任何I2C设备,请检查接线或电源") I2C_ADDR = devices[0] # 后续代码...PCF8574模块常见地址为
0x27或0x3F,如果扫描结果为空,说明硬件连接存在问题。降低I2C通信频率:多数PCF8574模块不支持400kHz高速模式,改为100kHz尝试:
i2c = I2C(0, sda=Pin(8), scl=Pin(9), freq=100000)修复驱动库中的地址错误:
I2cLcd.__init__中的self.i2c_addr = int(hex(i2c_addr))完全多余,i2c.scan()返回的是整数地址,这行代码会导致地址处理异常,直接替换为:self.i2c_addr = i2c_addr检查电源供应:20x4 LCD的背光需要较大电流,若使用Pico的3.3V供电不足,可尝试切换到5V引脚供电(确保PCF8574模块支持5V电平),或使用外部电源给LCD模块供电。
延长初始化延迟:部分LCD模块需要更长的上电初始化时间,将
__init__中的utime.sleep_ms(20)改为utime.sleep_ms(100)。再次确认接线:确保SDA接Pin8、SCL接Pin9,GND引脚完全接地,电源引脚无虚接,排线或杜邦线无损坏。
内容的提问来源于stack exchange,提问作者Smh Dg
相关产品推荐
相关产品推荐

