嵌入式人工智能(7-树莓派4B的IIC总线连接OLED显示中文与图片)

1、IIC总线

IIC总线(Inter-Integrated Circuit)是一种串行通信总线,也被称为I2C总线。它由飞利浦(Philips)公司在1980年代开发,用于连接微处理器和外部设备。

IIC总线使用两根信号线:SDA(Serial Data)和SCL(Serial Clock)。SDA线用于数据传输,SCL线用于时钟同步。这两根线通过上拉电阻连接到正电源电压,数据传输时通过开漏或三态输出进行。

总的来说,IIC总线是一种常用的串行通信总线,具有低成本、低功耗和简单的硬件连接等优点。它广泛应用于各种设备和系统,如传感器、存储器、显示器、音频设备等。

打开终端命令,输入gpio readall,回车,在返回的IO表中可以看见有SDA1、SCL1;SDA0,SCL0两组I2C接口,我们使用SCL1与SDA1这一组进行。

2、OLED屏

OLED使用的是单色0.96英寸显示屏,它的驱动器是SSD1306,显示尺寸为128x64像素,使用I2C通信,如下图所示。

3、连接OLED

使用杜邦线将OLED连接到面包板上面的扩展卡,没有面包板直接接树莓派。VCC接3.3V引脚,GND接地,SDA接3 - GPIO 2 (SDA),SCL接5 - GPIO 3(SCL)。

4、启用系统IIC总线

一般把所有的总线、端口、服务,能打开的全部打开,不用担心功耗问题,这点电费还是不在话下的。

或者通过raspi-congifg命令进行开启。

