1071 字
5 分钟
树莓派 Pico 驱动墨水屏显示信息
墨水屏
显示屏为 2.13
寸黑白电子墨水屏,于 微雪电子 购买,并利用树莓派 Pico 驱动以显示信息。
树莓派 Pico 环境搭建
于树莓派 5 上进行环境搭建。
创建 pico
文件夹并进入。
mkdir pico
cd pico
Raspberry Pi Pico SDK
参考 GitHub 页面。
安装依赖
安装 CMake
和 GCC
编译器及其相关依赖。
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 系统信息。
参考
树莓派 Pico 驱动墨水屏显示信息
https://blog.wely.fun/posts/树莓派-pico-驱动墨水屏显示信息/