BeagleY-AI 05 驱动 OLED 液晶屏显示文字
[复制链接]
BeagleY-AI 05 驱动 OLED 液晶屏显示文字
背景
管脚
硬件连接
I2C 设备扫描
安装库并运行示例
创建 python 虚拟环境
安装 Luma OLED Python 库
克隆 luma.examples 仓库
运行 welcome.py
重写 eeworld_welcome.py
背景
BeagleY-AI 默认有5个I2C接口,但是其中有3路被 CSI/DSI 以及 OLDI 占用,只有另外2路接到 40-Pin 接口;所有的 I2C 接口都有外部上拉。
MCU_I2C0 作为主要的外部 I2C 接口,连接到 HAT3/HAT5;
WKUP_I2C0 同样连接到 40-Pin 接口,连接到 HAT27/HAT28。但是这路I2C与板子上的很多器件共用了,例如 PMIC,Board ID EEPROM 以及 RTC。通常不建议使用这个I2C接口。
管脚
硬件连接
购买了一个野火 0.96 英寸 OLED 模块,接口为 I2C ,单色屏。
BeagleY-AI 板卡
0.96英寸 OLED 模块
说明
HAT-1, 3.3V
VCC
电源
HAT-6, GND
GND
地
HAT-5, SCL
SCL
I2C 时钟
HAT-3, SDA
SDA
I2C 数据
I2C 设备扫描
先安装 i2c-tools 工具
sudo apt install i2c-tools
输入以下命令扫描I2C1设备总线上的设备,扫描到 0x3c 地址的设备
安装库并运行示例
此处使用 luma.oled 库来驱动 OLED,非常方便。
创建 python 虚拟环境
在当前项目目录创建一个名为 venv 的虚拟环境,输入以下命令
输入以下命令激活这个虚拟环境
安装 Luma OLED Python 库
在当前虚拟环境中输入以下命令安装 luma.oled 库
python -m pip install --upgrade luma.oled
因为我已经安装过,所以不用重新下载。
克隆 luma.examples 仓库
在项目目录输入以下命令:
git clone https://github.com/rm-hull/luma.examples.git
我已经克隆过,直接看下目录结构
运行 welcome.py
这个示例是在 OLED 屏幕上动态显示多国语言的 welcome
代码如下:
python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2014-2023 Richard Hull and contributors
# See LICENSE.rst for details.
# PYTHON_ARGCOMPLETE_OK
"""
Unicode font rendering & scrolling.
"""
import random
from pathlib import Path
from demo_opts import get_device
from luma.core.virtual import viewport, snapshot, range_overlap
from luma.core.sprite_system import framerate_regulator
from PIL import ImageFont
welcome = [
u"Бзиала шәаабеит",
u"Къеблагъ",
u"Welkom",
u"Bienvenue",
u"Maayong pag-abot",
u"Mayad-ayad nga pad-abot",
u"Mir se vjên",
u"እንኳን ደህና መጣህ።",
u"Willkumme",
u"أهلاً و سهل",
u"مرحابة",
u"Bienvenius",
u"Բարի գալուստ!",
u"আদৰণি",
u'欢迎光临',
u"歡迎光臨",
u"ᑕᑕᐊᐧᐤ",
u"Woé zɔ",
u"Bula",
u"Vælkomin",
u"Buiti achüluruni",
u"પધારો",
u"ברוך הבא",
u"Üdvözlet",
u"ಸುಸ್ವಾಗತ",
u"Приємаєме"
u"Xoş gəlmişsiniz!",
u"Salamat datang",
u"Сәләм бирем!",
u"Ongi etorri",
u"Menjuah-juah!",
u"স্বাগতম",
u"Добре дошли",
u"வாருங்கள்",
u"Kíimak 'oolal",
u"Märr-ŋamathirri",
u"Benvinguts",
u"Марша дагIийла шу",
u"歡迎",
u"Velkommen",
u"Welcome",
u"Wäljkiimen",
u"კეთილი იყოს თქვენი",
u"Καλώς Όρισες",
u"Eguahé porá",
u"Sannu da zuwa",
u"Aloha",
u"सवागत हैं",
u"Selamat datang",
u"Fáilte",
u"ようこそ",
u"Ирхитн эрҗәнәвидн",
u"Witôj",
u"សូមស្វាគមន៍",
u"환영합니다",
u"ຍິນດີຕ້ອນຮັບ",
u"Swagatam",
u"Haere mai",
u"Тавтай морилогтун",
u"خوش آمدید",
u"Witam Cię",
u"ਜੀ ਆਇਆ ਨੂੰ।",
u"Bon vinuti",
u"ยินดีต้อนรับ",
u"Hoş geldiniz",
u"Croeso",
u"Bonvenon",
u"Vitajte"
]
colors = [
"lightpink", "pink", "crimson", "lavenderblush", "palevioletred", "hotpink",
"deeppink", "mediumvioletred", "orchid", "thistle", "plum", "violet",
"magenta", "fuchsia", "darkmagenta", "purple", "mediumorchid", "darkviolet",
"darkorchid", "indigo", "blueviolet", "mediumpurple", "mediumslateblue",
"slateblue", "darkslateblue", "lavender", "ghostwhite", "blue", "mediumblue",
"midnightblue", "darkblue", "navy", "royalblue", "cornflowerblue",
"lightsteelblue", "lightslategray", "slategray", "dodgerblue", "aliceblue",
"steelblue", "lightskyblue", "skyblue", "deepskyblue", "lightblue",
"powderblue", "cadetblue", "azure", "lightcyan", "paleturquoise", "cyan",
"aqua", "darkturquoise", "darkslategray", "darkcyan", "teal",
"mediumturquoise", "lightseagreen", "turquoise", "aquamarine",
"mediumaquamarine", "mediumspringgreen", "mintcream", "springgreen",
"mediumseagreen", "seagreen", "honeydew", "lightgreen", "palegreen",
"darkseagreen", "limegreen", "lime", "forestgreen", "green", "darkgreen",
"chartreuse", "lawngreen", "greenyellow", "darkolivegreen", "yellowgreen",
"olivedrab", "beige", "lightgoldenrodyellow", "ivory", "lightyellow",
"yellow", "olive", "darkkhaki", "lemonchiffon", "palegoldenrod", "khaki",
"gold", "cornsilk", "goldenrod", "darkgoldenrod", "floralwhite", "oldlace",
"wheat", "moccasin", "orange", "papayawhip", "blanchedalmond", "navajowhite",
"antiquewhite", "tan", "burlywood", "bisque", "darkorange", "linen", "peru",
"peachpuff", "sandybrown", "chocolate", "saddlebrown", "seashell", "sienna",
"lightsalmon", "coral", "orangered", "darksalmon", "tomato", "mistyrose",
"salmon", "snow", "lightcoral", "rosybrown", "indianred", "red", "brown",
"firebrick", "darkred", "maroon", "white", "whitesmoke", "gainsboro",
"lightgrey", "silver", "darkgray", "gray", "dimgray", "black"
]
def make_font(name, size):
font_path = str(Path(__file__).resolve().parent.joinpath('fonts', name))
return ImageFont.truetype(font_path, size)
def lerp_1d(start, end, n):
delta = float(end - start) / float(n)
for i in range(n):
yield int(round(start + (i * delta)))
yield end
def lerp_2d(start, end, n):
x = lerp_1d(start[0], end[0], n)
y = lerp_1d(start[1], end[1], n)
try:
while True:
yield next(x), next(y)
except StopIteration:
pass
def pairs(generator):
try:
last = next(generator)
while True:
curr = next(generator)
yield last, curr
last = curr
except StopIteration:
pass
def infinite_shuffle(arr):
copy = list(arr)
while True:
random.shuffle(copy)
for elem in copy:
yield elem
def make_snapshot(width, height, text, fonts, color="white"):
def render(draw, width, height):
t = text
# measure text
for font in fonts:
left, top, right, bottom = draw.multiline_textbbox((0, 0), t, font)
size = right - left, bottom - top
if size[0] > width:
t = text.replace(" ", "\n")
left, top, right, bottom = draw.multiline_textbbox((0, 0), t, font)
size = right - left, bottom - top
else:
break
# draw text
left = (width - size[0]) // 2
top = (height - size[1]) // 2
draw.multiline_text((left, top), text=t, font=font, fill=color,
align="center", spacing=-2)
return snapshot(width, height, render, interval=10)
def random_point(maxx, maxy):
return random.randint(0, maxx), random.randint(0, maxy)
def overlapping(pt_a, pt_b, w, h):
la, ta = pt_a
ra, ba = la + w, ta + h
lb, tb = pt_b
rb, bb = lb + w, tb + h
return range_overlap(la, ra, lb, rb) and range_overlap(ta, ba, tb, bb)
def main():
regulator = framerate_regulator(fps=30)
fonts = [make_font("code2000.ttf", sz) for sz in range(24, 8, -2)]
sq = device.width * 2
virtual = viewport(device, sq, sq)
color_gen = pairs(infinite_shuffle(colors))
for welcome_a, welcome_b in pairs(infinite_shuffle(welcome)):
color_a, color_b = next(color_gen)
widget_a = make_snapshot(device.width, device.height, welcome_a, fonts, color_a)
widget_b = make_snapshot(device.width, device.height, welcome_b, fonts, color_b)
while True:
posn_a = random_point(virtual.width - device.width, virtual.height - device.height)
posn_b = random_point(virtual.width - device.width, virtual.height - device.height)
if not overlapping(posn_a, posn_b, device.width, device.height):
break
virtual.add_hotspot(widget_a, posn_a)
virtual.add_hotspot(widget_b, posn_b)
for _ in range(30):
with regulator:
virtual.set_position(posn_a)
for posn in lerp_2d(posn_a, posn_b, device.width // 4):
with regulator:
virtual.set_position(posn)
virtual.remove_hotspot(widget_a, posn_a)
virtual.remove_hotspot(widget_b, posn_b)
if __name__ == "__main__":
try:
device = get_device()
main()
except KeyboardInterrupt:
pass
重写 eeworld_welcome.py
参考上面的 welcome.py 代码,我重写了一个显示 EEWORLD & DigiKey 的代码
python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2014-2022 Richard Hull and contributors
# See LICENSE.rst for details.
# PYTHON_ARGCOMPLETE_OK
"""
Simple println capabilities.
"""
import time
from pathlib import Path
from demo_opts import get_device
from luma.core.virtual import terminal
from PIL import ImageFont
def make_font(name, size):
font_path = str(Path(__file__).resolve().parent.joinpath('fonts', name))
return ImageFont.truetype(font_path, size)
def main():
"""
可以接受的字体:
("ProggyTiny.ttf", 16), ("miscfs_.ttf", 12), ("FreePixel.ttf", 12), ('ChiKareGo.ttf', 16)
"""
for fontname, size in [('ChiKareGo.ttf', 16)]:
font = make_font(fontname, size) if fontname else None
term = terminal(device, font)
term.println("EEWORLD & DigiKey")
term.println("------------------")
term.println(" by CoderX9527")
term.puts(" 20250415")
term.flush()
time.sleep(2)
while True:
pass
if __name__ == "__main__":
try:
device = get_device()
main()
except KeyboardInterrupt:
pass