Raspberry Pi Pico – I2C LCD Shield (16x2), LED and Push Button Interface

by PugazhM in Circuits > Raspberry Pi

4826 Views, 2 Favorites, 0 Comments

Raspberry Pi Pico – I2C LCD Shield (16x2), LED and Push Button Interface

Circuit_V01.jpeg

This experimentation is about interfacing 16X2 I2C LCD, LEDs and Push Buttons with Raspberry Pi Pico, and using MicroPython library for programming the LCD, LED and Push Buttons.

Visit the "VESZLE - The Art Of Electronics" you tube channel for further information and videos.

https://www.youtube.com/channel/UCY4mekPLfeFinbQHp...

The I2C LCD, LED and Push Button you tube video link

Abstract

The Raspberry Pi Pico is a tiny, fast, and versatile board built using RP2040 features a dual-core Arm Cortex-M0+ processor with 264KB internal RAM and support for up to 16MB of off-chip Flash. It provides wide range of flexible I/O options includes I2C, SPI, and uniquely Programmable I/O (GPIO) pins.

In Embedded system design, character LCD display [16x2, 16x4, 20x2 or 20x4 LCDs] is used for display the system status, menu navigation and configuring system parameters. LEDs are used for visual indication and Push Buttons are used for collecting / handling the user inputs. This experimentation is about interfacing 16X2 I2C LCD, LEDs and Push Buttons with Raspberry Pi Pico, and using MicroPython library for programming the LCD, LED and Push Buttons.

Reference

“Raspberry Pi Pico, Getting Started on Board Blink LED” Instruct-able / You-tube by PugazhM

https://www.instructables.com/Raspberry-Pi-Pico-G...

The “i2c_lcd_lib.py” driver library

The “lcd_api.py” driver library


Components

Component.jpg

Raspberry Pi Pico

Micro USB Cable

PCF8574 LCD IO expander module

I6x2 LCD

Red LED, Green LED and Orange LED

330-ohm resistor – 3 Nos

Schematic

Circuit_V01.jpeg

An I2C LCD display is a screen which talks to your Pico over a special communication system called the inter-integrated circuit (I2C) bus.

RPi Pico can use the I2C LCD for writing the system status and control parameters and user inputs etc.

The 16x2 is very common type LCD, with two rows. Each row displays 16 characters of either 5x7 or 5x8 dot matrix characters. Totally 32 alpha numerical charters can be displayed in two rows.

It has inbuilt font ROM, for decoding the ASCII input. There's a dot pitch between two characters and a space between lines, thus separating characters and lines.

The 16x2 LCD supports 8-bit interface mode or 4-bit interface mode. This experiment uses 4-bit interface mode.

The I2C - PCF8574 device provides general-purpose remote I/O expansion. The device features an 8-bit quasi-bidirectional I/O port (P0–P7), including latched outputs with high current drive capability for directly driving LEDs.

Each quasi-bidirectional I/O can be used as an input or output without the use of a data-direction control signal.

The Address range of PCF8574 is 0x20 to 0x27 (7 bit address mode).

The least significant bit of address is used for Write (0) or Read (1) operation selection.

The PCF8574 I2C based GPIO expander is used along with 16x2 LCD, and 4-bit mode configuration.

The PCF8574 IO expander LCD backpack consists of inbuild LCD brightness control circuit, and 4Bit LCD interfacing header.

The PCF8574 IO expander can be connected to Raspberry Pi Pico GPIO I2C pins (GPIO0—GPIO1). LCD operates at 4-bit data mode as given in above circuit.

If the display is not visible, adjust the Contrast pot (1K), to make it visible.

LEDs and Push Button

button.jpg
LED.jpg

LEDs are available in a wide range of shapes, colours, and sizes. LEDs are mainly used for visual indication.

The Red, Green and Orange LEDs are connected to RPi Pico GPIO pins (2,3 and 4) via 330-ohm current limiting resistors.

A Push Button switch also known as momentary switch is an input device, used for collecting the user inputs.

The push button is active when holding the button down.

Push and release, will create an event, then event executes a task to perform the user programmed actions.

