I have an raspberry pi pico and a 20x4 I2C lcd. But when I try to connect to the lcd, it raises this error:
I checked my wires many times. And I connect and disconnected them to much. but none of this works.
I REALLY looked for it on internet but there wasn't any complete answer for me
OSError: [Errno 5] EIO
please help me
My i2cLcd.py (my library for connecting)(I chosen this name):
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()
my part of code that errors:
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
thanks
This is a very common error and it normally appears when the pico cannot establish I2C connection.
I don't know maybe you have already tried, but consider checking one more time that every single connection is going to where it should.
Make sure that your i2c pins are good, that SDA and SCL and other pins are connected to the right parts of the display.