4.1. LCD Message Display

This example shows how to connect and use the I2C 16x2 LCD Display with the NULA Mini board. We will be using a simple pushbutton to measure the time difference between two presses and update the display accordingly.
At the end of this example you will learn:
- How to connect 16x2 LCD display
- How to display data and update it
- How to measure time difference
Parts required:
- Soldered NULA Mini Board
- Breadboard
- 16x2 LCD Display
- 1 x Pushbutton
- 1 x Qwiic cable
- Some jumper wires

Putting the components together
- Place the pushbutton on the breadboard, connect one side of the terminal to pin 5, and the other opposite side to GND.
- Connect the LCD via Qwiic cable to the NULA Mini board

Code Example
Import LCD driver with other necessary modules.
from LCD import LCD_I2C
from machine import I2C, Pin
import time
Create a LCD_I2C object and initialize it over I2C using Qwiic cable.
i2c = I2C(0, scl=Pin(7), sda=Pin(6))
lcd = LCD_I2C(i2c)
# Initialize sensor over Qwiic
# lcd = LCD_I2C()
Turn on the backlight of the LCD and start communication over I2C.
lcd.backlight()
lcd.begin()
Initialize the button on pin 5 and use internal PULL-UP to set the pin HIGH (1) while not pressed.
BUTTON_PIN = 5
btn = Pin(BUTTON_PIN, Pin.IN, Pin.PULL_UP)
Here we print initial text on the display. Indexing on both row and column start at 0, to print a character or message in the third column and first row we set the cursor to (2, 0). For first column in second row set the cursor to (0, 1).
# Sets the cursor to the third character place in the first row
lcd.setCursor(2, 0)
lcd.print("Hello, World!")
# Sets the cursor to the first character place in the second row
lcd.setCursor(0, 1)
lcd.print("Press the button")
Define variables last_press_MS to hold the last time button was pressed (in milliseconds) and DEBOUNCE_MS for button debounce time. We also set the first print flag to True to see if button was pressed for the first time or was already pressed.
last_press_MS = time.ticks_ms()
DEBOUNCE_MS = 30
isFirstPrint = True
Now we define the function that will be used for printing the elapsed time from button presses. If a button was pressed, function is called which formats the elapsed time in mm:ss format and overwrites the previous info on the display, this way we don't have to use lcd.clear() every single time ensuring smooth display update.
def print_time_lcd(elapsed_time_s, isFirstPrint):
# Check if button is pressed for first time, print accordingly
if isFirstPrint:
lcd.clear()
lcd.setCursor(0, 0)
lcd.print("Elapsed time: ")
# Set cursor to point to first character in second row
lcd.setCursor(0, 1)
# Check if more than a minute has passed
if elapsed_time_s < 60:
# Print time in seconds format
msg = "{:6.2f} s".format(elapsed_time_s)
else:
# Print time in MM:SS format
minutes = int(elapsed_time_s / 60)
seconds = int(elapsed_s % 60)
msg = "{:02d}:{:02d} min".format(minutes, seconds)
# Overwrite old text
msg = (msg + " " * 16)[:16]
# Print new text
lcd.print(msg)
Main loop of the program where button state is constantly checked, when a button is pressed time.ticks_diff() is called to return difference between current time and last button press time and converts it to seconds. That value is then passed to print_time_lcd function. Additional debounce is added to count only one press.
while True:
# Get current button state
current_state = btn.value()
# Check if button was pressed
if current_state == 1:
time.sleep_ms(DEBOUNCE_MS) # Debounce
if btn.value() == 0: # Additional debounce check to count only one press
# Get elapsed time from last press in seconds
elapsed_s = time.ticks_diff(time.ticks_ms(), last_press_MS) / 1000.0
# Print elapsed time on LCD
print_time_lcd(elapsed_s, isFirstPrint)
isFirstPrint = False
# Reset timer
last_press_MS = time.ticks_ms()
# Wait until button is released to avoid repeated triggers
while btn.value() == 0:
time.sleep_ms(10)