The push buttons, does not need a current limiting resistor, when connecting a push button into RPi Pico GPIO pins.

The RPi Pico includes an on-board programmable resistor connected to each GPIO pin.

These can be set in MicroPython to pull-down resistors or pull-up resistors as required by the circuit.

A pull-up resistor connects the pin to 3V3, meaning when the push-button isn’t pressed, the input will be 1.

A pull-down resistor connects the pin to ground, meaning when the push-button isn’t pressed, the input will be 0.

Two push buttons are connected to RPi Pico GPIO pins (5 and 6). One leg is pulled into high (+3V3) and another leg is connected to GPIO.

MicroPython program, configures the GPIO as input, and activating the inbuild Pull Down Resistors.

button1 = machine.Pin(5, machine.Pin.IN, machine.Pin.PULL_DOWN)

button2 = machine.Pin(6, machine.Pin.IN, machine.Pin.PULL_DOWN)

Python Software - I2C 16x2 LCD, LED and Push Button Program

TaskEvent_V01.jpeg

Open the RPi Pico as drive,and then copy the following files into root directory.

lcd_api.py

i2c_lcd_lib.py Following LCD I2C functionalities are provided by the “i2c_lcd_lib.py” python library.

init

hal_write_init_nibble

hal_backlight_on

hal_backlight_off

hal_write_command

hal_write_data

Following LCD I2C functionalities are provided by the “lcd_api.py” python library.

def __init__(self, num_lines, num_columns):

def clear(self):

def show_cursor(self):

def hide_cursor(self):

def blink_cursor_on(self):

def blink_cursor_off(self):

def display_on(self):

def display_off(self):

def backlight_on(self):

def backlight_off(self):

def move_to(self, cursor_x, cursor_y):

def putchar(self, char):

def putstr(self, string):

def custom_char(self, location, charmap):

LCD is initialized with I2C bus and welcome screen of “Raspberry Pi Pico 16x2 LCD” is displayed in two rows, for about 5 seconds.

The count variable, LEDs and Push Buttons are initialized.

The timer_one is initialized and callbacks the “BlinkLED” functionality for toggling on board LED at 500mS duration. (frequency = 2)

The timer_two is initialized and callbacks the “ReadButton” functionality for reading push buttons at 200mS duration. (frequency = 5)

If Push Button 1 is pressed/released then the count variable is advanced by one count and the count value is displayed on the I2C LCD screen

If Push Button 2 is pressed/released, then the LEDs changes their state (RED—GREEN—ORANGE—OFF), and corresponding state change is displayed on the LCD screen.

'''
Demonstrates the use of I2C 1602 LCD, LEDs and Push Button shield with RPi Pico. * I2C 16x2 LCD Connection diagram * LCD 4 bit mode interface * Displaying welcome screen, LED and push button status. * The lcd lib provides Clear Display, Cursor on, Cursor Off, Backlight On, Back light Off * Write Command and Write data functionalities * The RPi Pico pin and I2C 16x2 LCD shield connection * GND -------------------- GND * VCC -------------------- +5V * SDA -------------------- GPIO0 * SCL -------------------- GPIO1 * LED and Push Button pin connection * RED LED ------------------ GPIO2 * GREEN LED ---------------- GPIO3 * ORANGE LED --------------- GPIO4 * PUSH BUTTON 1 ------------ GPIO5 * PUSH BUTTON 2 ------------ GPIO6 Name:- M.Pugazhendi Date:- 09thSep2021 Version:- V0.1 e-mail:- muthuswamy.pugazhendi@gmail.com '''
from machine import I2C, Pin, Timer
import time
from i2c_lcd_lib import I2cLcd
# Initialize I2C Bus
i2c = I2C(0, sda=Pin(0), scl=Pin(1), freq=400000)
# Scan I2C bus and initialize I2C LCD
I2C_ADDR = i2c.scan()[0]
I2C_LCD = I2cLcd(i2c, I2C_ADDR, 2, 16)
# Write Line one string
I2C_LCD.putstr('Raspberry Pi\n')
# Write Line two string
I2C_LCD.putstr('Pico 16x2 LCD')
time.sleep(5)
# Initializing LEDs and Push Buttons
red_led = machine.Pin(2, machine.Pin.OUT)
green_led = machine.Pin(3, machine.Pin.OUT)
orange_led = machine.Pin(4, machine.Pin.OUT)
button1 = machine.Pin(5, machine.Pin.IN, machine.Pin.PULL_DOWN)
button2 = machine.Pin(6, machine.Pin.IN, machine.Pin.PULL_DOWN)
on_board_led = machine.Pin(25, machine.Pin.OUT)
# Initialize button constants and variables
BUTTON_PRESSED = const(1)
BUTTON_RELEASE = const(0)
    
