树莓派OLED屏实战:I2C驱动与系统监控显示
1. 硬件准备与连接
给树莓派添加一个小巧的OLED屏幕来显示系统状态,是我觉得最实用的硬件扩展之一。这种方案成本低、接线简单,而且能实时查看IP地址、CPU内存使用率和时间,特别适合放在桌面上当个迷你监控器。
我这次用的是128×32分辨率的OLED屏,这种屏幕通常采用SSD1306驱动芯片,通过I2C协议通信。你可能会看到市面上有各种尺寸的OLED屏,从0.96寸到2.23寸都有,但128×32这个规格对于显示系统信息来说刚刚好,不会太大也不会太小。
需要的材料清单:
- 树莓派(任何型号都可以,我用的树莓派5)
- OLED显示屏(支持I2C通信的SSD1306芯片)
- 4根杜邦线(母对母)
- 可选:面包板让连接更稳定
接线其实特别简单,OLED屏一般有4个引脚:VCC、GND、SCL、SDA。找到树莓派的GPIO引脚,对照着接就行:
- VCC → 3.3V(树莓派的第1或17引脚)
- GND → 地线(第6、9、14、20、25、30、34、39引脚都可以)
- SCL → I2C时钟线(BCM 3,物理引脚5)
- SDA → I2C数据线(BCM 2,物理引脚3)
这里有个小细节要注意:一定要接3.3V,不要接5V!我一开始就接错了,差点把屏幕烧了。OLED屏的工作电压通常是3.3V,接5V可能会永久损坏屏幕。
如果你用的是那种直接插在GPIO上的OLED扩展板,那更简单,直接插上去就行,连杜邦线都省了。不过我个人还是喜欢用杜邦线连接,这样屏幕可以单独放置,摆放位置更灵活。
接好线后,最好用手轻轻拉一下线,确保接触良好。我就遇到过因为接触不良导致屏幕时好时坏的情况,排查了好久才发现是线没插紧。
2. 软件环境配置
硬件连接好后,接下来就是配置树莓派的软件环境了。这个过程需要开启I2C接口、安装必要的库文件,我会一步步带你操作。
首先开启I2C功能: 树莓派的I2C接口默认是关闭的,需要手动开启。有两种方法可以开启:
# 方法一:使用raspi-config工具(推荐新手)
sudo raspi-config
然后选择 Interfacing Options → I2C → Yes → OK
# 方法二:直接修改配置文件
sudo nano /boot/config.txt
找到并确保有以下两行(如果没有就添加):
dtparam=i2c_arm=on
dtparam=i2c1=on
保存重启后,可以用这个命令检测I2C设备:
sudo i2cdetect -y 1
如果看到类似这样的输出,就说明I2C功能正常了:
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
这里的"3c"就是OLED屏幕的I2C地址,不同屏幕可能略有不同,但0x3C是最常见的。
安装必要的软件包: 接下来安装驱动OLED屏需要的Python库和依赖:
# 更新系统包列表
sudo apt update
# 安装基础依赖
sudo apt install -y python3-dev python3-pip python3-pil python3-smbus i2c-tools
# 安装psutil用于获取系统信息
sudo pip3 install psutil
# 安装luma.oled库(这是驱动OLED的核心库)
sudo pip3 install luma.oled
这里有个小坑要注意:如果直接用系统pip安装,可能会遇到权限问题。我建议为这个项目创建虚拟环境:
# 创建项目目录
mkdir ~/oled-project && cd ~/oled-project
# 创建虚拟环境
python3 -m venv oled-env
# 激活虚拟环境
source oled-env/bin/activate
# 在虚拟环境中安装库
pip install luma.oled psutil pillow
用虚拟环境的好处是隔离了项目依赖,不会影响系统其他Python程序。而且如果以后想删除这个项目,直接删除整个目录就行,完全不会留下垃圾文件。
3. 核心代码解析
现在来到最有趣的部分——编写Python代码来驱动OLED屏显示系统信息。我会逐段解释代码的每个部分,让你真正理解原理而不只是复制粘贴。
首先导入必要的库:
from luma.core.interface.serial import i2c
from luma.core.render import canvas
from luma.oled.device import ssd1306
import netifaces
import time
import psutil
from PIL import ImageFont
这些库各司其职:luma负责OLED驱动,netifaces获取网络信息,psutil获取系统性能数据,PIL处理字体显示。
字体设置很重要:
font = ImageFont.truetype('./msyh.ttc', 11, encoding='unic')
WIDTH = 128
HEIGHT = 32
中文字体显示是个常见坑点。如果没有微软雅黑字体,可以用系统自带的字体:
# 使用默认字体
font = ImageFont.load_default()
# 或者使用DejaVu字体(如果系统有安装)
# font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', 10)
获取系统信息的函数:
def getIPAddr():
ip_addresses = {}
for interface in netifaces.interfaces():
if interface != 'lo': # 排除回环接口
try:
addrs = netifaces.ifaddresses(interface)
ip_addresses[interface] = addrs[netifaces.AF_INET][0]['addr']
except:
ip_addresses[interface] = '0.0.0.0'
return ip_addresses
def getCPU():
return psutil.cpu_percent()
def getMem():
free = str(round(psutil.virtual_memory().free / (1024.0 * 1024.0 * 1024.0), 2))
total = str(round(psutil.virtual_memory().total / (1024.0 * 1024.0 * 1024.0), 2))
memory = int(psutil.virtual_memory().total - psutil.virtual_memory().free) / float(psutil.virtual_memory().total)
return int(memory * 100)
def getCurDate():
return time.strftime("%Y年%m月%d日", time.localtime())
def getCurTime():
return time.strftime("%H:%M:%S", time.localtime())
这些函数分别获取网络IP、CPU使用率、内存使用率、当前日期和时间。注意内存计算的那段代码:先把字节转换成GB,再计算使用百分比。这种转换让显示更加人性化。
显示函数是关键:
def mydraw(draw, x, y, message):
draw.text((x, y), message, font=font, fill='white')
这个简单的函数在指定位置显示文本。fill='white'是因为OLED屏通常是单色显示,白色在最常见的蓝色背景上最清晰。
主循环显示逻辑:
serial = i2c(port=1, address=0x3C)
device = ssd1306(serial, rotate=2, width=WIDTH, height=HEIGHT)
while True:
with canvas(device) as draw:
ipAddr = getIPAddr()
mydraw(draw, 0, 0, f"有线 : {ipAddr['eth0']}")
mydraw(draw, 0, 16, f"无线 : {ipAddr['wlan0']}")
time.sleep(5)
device.clear()
# 后续的CPU、内存、时间显示类似...
这里的rotate=2表示旋转180度,如果你的屏幕显示方向不对,可以调整这个参数(0、1、2、3分别对应不同旋转角度)。
4. 高级功能与优化
基础功能实现后,我们可以做一些优化和增强,让这个小小的OLED屏发挥更大作用。
显示优化技巧: 128×32的分辨率确实不高,所以显示布局要精心设计。我建议分屏显示,每屏显示一类信息:
- 第一屏:网络信息(有线IP和无线IP)
- 第二屏:系统状态(CPU和内存使用率)
- 第三屏:时间信息(日期和时间)
每屏显示2-3秒然后切换,这样信息量足够又不会显得拥挤。
添加动态效果: 虽然分辨率低,但也可以做一些简单的动画效果。比如在显示CPU使用率时,可以画一个简单的进度条:
def draw_progress_bar(draw, x, y, width, height, percent):
# 画边框
draw.rectangle((x, y, x + width, y + height), outline="white")
# 画填充
fill_width = int((width - 2) * percent / 100)
draw.rectangle((x + 1, y + 1, x + fill_width, y + height - 1), fill="white")
系统服务化: 让程序开机自启动是个很实用的需求。创建systemd服务:
sudo nano /etc/systemd/system/oled.service
添加以下内容:
[Unit]
Description=OLED Display Service
After=network.target
[Service]
ExecStart=/home/pi/oled-project/venv/bin/python /home/pi/oled-project/oled_display.py
WorkingDirectory=/home/pi/oled-project
User=pi
Restart=always
[Install]
WantedBy=multi-user.target
然后启用服务:
sudo systemctl enable oled.service
sudo systemctl start oled.service
这样树莓派启动后就会自动运行OLED显示程序,完全不需要手动干预。
功耗考虑: 虽然OLED屏本身功耗很低,但如果你打算24小时运行,可以考虑添加一些智能控制。比如在夜间自动降低亮度或关闭显示:
def adjust_brightness(hour):
if 23 <= hour or hour < 7: # 晚上11点到早上7点
device.contrast(10) # 低亮度
else:
device.contrast(255) # 正常亮度
5. 常见问题排查
在实际使用中,你可能会遇到各种问题。这里我总结了一些常见问题和解决方法。
屏幕不显示: 这是最常见的问题,排查步骤:
- 检查接线:VCC、GND、SCL、SDA是否接对
- 检查I2C是否启用:用
i2cdetect -y 1看是否能检测到设备 - 检查地址:有些屏幕地址可能是0x3D而不是0x3C
显示乱码: 如果显示中文乱码,通常是字体问题。可以尝试:
- 使用英文显示
- 安装中文字体:
sudo apt install fonts-wqy-microhei - 使用位图字体而不是TrueType字体
显示内容闪烁: 如果显示内容不时闪烁,可能是电源问题。尝试:
- 给树莓派接更稳定的电源
- 在VCC和GND之间加一个100μF的电容滤波
内存泄漏: 长期运行后如果发现内存占用过高,可以在代码中添加定期清理:
import gc
# 在循环中定期调用
gc.collect()
性能优化: 如果你发现显示刷新慢,可以尝试提高I2C总线速度:
# 在/boot/config.txt中添加
dtparam=i2c_arm_baudrate=400000
温度监控: 除了CPU和内存,还可以添加温度显示:
def get_temp():
with open("/sys/class/thermal/thermal_zone0/temp", "r") as f:
temp = float(f.read()) / 1000
return temp
这个项目最让我满意的是它的实用性和可扩展性。你不仅可以用它来监控系统状态,还可以显示天气预报、股票信息、新闻头条等等。我就在自己的树莓派上添加了室内温湿度显示,用起来特别方便。
硬件项目最怕的就是复杂难上手,但这个OLED屏项目真的做到了简单实用。从接线到编程,整个流程都很 straightforward。即使你是第一次玩树莓派,跟着步骤来也能成功。而且成本极低,一个OLED屏也就十几二十块钱,带来的便利却是实实在在的。
我在实际使用中发现,放在桌面上当个迷你监控器真的很实用。不需要开终端敲命令,一眼就能看到系统状态。特别是当树莓派作为服务器运行时,能快速确认网络连接是否正常,CPU负载是否过高。
更多推荐

所有评论(0)