启用后,通过输入ls /dev/*i2c* 命令检查用户模式的IIC端口

树莓派回复I2C端口名字,也可以通过i2C-tools工具测试扫描连接开发板上的任何I2C设备,新版该i2C-tools工具已经默认安装,如果没有安装,使用sudo apt-get install -y i2x-tools命令安装即可。安装后,通过sudo i2cdetect 1查看挂载到i2c总线上的设备。可看到该OLED从设备的寄存器地址为0x3c。

5、在OLED屏显示

(1)安装luma.oled库

使用pip install luma.oled 或者 pip3 install luma.oled ,也可以sudo,代表的含义不同。

这里有一些注意事项比较麻烦,一个是pip安装的设置安装源问题,一个是高版本的Python在树莓派linux上不让直接使用pip进行安装,需要虚拟环境。我不管,上来就开整。

1、设置pip

pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

2、修改权限

pip 不让安装模块:注意python版本号写你自己的别直接抄

sudo mv /usr/lib/python3.11/EXTERNALLY-MANAGED /usr/lib/python3.11/EXTERNALLY-MANAGED.bk

Installing collected packages: pyusb, cbor2, pyftdi, luma.core, luma.oled

Successfully installed cbor2-5.6.4 luma.core-2.4.2 luma.oled-3.13.0 pyftdi-0.55.4 pyusb-1.2.1

安装成功!

(2)Adafruit Python 库

这两个库都可以驱动OLED,大家找一个好用的自己摸索即可。

6、OLED屏显示Helloworld与中文

python 复制代码
import os
import glob
import time
from PIL import Image  
from PIL import ImageDraw
from PIL import ImageFont
import RPi.GPIO as GPIO
import time
import luma.oled as oled  
from luma.core.interface.serial import i2c    
from luma.oled.device import ssd1306  
from luma.core.render import canvas
  
WIDTH=128
HEIGHT=64 

# 指定编号规则为BOARD
GPIO.setmode(GPIO.BOARD)

# 关闭警告
GPIO.setwarnings(False)

# 设置输入引脚
channel = 13

# 设置GPIO输入模式, 使用GPIO内置的上拉电阻, 即开关断开情况下输入为HIGH
GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_UP)
 
def load_device():
    # 创建I2C接口对象  
    serial = i2c(port=1, address=0x3C)  # 地址可能因显示屏型号而异,由命令行"sudo i2cdetect -y 1"得到
    # 创建OLED设备对象  
    device = ssd1306(serial, WIDTH, HEIGHT) 
    return device

    
if __name__=='__main__':
    global device
    device = load_device()
    #font = ImageFont.load_default()
    font = ImageFont.truetype('SIMKAI.TTF',15)
    while True:
        if GPIO.input(channel)==GPIO.LOW:
            GPIO.cleanup()
            exit()
        with canvas(device) as draw:
            #draw.rectangle((0,0,WIDTH,HEIGHT), outline=0, fill=0)
            draw.rectangle(device.bounding_box, outline=0, fill=0)
            draw.text((0,0), "Hello World",font=font, fill=255)
            draw.text((0,20), '欢迎你!', font=font, fill="white")

显示中文报错的小伙伴这里需要注意了。

需要将字体文件拷贝到/usr/share/fonts/truetype/目录下面才行,还需要注意大小写。

sudo cp /home/pi/Embed_Python/STKAITI.TTF /usr/share/fonts/truetype/

7、OLED显示图片或者小视频

把这张图片放到指定目录中3_OLED\pic\里面,调用PIL库的resize和convert来转换为1位图像,如果是视频,要存放多张连贯的图片,并且用数字按顺序命名。

python 复制代码
import os
import glob
import time
from PIL import Image  
import luma.oled as oled  
from luma.core.interface.serial import i2c    
from luma.oled.device import ssd1306  
import RPi.GPIO as GPIO

# 指定编号规则为BOARD
GPIO.setmode(GPIO.BOARD)

# 关闭警告
GPIO.setwarnings(False)

# 设置输入引脚
channel = 13

# 设置GPIO输入模式, 使用GPIO内置的上拉电阻, 即开关断开情况下输入为HIGH
GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_UP)
   
WIDTH=128
HEIGHT=64 

def search_dir_pic(dir_name, suffix):
    # 设置文件夹路径  
    folder_path = os.path.join(os.getcwd(), dir_name)
    print(dir_name)
    print(folder_path)
    # 使用glob模块匹配以数字命名的文件  
    number_files = glob.glob(os.path.join(folder_path, '[0-9]*.'+suffix)) 
    print('图片文件名')
    print(number_files)
    return number_files
 
def load_device():
    # 创建I2C接口对象  
    serial = i2c(port=1, address=0x3C)  # 地址可能因显示屏型号而异,由命令行"sudo i2cdetect -y 1"得到
    # 创建OLED设备对象  
    device = ssd1306(serial, WIDTH, HEIGHT) 
    return device
  
def load_pic(pic_name):
    # 加载图片并调整大小  
    #print('ready show pic'+pic_name)
    image = Image.open(pic_name).convert('1')  # 转换为1位图像  
    image = image.resize((WIDTH, HEIGHT)) 
    return image
  
def show(image):
    # 将图片数据发送到OLED  
    device.display(image)
    time.sleep(1/24)
    
if __name__=='__main__':
    global device
    device = load_device()
    pic_group = search_dir_pic('3_OLED/pic', 'jpg')
    while True:
        if GPIO.input(channel)==GPIO.LOW:
            GPIO.cleanup()
            exit()
        for pic_file in pic_group:
            image = load_pic(pic_file)
            show(image)

总之用Pyhton语言来做就是搭积木,相比C语言的寄存器编程、库函数编程、HAL编程都要简单多了,我好像什么都没有写就完成简单的功能了。

相关推荐
AI_Claude_code3 天前
ZLibrary访问困境方案四:利用Cloudflare Workers等边缘计算实现访问
javascript·人工智能·爬虫·python·网络爬虫·边缘计算·爬山算法
视***间3 天前
智视无界,一采倾城 —— 视程空间高性能影像采集卡,开启视觉采集全新时代
人工智能·边缘计算·采集卡·ai算力·视程空间·视频采集卡
Code-keys3 天前
ADSP/ARM 性能/稳定性排查专栏总述
arm开发·算法·边缘计算·dsp开发
视***间3 天前
智采高清,视界无界——视程空间视频采集卡,定义专业采集新标杆
人工智能·机器人·音视频·边缘计算·采集卡·视程空间·视频采集卡
竹之却4 天前
【Agent-阿程】AI先锋杯·14天征文挑战第14期-第2天-大模型部署与优化实战
人工智能·ai·大模型·边缘计算·剪枝·优化·蒸馏
roman_日积跬步-终至千里4 天前
【系统架构师-案例题-Web应用系统架构设计】22年(4)基于边缘计算的智能门禁系统
人工智能·系统架构·边缘计算
武汉唯众智创4 天前
AI 三大赛道(边缘计算 / 全栈开发 / 智能体)如何适配高职 & 职教本科专业建设
人工智能·边缘计算·智能体·职教实训建设·ai 全栈开发
河南博为智能科技有限公司5 天前
蓄电池在线监测系统-守护数据中心安全防线
运维·边缘计算
搜佛说5 天前
比SQLite更快,比InfluxDB更轻:sfsDb的降维打击
jvm·数据库·物联网·架构·sqlite·边缘计算·iot
搜佛说5 天前
01-第1章-概述与快速开始
物联网·golang·开源·软件工程·边缘计算·嵌入式实时数据库