button1_previous = BUTTON_RELEASE
button1_present = BUTTON_RELEASE
button2_previous = BUTTON_RELEASE
button2_present = BUTTON_RELEASE
count = 0
led_state = 0
# Blink LED function implementation
def BlinkLED(timer_one):
    on_board_led.toggle()
    
# Clear and update screen function implementation
def UpdateScreen():
    # Clear Screen
    I2C_LCD.clear()
    I2C_LCD.move_to(0,1)
    I2C_LCD.putstr("Count = " + str(count))
    if led_state == 1:
        I2C_LCD.move_to(0,2)
        I2C_LCD.putstr("\nRed LED")
    elif led_state == 2:
        I2C_LCD.move_to(0,2)
        I2C_LCD.putstr("\nGreen LED")
    elif led_state == 3:
        I2C_LCD.move_to(0,2)
        I2C_LCD.putstr("\nOrange LED")
    else:
        I2C_LCD.move_to(0,2)
        I2C_LCD.putstr("\nLEDs OFF")
# Read push button state. If button state is changed, then increment a counter or change the LED state.
def ReadButton(timer_two):
    # Initialize global variables.
    global button1_previous, button2_previous, button1_present, button2_present,count,led_state
    
    # Read Buttons
    button1_present = button1.value()
    button2_present = button2.value()
    
    # Compare button one present vs previous. If differ, then update the count variable.
    if button1_previous != button1_present:
        button1_previous = button1_present      
        if button1_present == BUTTON_PRESSED:
            print("Button One Pressed")
        else:
            print("Button One Released")
            count = count + 1      
            UpdateScreen()
            
    # Compare button two present vs previous. If differ then change the LED state.       
    if button2_previous != button2_present:
        button2_previous = button2_present
        if button2_present == BUTTON_PRESSED:
            print("Button Two Pressed")
        else:
            print("Button Two Released")
            led_state = led_state + 1
            if led_state > 3:
                led_state = 0
                
            if led_state == 1:
                red_led.on()
                green_led.off()
                orange_led.off()
            elif led_state == 2:
                red_led.off()
                green_led.on()
                orange_led.off()
            elif led_state == 3:
                red_led.off()
                green_led.off()
                orange_led.on()
            else:
                red_led.off()
                green_led.off()
                orange_led.off()
            UpdateScreen()
#Initialize timer_one. Used for toggle the onboard LED
timer_one = Timer()
#Initialize timer_two. Used for reading push button
timer_two = Timer()
# Initialize periodic timer one. Call Blink LED function
timer_one.init(freq=2, mode=Timer.PERIODIC, callback=BlinkLED)
# Initialize periodic timer two. Call read push button, function
timer_two.init(freq=5, mode=Timer.PERIODIC, callback=ReadButton)

Conclusion

C1.jpg

The project is successfully completed with Raspberry Pi Pico and I2C - 1602 LCD shield, LED’s and Buttons

The I2C - 16x2 LCD shield, LEDs and Buttons can be used for many embedded projects as alpha numerical display, visual indications and feeding user inputs.

Video Link

C2.jpg

Result_Video.mp4

Visit "VESZLE - The Art Of Electronics" you tube channel for further information and videos.

https://www.youtube.com/channel/UCY4mekPLfeFinbQH...

If you enjoyed this instruct-able, then make sure you subscribe

The I2C LCD, LED and Push Button you tube video link