树莓派系列:驱动SSD1306 OLED屏幕
源码:https://github.com/Taosky/SSD1306
起因在V2EX看到有人用树莓派做了一个发呆用的小屏幕,也想折腾一下,淘宝挑屏比较纠结,后来看到有家店卖OLED屏,于是就买来尝试一下。
到了之后发现还是很小的,0.96寸,看新闻好像不太行了,显示温度时间什么的就好了。
准备
首先是连线,支持3.3V~5V,VCC接3.3V,GND接GND口,SDA接GPIO3,SCL接GPIO2,(看网上都是接这两个
由于采用I2C通信,需要打开树莓派上的I2C功能。
sudo apt-get install -y python-smbus
sudo apt-get install -y i2c-tools
sudo raspi-config
选择Interfacing Options - I2C打开。
运行“sudo i2cdetect -y 1”测试能不能看到I2C的地址,如下就是成功获取地址了。
驱动
卖家提到的Github上的项目是Node写的,看不大明白,根据上面的信息搜了SSD1306找到一个叫luma的Python库可以驱动这块屏幕。
在luma.example中有一些示例可以学习。
首先要理解几个概念:
要在屏幕上显示内容可以理解成是在”画布“上画图,再将画布显示出来。因此在显示文字的时候也是传输的图而不是文字本身,需要选用字体显示。
变化屏幕上显示的内容需要用一张新的“画布”覆盖,如果不进行覆盖,屏幕就一直显示当前的“画布”,除非对它发送指令关闭。
因为是画布,所以可以显示我们所需要的任意内容,文字、图形、图像都是可以显示的。
显示文字的话调用draw.text,使用正确的字体就可以了,可以控制字体大小、颜色等参数。
这里在导入字体的时候设置字号为21,绘制字体的时候指定字体并设置了显示位置(可以根据128x64计算确定大概的位置),time.sleep(8)让程序休眠8秒,也就是让“画布”保持8秒不被后面的画布覆盖。
font_path = os.path.abspath(os.path.join(os.path.dirname(__file__), 'fonts', 'code2000.ttf')) # 导入字体文件font1 = ImageFont.truetype(font_path, 21)with canvas(my_device) as draw:
draw.text((32, 0), '树莓派', font=font1, fill="white")
draw.text((20, 21), sensor_data_to_show[0], font=font3, fill="white")
time.sleep(8)
显示图像稍微复杂一点,以天气图标和温度的显示作为示例。
首先是导入图像,然后将图像转换成RGBA模式,创建一个适配设备的空白图像,将要显示的图像“粘贴”到空白图像上;这时还需要一个温度文字的显示,通过类似的方法,将文字画到图像上就完成了。最后使用device.display()显示图像(我也不知道为啥是display(+_+)?)
icon_path = os.path.abspath(os.path.join(os.path.dirname(__file__),'weather_icon', '200.jpg'))
weather_icon = Image.open(icon_path)
inverted_icon = ImageOps.invert(weather_icon).convert("RGBA")
weather_image = Image.new("RGBA", device_size)
weather_image.paste(inverted_icon, (0, 0))
draw = ImageDraw.Draw(weather_image)
draw.text((66, 12), '32℃', (255, 255, 255), font=font2)
my_device.display(weather_image.convert(my_device.mode))
至此基本就解决显示图像的问题了,当然这只是最简单的显示,比如luma示例里面的时间显示就很复杂。
问题
亮度似乎无法调低,通过device.contrast()设置为1好像还是很亮。
哒哒
校验提示文案
哒哒
校验提示文案