【前提】:首先保证你的液晶屏幕能正常显示英文,可以参考本人的这个教程:
树莓派+OLCD 12864液晶屏+SSD1306芯片驱动(2020-09-09) - https://www.jianshu.com/p/8a5824a049e2
在网上找了好久,没发现有好用的python在ssd1306液晶屏上显示中文的办法, 自己汇总了多家的教程,整理如下,测试通过!
测试环境:树莓派4+python3.7+ssd1306液晶屏(0.96寸)
直接上代码:
import time
import Adafruit_GPIO.SPI as SPI
import Adafruit_SSD1306
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
# Raspberry Pi pin configuration:
RST = None
# 128x64 display with hardware I2C:
disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST)
# Initialize library.
disp.begin()
# Clear display.
disp.clear()
disp.display()
# Make sure to create image with mode '1' for 1-bit color.
width = disp.width #128
height = disp.height #64
image = Image.new('1', (width, height))
# Get drawing object to draw on image.
draw = ImageDraw.Draw(image)
# 调用默认字体,或者自行设置指定字体
font = ImageFont.load_default()
font16 = ImageFont.truetype('/usr/share/fonts/truetype/ttf-bitstream-vera/VeraBd.ttf', 16)
###################################
## 汉字部分
###################################
#1、先建立字模,可以用 pc2lcd2002完美版 软件,设置如下,即可生成字模,注意字模选项要如图设置
#2、将每个中文字转成16进制编码, 可用下面的模块【txt2hex】生成对应关系 如(我= 0xe68891)
#3、把字模每行开头的【改此处】替换为这个汉字的16进制数,
#4、最终字模结果如下:
fonts= {
0xe6989f: [0x00,0x1F,0x10,0x1F,0x10,0x1F,0x01,0x11,0x1F,0x21,0x41,0x1F,0x01,0x01,0x7F,0x00,0x00,0xF0,0x10,0xF0,0x10,0xF0,0x00,0x00,0xF8,0x00,0x00,0xF0,0x00,0x00,0xFC,0x00],#星0
0xe69c9f: [0x22,0x22,0x7F,0x22,0x22,0x3E,0x22,0x22,0x3E,0x22,0x22,0xFF,0x04,0x22,0x41,0x82,0x00,0x7C,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x7C,0x44,0x44,0x84,0x84,0x14,0x08],#期1
0xe4b880: [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],#一2
0xe4ba8c: [0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00],#二3
0xe4b889: [0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00],#三4
0xe59b9b: [0x00,0x00,0x7F,0x44,0x44,0x44,0x44,0x44,0x48,0x48,0x50,0x60,0x40,0x7F,0x40,0x00,0x00,0x00,0xFC,0x44,0x44,0x44,0x44,0x44,0x44,0x3C,0x04,0x04,0x04,0xFC,0x04,0x00],#四5
0xe4ba94: [0x00,0x7F,0x02,0x02,0x02,0x02,0x3F,0x04,0x04,0x04,0x04,0x08,0x08,0x08,0xFF,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xFE,0x00],#五6
0xe585ad: [0x02,0x01,0x00,0x00,0x00,0xFF,0x00,0x00,0x04,0x04,0x08,0x08,0x10,0x20,0x40,0x00,0x00,0x00,0x80,0x80,0x00,0xFE,0x00,0x00,0x40,0x20,0x10,0x08,0x08,0x04,0x04,0x00],#六7
0xe697a5: [0x00,0x1F,0x10,0x10,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x10,0x10,0x10,0x1F,0x10,0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0xF0,0x10],#日8
0xe68891: [0x04,0x0E,0x78,0x08,0x08,0xFF,0x08,0x08,0x0A,0x0C,0x18,0x68,0x08,0x08,0x2B,0x10,0x40,0x50,0x48,0x48,0x40,0xFE,0x40,0x44,0x44,0x48,0x30,0x22,0x52,0x8A,0x06,0x02],#我9
0xe5bc80: [0x00,0x7F,0x08,0x08,0x08,0x08,0x08,0xFF,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x40,0x00,0xFC,0x20,0x20,0x20,0x20,0x20,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20],#开10
0xe5bf83: [0x00,0x02,0x01,0x00,0x00,0x04,0x04,0x24,0x24,0x24,0x44,0x44,0x84,0x04,0x03,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x08,0x04,0x04,0x02,0x02,0x12,0x10,0x10,0xF0,0x00],#心11
}
#在屏幕上显示汉字, txt2lcd("字符串内容",屏幕x坐标,屏幕y坐标),支持中英文混显
def txt2lcd(ch_str, xx, yy):
for k in ch_str:
print(k)
if k in ("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijlkmnopqrstuvwxyz,.!()"): #如果当前字符是英文、数字或标点,则直接调用自身字库显示,内容可以自己修改
draw.text((xx,yy), k,font=font16, fill=255)
xx=xx+12
else: #如果检测到当前字符是中文,则直接调用自定义的字模显示
code = 0x00 # 将中文转成16进制编码
data_code = k.encode("utf-8")
code |= data_code[0] << 16
code |= data_code[1] << 8
code |= data_code[2]
byte_data = fonts[code]
for y in range(0, 16):
left8 = bin(byte_data[y]).replace('0b', '')
left8 = ('00000000'+left8)[-8:] #如果不足8位,直接补齐8位,如从0010,补齐成00000010,代表汉字每一行左半部分8个像素点。0代表像素点不亮,1代表像素点亮
right8 = bin(byte_data[y+16]).replace('0b', '')
right8 = ('00000000'+right8)[-8:] #代表汉字每一行右半部分8个像素点
all16 = left8+right8 #拼成每一行16个像素点
#print(all16)
for x in range(0, 16): #开始循环检测,如果是1,则在这个位置点亮像素点
if all16[x] == "1" :
weizhi=(xx+x,yy+y)
draw.point(weizhi,fill=255)
xx=xx+16 #显示完一个汉字,显示下一个时,x位置向右移16像素
# txt2hex为建字模用的。前期的时候可以用到,后期可以注释掉
# 将中文转成16进制编码,对应关系如(我= 0xe68891)
def txt2hex(ch_str):
for k in ch_str:
code = 0x00
data_code = k.encode("utf-8")
code |= data_code[0] << 16
code |= data_code[1] << 8
code |= data_code[2]
print(k+" "+hex(code))
txt2hex('星期一二三四五六日我开心')
#########################
# 主程序循环开始
#########################
while True:
# 先清理屏幕
draw.rectangle((0,0,width,height), outline=0, fill=0)
# 获取日期、时间、星期几
my_date=time.strftime("%Y-%m-%d",time.localtime()) #获取日期如 2020-09-23
my_time=time.strftime("%H:%M:%S",time.localtime()) #获取时间如 13:15:03
my_week=time.strftime("%w",time.localtime()) #获取周几,返回0-6, 0代表周日,1代表周一
# 显示日期、时间、周几(数字格式的)
draw.text((28, 0), my_time , font=font16, fill=255)
draw.text((16, 20), my_date , font=font16, fill=255)
draw.text((88, 40), "("+my_week+")" , font=font16, fill=255)
# 显示中文的星期几(为了好理解,用的简单易懂的代码)
if my_week == "0":
txt2lcd('星期日',40,40)
elif my_week=="1":
txt2lcd('星期一',40,40)
elif my_week=="2":
txt2lcd('星期二',40,40)
elif my_week=="3":
txt2lcd('星期三',40,40)
elif my_week=="4":
txt2lcd('星期四',40,40)
elif my_week=="5":
txt2lcd('星期五',40,40)
elif my_week=="6":
txt2lcd('星期六',40,40)
# 刷新屏幕,显示内容
disp.image(image)
disp.display()
# 每隔几秒刷新一次
time.sleep(1)
PCtoLCD的设置方式:
段前缀:fonts= {
段后缀:}
注释前缀:,#
注释后缀:
数据前缀:0x
数据后缀:,
行前缀:改此处:[
行后缀:
行尾缀:]