树莓派3B与0.96 oled屏幕的局部刷新实践探讨 IIC实现

网上对于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' # 返回的是字符串

这篇文章我是写在自己的博客上的,但是搜索引擎根本搜索不到这篇文章。所以转载到简书。希望大家多多评价。

完。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,980评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,422评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,130评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,553评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,408评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,326评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,720评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,373评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,678评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,722评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,486评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,335评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,738评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,283评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,692评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,893评论 2 335

推荐阅读更多精彩内容