Git Product home page Git Product logo

rpi-pico-i2c-lcd's Introduction

RPI-PICO-I2C-LCD

This is a project which adapts code from another user to allow usage of the PCF8574 I2C lcd backpack for either 20x4 or 16x2 lcd screens.

Credit: https://github.com/dhylands/python_lcd/tree/master/lcd mostly to Dave Hylands for the basic api and lcd driver code.

Project: Check it out for a full step-by-setp guide on Instructables: https://www.instructables.com/RPI-Pico-I2C-LCD-Control/

This is code adaptded for micropython and the Raspberry Pi PICO specifically.

Usage:

  • Download all 3 .py files included.
  • Open Thonny IDE with the 3 files
  • Make pin edits or setup changes (See below for options)
  • DO NOT EDIT FILE NAMES!
  • In Thonny, go to top menu File => Save Copy => Raspberry Pi Pico and save each file to the board with the same name as downloaded and with a .PY extension when saving it to the board.
  • Switch to the pico_i2c_lcd_test.py (this is the main file) and click run. This should be able to initalize the LCD display if settings are right.
  • If you get errors, see below for a known list of errors and their fixes
  • Wiring Diagram LCD_bb.jpg! Please look here for a fritzing diagram!

Requirements:

  • 3.3 - 5V level translator. This is crucial to encure the lcd recieves the commands properly. I recommend this: https://www.adafruit.com/product/757 (Must be Bi-Directional)
  • PCF8574 I2C LCD backpack. (These are common to find)

Setup Changes:

  • Make sure the top address is set correctly! Use this small program to scan for I2C devices:
import machine
sda=machine.Pin(0)
scl=machine.Pin(1)
i2c=machine.I2C(0,sda=sda, scl=scl, freq=400000)
print(i2c.scan())
  • Once you get an address through the console (REPL), this will be in decimal and not hex. You can convert the decimal to hex or simply put a decimal address in the setup. in my case, the decimal addr. was 39 which converts to 0x27 in hex.
  • Ensure that your SCL and SDA pins are selected properly in accordance with the Pico's pin table. These connect to the low voltage side of the translator with a 3.3V Reference from the board. The high voltage side gets a 5V reference from the VBUS pin of the Pico.
  • Finally, assure the I2C_NUM_ROWS and I2C_NUM_COLS are set properly!

Functions / Usage:

These are the python commands used in a program! (They can all be found in the lcd_api.py file with definitions to their functions)

  • lcd.putstr("Text goes here!") - Send a string of chars to the display IMPORTANT: Use this for printing a variable: lcd.putstr(str(Variable)) [Turns variable into string]
  • lcd.show_cursor() / lcd.hide_cursor() - Show / Hide the cursor of the lcd (White bar)
  • lcd.blink_cursor_on() / lcd.blink_cursor_off() - Turn on / Off the blinking cursor upon printing
  • lcd.backlight_on() / lcd.backlight_off() - Turn on / Off backlight of the LCD (Controlled by a small transistor on the backpack)
  • lcd.display_on() / lcd.display_off() - Turn on / Off the display (Not backlight but the entire chip)
  • lcd.clear() - Clear all chars or anything written to the display
  • lcd.move_to(Col, Row) - Move to position based on row and col values (Y, X)
  • lcd.custom_char(Num, bytearray([HEX chars]))) - Num can be any integer 0 - 8 (Writing to CGRAM locations) merely used for numbering. The HEX chars are simply made by using this link: https://maxpromer.github.io/LCD-Character-Creator/. It will provide a string of Hex charecters which can replace the "HEX chars" in the example command.

Errors:

