该文章是在研究出温度传感器的使用和OLED的使用后将其进行结合的文章,主要目的是让OLED显示屏显示当前的温度。
先上一张效果图~
OLED:
GND————接地
VCC————3.3 ~ 5V
SCL————串行时钟
SDA————串行数据
驱动芯片————SSD1306
通信方式————IIC
分辨率————128 * 64
支持显示————一般为数字、大小写英文
温度传感器(DS18B20):
- 独特的单线接口方式
- 测温范围 -55℃~+125℃,固有测温误差1℃
- 支持多点组网功能,多个DS18B20可以并联在唯一的三线上,最多只能并联8个,实现多点测温,如果数量过多,会使供电电源电压过低,从而造成信号传输的不稳定
- 工作电源: 3.0~5.5V/DC
- 在使用中不需要任何外围元件
其中对OLED 屏幕或DS18B20温度传感器有疑惑的可以看另外两篇文章:
树莓派4B-Python-使用SSD1306 OLED
树莓派4B-Python-控制DS18B20(温度传感器)
OLED:
红色线————5V
黑色线————GND
黄色线————SCL
绿色线————SDA
温度传感器:
白色线————3.3V
灰色线————GND
橙色线————GPIO04
代码如下:
#!/usr/bin/python3
from luma.core.interface.serial import i2c, spi
from luma.core.render import canvas
from luma.oled.device import ssd1306, ssd1325, ssd1331, sh1106
# PIL是树莓派系统自带的库,在这用于加载楷体字体
from PIL import ImageFont
import os,time
# 该路径为单总线生成并存放地址的路径
device_file ='/sys/bus/w1/devices/28-012029ad0b30/w1_slave'
def read_temp_raw():
f = open(device_file,'r')
lines = f.readlines()
f.close()
return lines
def read_temp():
lines = read_temp_raw()
while lines[0].strip()[-3:] != 'YES':
time.sleep(0.2)
lines = read_temp_raw()
equals_pos = lines[1].find('t=')
if equals_pos != -1:
temp_string = lines[1][equals_pos+2:]
temp_c = float(temp_string)/1000.0
temp_c = str(temp_c)
return temp_c
serial = i2c(port=1, address=0x3C)
device = ssd1306(serial)
# 用于加载字体,'simkai.ttf'为中文楷体,该文件可以直接从windows的C盘中搜索,然后复制过来放在与该程序同一文件夹下即可
# 后面的数字'15'为字体的大小
font = ImageFont.truetype('simkai.ttf', 15)
try:
while 1:
temp1 = '温度 = ' + read_temp() + "度"
temp0 = 'temp = ' + read_temp() + "C"
print(temp0) # 这里可能是同时获取温度的缘故所以导致有时候显示的温度值不一至
print(temp1)
with canvas(device) as draw:
# 用于显示一个框(在屏幕最外一圈)
draw.rectangle(device.bounding_box, outline="white", fill="black")
# 20为OLED上X轴上移动的距离;
# 0为Y轴上移动的距离;
# 显示的内容需要以字符串形式呈现;
# 填充的颜色为‘white’白色,但因目前使用的OLED只有一种颜色所以不能显示白色;
draw.text((20, 20), str(temp0), fill="white")
# 若想显示中文,则需要加载支持中文的字体,并更改替换默认的font即可
draw.text((5, 3), str(temp1), font=font, fill="white")
draw.text((20, 40), '度', font=font, fill="white")
print('当前温度是',read_temp(),'度\n')
time.sleep(0.1)
except IndexError:
print('指示错误')
如果没仔细看过上面这个代码的话肯定会出现类似以下的报警:
这个问题(无法在屏幕上显示中文字幕)已经得到解决,它需要转换一下字体呀什么的七七八八的东西,所以需要用到一个“ .ttf ”后缀的字体文件:
from PIL import ImageFont
font = ImageFont.truetype('simkai.ttf', 15)
这里使用的是 simkai.ttf (中文楷体),这个文件可以直接在win10C盘中搜索出来,当然想直接下载本人验证过可以使用的字体转换文件也行的啦~~字体文件放在与该程序同一文件夹下即可
链接: 加载的楷体字体文件
以下是luma.oled库的使用说明:
luma.oled文档内对get_font的使用说明
本人是没怎么看得明白了,也是抱着试一试的态度试了一下,然后就莫名其妙的成功了…
draw.text((20, 40), '度', font=font, fill="white")
将默认用的 font 替换成楷体的 font 就完事了
之后会继续开拓新用途,以花样玩坏OLED屏幕为目标!