1071 字
5 分钟
树莓派 Pico 驱动墨水屏显示信息

墨水屏#

显示屏为 2.13 寸黑白电子墨水屏,于 微雪电子 购买,并利用树莓派 Pico 驱动以显示信息。

树莓派 Pico 环境搭建#

于树莓派 5 上进行环境搭建。

创建 pico 文件夹并进入。

mkdir pico
cd pico

Raspberry Pi Pico SDK#

参考 GitHub 页面。

安装依赖#

安装 CMakeGCC 编译器及其相关依赖。

sudo apt install cmake gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib

克隆存储库#

git clone https://github.com/raspberrypi/pico-sdk.git

添加环境变量#

vi ~/.bashrc

添加 PICO_SDK_PATH 路径。

export PICO_SDK_PATH=/home/ubuntu/pico/pico-sdk

使环境变量立即生效。

source ~/.bashrc

picotool#

参考 GitHub 页面。

首先于 pico-sdk 路径下克隆相关库。

cd /home/ubuntu/pico/pico-sdk
git submodule update --init lib/mbedtls
git submodule update --init

若因为网络原因无法完成克隆,可参考错误信息手动克隆至相关目录下。

Submodule 'lib/mbedtls' (https://github.com/Mbed-TLS/mbedtls.git) registered for path 'lib/mbedtls'
Submodule 'lib/btstack' (https://github.com/bluekitchen/btstack.git) registered for path 'lib/btstack'
Submodule 'lib/cyw43-driver' (https://github.com/georgerobotics/cyw43-driver.git) registered for path 'lib/cyw43-driver'
Submodule 'lib/lwip' (https://github.com/lwip-tcpip/lwip.git) registered for path 'lib/lwip'
Submodule 'tinyusb' (https://github.com/hathach/tinyusb.git) registered for path 'lib/tinyusb'

安装依赖#

sudo apt install build-essential pkg-config libusb-1.0-0-dev cmake

克隆存储库#

cd ~/pico
git clone https://github.com/raspberrypi/picotool.git

编译安装#

cd picotool
mkdir build
cd build
cmake ..
make -j8
sudo make install

去除 sudo 权限#

cd ~/pico/picotool
sudo cp udev/99-picotool.rules /etc/udev/rules.d/

树莓派 Pico 部分程序#

例程下载#

cd ~/pico
wget  https://www.waveshare.net/w/upload/2/27/Pico_ePaper_Code.zip
unzip Pico_ePaper_Code.zip -d Pico_ePaper_Code
cd Pico_ePaper_Code

编写程序#

cd c
mv main.c main.c.bak
vi main.c

程序为以下内容。

#include "DEV_Config.h"
#include "GUI_Paint.h"
#include "ImageData.h"
#include "Debug.h"
#include <stdlib.h>
#include "EPD_2in13_V4.h"
#include "string.h"

int main(void)
{
    stdio_init_all();
    unsigned char data[100]={0};
    unsigned char cpu[100]={0};
    unsigned char cpu_i[100]={0};
    unsigned char cpu_o[100]={0};
    unsigned char mem_p[100]={0};
    unsigned char mem_u[100]={0};
    unsigned char mem_t[100]={0};
    unsigned char disk_p[100]={0};
    unsigned char disk_u[100]={0};
    unsigned char disk_t[100]={0};
    unsigned char ipv4[100]={0};
    unsigned char ipv6[100]={0};

    if(DEV_Module_Init()!=0){
        return -1;
    }

    EPD_2in13_V4_Init();
    EPD_2in13_V4_Clear();

    UBYTE *BlackImage;
    UWORD Imagesize = ((EPD_2in13_V4_WIDTH % 8 == 0)? (EPD_2in13_V4_WIDTH / 8 ): (EPD_2in13_V4_WIDTH / 8 + 1)) * EPD_2in13_V4_HEIGHT;
    if((BlackImage = (UBYTE *)malloc(Imagesize)) == NULL) {
        return -1;
    }
    Paint_NewImage(BlackImage, EPD_2in13_V4_WIDTH, EPD_2in13_V4_HEIGHT, 90, WHITE);
        Paint_Clear(WHITE);

    int n=0;
    int count=0;

    while(1){
    
    n+=1;

    printf("input name: ");
    scanf("%s", data);
    printf("\nHello, %s\n\n", data);
    sscanf(data, "%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%s", &cpu, &cpu_i, &cpu_o, &mem_p, &mem_u, &mem_t, &disk_p, &disk_u, &disk_t, &ipv4, &ipv6);
    printf("%s\n",cpu);
    printf("%s\n\n",cpu_i);

    EPD_2in13_V4_Init_Fast();
    Paint_NewImage(BlackImage, EPD_2in13_V4_WIDTH, EPD_2in13_V4_HEIGHT, 90, WHITE);
    Paint_SelectImage(BlackImage);
    
    Paint_ClearWindows(70, 20, 70 + Font20.Width * 4, 20 + Font20.Height, WHITE);
    Paint_ClearWindows(151, 24, 151 + Font16.Width *4, 24 + Font16.Height, WHITE);
    Paint_ClearWindows(206, 24, 206 + Font16.Width *4, 24 + Font16.Height, WHITE);
    Paint_ClearWindows(70, 40, 70 + Font20.Width * 4, 40 + Font20.Height, WHITE);
    Paint_ClearWindows(151, 44, 151 + Font16.Width *4, 44 + Font16.Height, WHITE);
    EPD_2in13_V4_Display_Partial(BlackImage);
    //DEV_Delay_ms(500);
    Paint_DrawString_EN(70, 20, &cpu, &Font20, WHITE, BLACK);
    Paint_DrawString_EN(151, 24, &cpu_i, &Font16, WHITE, BLACK);
    Paint_DrawString_EN(206, 24, &cpu_o, &Font16, WHITE, BLACK);
    Paint_DrawString_EN(70, 40, &mem_p, &Font20, WHITE, BLACK);
    Paint_DrawString_EN(151, 44, &mem_u, &Font16, WHITE, BLACK);
    EPD_2in13_V4_Display_Partial(BlackImage);
    DEV_Delay_ms(500);
    EPD_2in13_V4_Sleep();
    DEV_Delay_ms(4000);
    
    if(n>=50 || count==0){
        count=1;
        n=0;
        EPD_2in13_V4_Init_Fast();
        Paint_NewImage(BlackImage, EPD_2in13_V4_WIDTH, EPD_2in13_V4_HEIGHT, 90, WHITE);
        Paint_Clear(WHITE);

        Paint_DrawString_EN(27, 0, "Raspberry Pi 5", &Font20, WHITE, BLACK);
        Paint_DrawString_EN(0, 20, "CPU:     %", &Font20, WHITE, BLACK);
        Paint_DrawString_EN(195, 24, "|", &Font16, WHITE, BLACK);
        Paint_DrawString_EN(0, 40, "Mem:     %", &Font20, WHITE, BLACK);
        Paint_DrawString_EN(195, 44, "/", &Font16, WHITE, BLACK);
        Paint_DrawString_EN(206, 44, &mem_t, &Font16, WHITE, BLACK);
        Paint_DrawString_EN(0, 60, "Disk:    %", &Font20, WHITE, BLACK);
        Paint_DrawString_EN(195, 64, "/", &Font16, WHITE, BLACK);
        Paint_DrawString_EN(70, 60, &disk_p, &Font20, WHITE, BLACK);
        Paint_DrawString_EN(151, 64, &disk_u, &Font16, WHITE, BLACK);
        Paint_DrawString_EN(206, 64, &disk_t, &Font16, WHITE, BLACK);
        Paint_DrawString_EN(0, 82, "IPv4:", &Font16, WHITE, BLACK);
        Paint_DrawString_EN(55, 80, &ipv4, &Font20, WHITE, BLACK);
        Paint_DrawString_EN(0, 102, "IPv6:", &Font16, WHITE, BLACK);
        Paint_DrawString_EN(55, 106, &ipv6, &Font8, WHITE, BLACK);
        EPD_2in13_V4_Display_Base(BlackImage);
        DEV_Delay_ms(3000);
    }

    }

    EPD_2in13_V4_Sleep();
    free(BlackImage);
    BlackImage = NULL;
    DEV_Delay_ms(2000);
    return 0;
}

加入头文件路径#

编辑 ~/pico/Pico_ePaper_Code/c/CMakeLists.txt 文件。

# add a header directory
include_directories(./lib/e-Paper)

编译程序#

mkdir build
cd build
cmake ..
make -j8

运行程序#

按住树莓派 Pico 上的 BOOTSEL 按键,同时使用 Micro USB 数据线将 树莓派 Pico 连接至 树莓派 5,连接后放开按键,即可看到树莓派 Pico 的存储空间。

挂载树莓派 Pico 存储。

sudo mount /dev/sda1 /mnt/pico

复制 epd.uf2 文件。

sudo cp -v epd.uf2 /mnt/pico/

释放树莓派 Pico 存储。

sudo umount /mnt/pico

此时树莓派 Pico 将自动运行程序。

树莓派 5 部分程序#

树莓派 5 部分为 Python 程序。

安装完整版 Python#

sudo apt update
sudo apt install python3-full

编写程序#

cd ~
mkdir python
cd python
vi pico.py

添加以下程序。

import psutil
import serial
import time

pico=serial.Serial("/dev/ttyACM0",115200)

while True:

    print("Raspberry Pi 5")

    cpu=psutil.cpu_percent(1)
    cpu_temp=psutil.sensors_temperatures()
    print(f"CPU: {cpu}% {cpu_temp['cpu_thermal'][0].current}C/{cpu_temp['rp1_adc'][0].current}C")
    cpu_i=round(cpu_temp['cpu_thermal'][0].current,1)
    cpu_o=round(cpu_temp['rp1_adc'][0].current,1)


    mem=psutil.virtual_memory()
    print(f"Mem: {mem.percent}%({((mem.total-mem.available)/1024**3):.2f}GB/{(mem.total/1024**3):.2f}GB)")
    mem_p=mem.percent
    mem_u=round(((mem.total-mem.available)/1024**3),2)
    mem_t=round((mem.total/1024**3),2)

    disk=psutil.disk_usage('/')
    print(f"Disk: {disk.percent}%({(disk.used/1024**3):.2f}GB/{(disk.total/1024**3):.2f}GB)")
    disk_p=disk.percent
    disk_u=round((disk.used/1024**3),1)
    disk_t=round((disk.total/1024**3),1)

    net=psutil.net_if_addrs()
    print(f"IPv4: {net['eth0'][0].address}")
    print(f"IPv6: {net['eth0'][1].address}")
    ipv4=net['eth0'][0].address
    ipv6=net['eth0'][1].address

    data=str(cpu)+','+str(cpu_i)+','+str(cpu_o)+','+str(mem_p)+','+str(mem_u)+','+str(mem_t)+','+str(disk_p)+','+str(disk_u)+','+str(disk_t)+','+str(ipv4)+','+str(ipv6)+'\n'
    print(data)
    pico.write(data.encode("utf-8"))

    time.sleep(5)

虚拟环境#

创建虚拟环境。

python3 -m venv venv

进入虚拟环境。

source venv/bin/activate

安装第三方库。

pip install psutil pyserial 

添加执行权限。

chmod +x pico.py

运行程序。

python3 pico.py

退出虚拟环境。

deactivate

开机自动运行#

利用 bash 脚本与 systend 服务使其成为守护进程。

编写 bash 脚本#

vi pico.sh

添加以下内容。

#!/usr/bin/bash
source /home/ubuntu/python/venv/bin/activate
python3 /home/ubuntu/python/pico.py

添加执行权限。

chmod +x pico.sh

添加系统服务。

cd /etc/systemd/system
sudo vi pico.service

添加以下内容。

[Unit]
Description=pico e-Paper
After=network-online.target
Wants=network-online.target

[Service]
TimeoutStartSec=0
ExecStart=/home/ubuntu/python/pico.sh
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target

添加开机启动服务。

sudo systemctl enable pico

启动服务。

sudo systemctl start pico

查看服务状态。

sudo systemctl status pico

至此墨水屏可以正常显示树莓派 5 系统信息。


参考#

  1. Pico-ePaper-2.13 - Waveshare Wiki

  2. raspberrypi/pico-sdk (github.com)

  3. raspberrypi/picotool (github.com)

树莓派 Pico 驱动墨水屏显示信息
https://blog.wely.fun/posts/树莓派-pico-驱动墨水屏显示信息/
作者
Wely
发布于
2024-08-18
许可协议
CC BY-NC-SA 4.0