This project is built on top of https://github.com/dhylands/python_lcd
Scroll down on the list of items
Jump into LED menu and select Toggle 2 times, then go Back
Try the simulator on Wokwi here
Interacting with extensive live data on a 16x2 character LCD can be challenging due to limited display space.
TinyBlue organizes items (text and buttons), supports multiple screens, and updates live data efficiently.
The interface reserves one character on the left to show the cursor position. The cursor indicates the item currently in focus, which can be clickable or a Back button.
Character | Description |
---|---|
This item cannot be selected | |
This item can be selected | |
This item is a back button | |
The cursor is not at this item yet |
An Item
represents a single line of text displayed on the LCD screen.
from tinyblue import Item, Screen, TinyBlue
# create an item
item_temp = Item('Temp 40C')
To turn an item into a clickable button, set on_click
to a callable function:
def on_update():
print('updating')
# an update button that calls on_update() when clicked
item_update = Item('Update', on_click = on_update)
To create a back button, set is_back_button
to True
:
# a back button
item_back = Item('Back', is_back_button = True)
Update the text of an item using set_text(text: string)
. The text updates automatically if the item is currently displayed:
# update the text
item_temp.set_text('Temp 50C')
A Screen
contains a list of Item
objects that users can scroll through and interact with.
...
item_sound = Item('Sound: On', on_click = on_click_sound)
item_light = Item('Light: On', on_click_light)
# create a Settings screen
settings_options = Screen([
Item('Back', is_back_button = True),
item_sound,
item_light
])
Once items and screens are ready. Initialize TinyBlue(lcd, num_lines, num_columns)
lcd
must be the I2cLcd objectnum_lines
is how many lines vertically on LCD screensnum_columns
is how many characters per line
For 1602A format, num_lines = 16, num_columns = 2.
...
num_lines = 2
num_columns = 16
i2c = I2C(0, scl = Pin(17), sda = Pin(16), freq = 400000)
lcd = I2cLcd(i2c, i2c.scan()[0], num_lines, num_columns)
# initialize TinyBlue
tb = TinyBlue(lcd, num_lines, num_columns)
Add the screen objects into TinyBlue with a unique path
. '/'
is the root path.
screen_menu = Screen([
Item('Hello 1'),
Item('Hello 2'),
Item('Hello 3')
])
# add menu as a root screen to TinyBlue
tb.add_screen(path = '/', screen_menu)
Call render()
to display the current screen. This will call I2cLcd functions.
# show what is the screen
tb.render()
TinyBlue is designed to navigate through screens using just 2 buttons
- Scroll down by calling
tb.scroll()
- Select the focused item by calling
tb.select()
...
# keyA is a Pin button
if keyA.value() == 0:
tb.scroll()
# keyB is a Pin button
if keyB.value() == 0:
tb.select()
You can add 2 more buttons
- Scroll up by calling
tb.scroll(direction = -1)
- Go back to the previous screen by calling
tb.back()
. When you set item'sis_back_button = True
, it will call thistb.back()
Open a screen at a specific path using tb.open_screen(path)
# ====================== add screen a
screen_a = Screen([
Item('Back', is_back_button = True),
Item('Hello A')
])
tb.add_screen(path = '/a', screen_a)
# ====================== add screen b
screen_b = Screen([
Item('Back', is_back_button = True),
Item('Hello B')
])
tb.add_screen(path = '/a', screen_a)
# ====================== add screen main
def on_click_a():
tb.open_screen('/a')
def on_click_b():
tb.open_screen('/b')
screen_main = Screen([
Item('Open A', on_click = on_click_a),
Item('Open B', on_click = on_click_b)
])
tb.add_screen(path = '/', screen_main)
Here is a counter example showing how to implement a counter with a button
...
count = 0
item_count = Item('Count: 0')
def on_click_add():
global count
count += 1
item_count.set_text(f"Count: {count}")
screen_main = Screen([
item_count,
Item('Add', on_click = on_click_add)
])
tb.add_screen(path = '/', screen_main)
- Have one of the Raspberry Pi Pico devices
- Have one of the HD44780 compatible character LCDs connected via L2C
- Have at least 2 buttons connected to Pi Pico via GPIO ports
- Complete the Get Started guide with the Pi Pico
- Open Thonny, and connect to the Pi Pico
- Upload
lcd_api.py
andmachine_i2c_lcd.py
from this repository - Upload
tinyblue.py
andexample_tinyblue.py
- Open
example_tinyblue.py
on Thonny and check on the pins
...
# setup display and pins
i2c = I2C(0, scl = Pin(17), sda = Pin(16), freq = 400000)
i2c_devices = i2c.scan()
lcd = I2cLcd(i2c, i2c_devices[0], 2, 16)
scroll = Pin(6, Pin.IN, Pin.PULL_UP)
select = Pin(13, Pin.IN, Pin.PULL_UP)
...
- Run it
The source code for the site is licensed under the MIT license, which you can find in the LICENSE file.
All graphical assets are licensed under the Creative Commons Attribution 4.0 International License.