OSERROR : 5 (This is quite a common error, 5 means I/O error. Check Your connections. This means codes can't be sent or recieved ensure SCL and SDA are properly connected through the level translator or, use 2x 1K resistors, connected between +5V and the SCL and SDA pins, as external pullups.

Feel to leave comments or questions / issues and I will try to answer / resolve them as quick as possible!

For people wondering how to use this code, Tinkernut on Youtube created a very nice guide + some more features! https://www.youtube.com/watch?v=B8Kr_3xHjqE&t

rpi-pico-i2c-lcd's People

Contributors

janosrusiczki avatar n0n3nt1ty avatar oalders avatar t-622 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

rpi-pico-i2c-lcd's Issues

can you help please

hi im not sure what ive done wrong I followed each of your steps exactly but something is not quite right the screen comes on so it is definitely getting power however the cursor is not showing up and neither is any characters the screen is just flashing (turning on and off)

OSError: [Errno 5] EIO

I had this running several times and today I went to work on my code and before I ran it I tested my working code and I now get this error below. I also get the same error running your test code. What could it be?

Running test_main Traceback (most recent call last): File "<stdin>", line 62, in <module> File "<stdin>", line 16, in test_main File "pico_i2c_lcd.py", line 22, in __init__ OSError: [Errno 5] EIO

Eating up the memory

Hello! I used your library with my Pico to my alarm project. I used the LCD to type in the PIN needed to arm and disarm the alarm. My code utilises a while loop to await input from the keypad and then print a typed number on the LCD. I noticed that with every character printed a lot of memory of my Pico is being consumed. Apart from printstr() function I also noticed that lcd.clear() consumes a lot of memory too. When it's executed in a loop it takes all the memory from my Pico and the microcontroller freezes. I got rid of lcd.clear() function in my loop, but eveytime I printed a character on the LCD it still took memory. What I did was adding GarbageCollector library and adding a line with gc.collect() at the end of every function in pico_i2c_lcd.py. This really helped! Now any function from your library barely takes any memory off my microcontroller. I think you should add those lines to your code.

`import utime

from lcd_api import LcdApi
from machine import I2C
import gc

MASK_RS = 0x01
MASK_RW = 0x02
MASK_E = 0x04

SHIFT_BACKLIGHT = 3
SHIFT_DATA = 4

class I2cLcd(LcdApi):

def __init__(self, i2c, i2c_addr, num_lines, num_columns):
    self.i2c = i2c
    self.i2c_addr = i2c_addr
    self.i2c.writeto(self.i2c_addr, bytes([0]))
    utime.sleep_ms(20)   # Allow LCD time to powerup
    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)
    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):
    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):
    self.i2c.writeto(self.i2c_addr, bytes([1 << SHIFT_BACKLIGHT]))
    gc.collect()
    
def hal_backlight_off(self):
    self.i2c.writeto(self.i2c_addr, bytes([0]))
    gc.collect()
    
def hal_write_command(self, cmd):
    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:
        utime.sleep_ms(5)
    gc.collect()

def hal_write_data(self, data):
    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()

`

Problem in file "pico_i2c_lcd.py" line 22

Hello and thanks for the LCD code. I have a Pi Pico W, Windows 10, Thonny 4.1.4 on COM7, 2x16 LCD. I have written and run several small test programs successfully including an i2c scan which shows LCD on 0x27 when run both from "computer" and "pi". I have modified pico_i2c_test.py to support my hookup and slowing the clock freq:
I2C_NUM_ROWS = 2
I2C_NUM_COLS = 16
i2c = I2C(0, sda=machine.Pin(20), scl=machine.Pin(21), freq=100000)
Copied 3 files to Pi without renaming. However, when I run pico_i2c_test.py I get the following error:

MPY: soft reboot
Running test_main
Traceback (most recent call last):
File "", line 62, in
File "", line 16, in test_main
File "pico_i2c_lcd.py", line 22, in init
OSError: [Errno 5] EIO

This is referencing this line 22 in pico_i2c_lcd.py:
self.i2c.writeto(self.i2c_addr, bytes([0])) # (this statement fails - put "print" statements before & after)

Note that a scan does detect i2c on 0x27. Rewired with shorter leads and slowed i2c clock -> no joy. I am not an accomplished Python programmer and consequently cannot troubleshoot the problem any further. Thanks again for any help.

So! This is just for your chuckles and anyone else who might have the same problem. After spending hours on the problem, while hooking up my scope to SCL and SDA the system rebooted and works!

Can't import smbus

Hello,
Just trying your code for driving 16x2 LCD on Raspberry Pi Pico using Micropython.
Have followed your instructions and copied the files onto the Pico.
Edited the parameters and when I try to run I get and error when the code tries to
import smbus

If I run this from the command prompt the inbuilt library is not found.
Please advise.
Regards
Phil Green

Unable To get address of LCD module

Hi I have a LCD 1602 and am unable to get the address,
running the code below : -

import machine sda=machine.Pin(0) scl=machine.Pin(1) i2c=machine.I2C(0,sda=sda,scl=scl, freq=400000) print(i2c.scan())

the output is
`>>> %Run -c $EDITOR_CONTENT
[]

`

Cant import lcd_api or pico_i2C_lcd

Hello,

I have copied the 3 files on to the pico. However Thonny returns ImportError: no module named "lcd_api" and no module named "pico_i2c_lcd"

What am I doing wrong ?

Best regards
Kim

Dreadfully slow because of excessive gc.collect()

Hello there,

I'm on a small project on Raspberry Pi Pico with a 2 line 1602 I2C LCD using your library.

I found out that my code was desperately slow.

Debugging, I found out that my code spent 95% of its time in the display routine, debugging more showed it spent 90% of the time in pico_I2c_lcd.

So I took a look at it and found out it was because your library calls gc.collect() FOR EACH AND EVERY ACTION.

So each time you put a char on screen you perform a memory garbage collection afterwards ?!

I found out that this comes from the issue #5 and this spurious code was added by user [n0n3nt1ty]

Garbage collection may be performed manually once at each iteration of the main program loop, but should never be buried down in a library that will be called hundreds of times !

So I removed the importation of gc from my copy of the library, removed all the gc.collect() stupid calls, and while I was at it, replace all the "utime" by "time".

Net result : My code using this fixed version of the library runs 10 times faster...

I get an error when running the test

I get this error while running the test (I know that my hexadecimal is correct.)
Traceback (most recent call last): File "<stdin>", line 62, in <module> File "<stdin>", line 16, in test_main File "pico_i2c_lcd.py", line 22, in __init__ OSError: [Errno 5] EIO

How can I fix this?

Clear rows instead

Is there a way you can clear rows of a 4X20 LCD and not the entire LCD? Thanks!

3 addresses for LCD issue

Hello,

I have some minor issues with using the scan.py as well as getting anything loaded onto the LCD screen.
I was going to post a screenshot, but github isn't allowing that at this time for some reason.
Upon running the scan.py script, I receive an array for the LCD address as follows in HEX:
[62, 96, 112]
and converted to decimal with make it
[3E, 60, 70]
This is strange as there should only be one address.
Either way, through troubleshooting, all 3 values work, if used separately, in the test.py script, as it runs and goes each line of testing script for the LCD, but the LCD doesn't illuminate or anything.
If the whole array is used, an error message occurs. Please help on this matter. 3 addresses is strange, and no LCD illumination or messaging is not helping. Thank you.

-Dom

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.