网上对于SSD1306的中文技术文章应用并不多,甚至都没有有关 局部刷新的文章。我在这里说下我的实现方案
本人技术有限。如果有更好的代码实现能告诉我那就再感激不过了。
关于接线,很简单,套用一张网上的图:
关于底层实现,我研究了Adafruit_Python_SSD1306的源码,麻烦的是不同硬件设备的适配问题。感谢开源的伟大。
git clone https://github.com/adafruit/Adafruit_Python_SSD1306.git # 下载源码
cd Adafruit_Python_SSD1306 # 移动到源码文件夹
sudo python3 ez_setup.py install # 先安装这个 顺序不要搞错了
sudo python3 setup.py install
首先导入我们需要的库:
import Adafruit_SSD1306
import time
import threading
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
PIL库会在上面安装Adafruit_Python_SSD1306时自动给你安装。这里会用到多线程,关于这个屏幕刷新,如果你想实现的东西多了,自然会用到的吧。
虽然我这个例子不会用到。还是写出来学习一下。
我还打算添加其他功能,代码规范化还是很有必要的。
如果你还不会多线程,可以参考 python 多线程就这么简单 我也是现学现用。这文章确实写的非常好,通俗易懂。
你可以在Adafruit_Python_SSD1306中找到例子,打开看会有一堆初始化代码。那主要是为了适配硬件设备的。我自己用的时只有四个管脚,I2C通信的0.96oled屏幕,所以我就直接吧适配的代码节减掉一部分。如果你使用的时spi通信。稍稍修改就可以实现。我会在以后更新更优的内容。
先把这段整个代码贴出来,再分段解释:
class SSD1306_IIC:
def __init__(self): # 初始化
self.disp = Adafruit_SSD1306.SSD1306_128_64(rst=24)
self.disp.begin()
self.disp.clear()
self.disp.display()
self.width = self.disp.width
self.height = self.disp.height
self.image = Image.new('1', (self.width, self.height))
self.draw = ImageDraw.Draw(self.image)
def Drawnow(self): # 屏幕刷新
self.disp.image(self.image)
self.disp.display()
def Cleanup(self, size=None): # 局部覆盖矩形or整体覆盖矩形
if size is None:
size = (0, 0, self.width, self.height)
self.draw.rectangle(size, outline=0, fill=0)
def Text(self, size, content, font, fontsize, visible=True):
# Some other nice fonts to try: http://www.dafont.com/bitmap.php
if visible == True:
self.draw.text(size, content, font=ImageFont.truetype(font, fontsize), fill=255)
elif visible == False:
self.draw.text(size, content, font=ImageFont.truetype(font, fontsize), fill=0)def
init 内的代码就是初始化。 你会发现,如果单独使用Cleanup函数屏幕是没有任何变化的。因为还需要调用Drawnow刷新一下屏幕。
全局刷新是设一个充满屏幕的矩形覆盖, 局部刷新就是指定区域设置一个矩形覆盖,不只是矩形,甚至连字体都可以这样做。
重点说下Text中最后一个参数visible,这个就相当于文章刷新了,仔细看不难发现其实只有 fill 参数改变了。
你可以这样理解,0就相当于 假,225就相当于 真。控制区域像素点的亮灭。这里的区域就是文字。
具体代码实现在后面。
我们要将用到的字体ttf文件就跟代码文件放在同一文件夹。字体最好是bitmap(位图)。
屏幕是可以显示中文的。可是我一直没找到较好的中文字体。so放弃,如果你有好的中文字体能发给我那就太好了。我找了接近一天,实践了20多个ttf字体。远点看还好,稍微近了,歪歪扭扭。
具体的局部刷新实现在这里,我们以时间为例:
class displayTime(SSD1306_IIC):
def nowTime(self):
# time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
font = 'dos.ttf'
size = (0, 0)
#先初始化显示时间
#因为当初我是没有秒的,所有是设置的10秒刷新一次。
self.Text(size, time.strftime("%H:%M:%S", time.localtime()), font, 16)
while 1:
oldTime = time.strftime("%H:%M:%S", time.localtime())
time.sleep(0.2)
newTime = time.strftime("%H:%M:%S", time.localtime())
if oldTime != newTime:
self.Text(size, oldTime, font, 16, False)
self.Text(size, newTime, font, 16)
def threadDrawnow(self): # 帧的概念
while 1:
self.Drawnow()
time.sleep(0.1)
def main(self):
GUI = []
time__ = threading.Thread(target=self.nowTime)
GUI.append(time__)
Drawnow__ = threading.Thread(target=self.threadDrawnow)
GUI.append(Drawnow__)
for i in GUI:
i.setDaemon(True)
i.start()
i.join()
这里用到了两个线程,一个是nowtime另一个就是 threadDrawnow了。这就相当与 帧 的概念。你还可以添加更多的东西到线程。这就是我写线程的原因。打算在以后添加更有用的东西,而不仅仅只是显示时间。
关于时间你可以在linux终端输入 date 查看当前时间。如果你没有设置,一般会相差8小时。
这就是时区问题了。
sudo raspi-config
- 打开第四个 Localisation Options 本地化设置
- 打开第二个Change Timezone 改变时区
- 选择Asia 亚洲
- 最后选择Chongqing 重庆
python中调用当前时间要导入time模块,我们在代码开头已经导入了。
>>>time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
>>>'2017-06-06 11:31:29' # 返回的是字符串
这篇文章我是写在自己的博客上的,但是搜索引擎根本搜索不到这篇文章。所以转载到。希望大家多多评价。
完。