1071 字
5 分钟
树莓派 Pico 驱动墨水屏显示信息
墨水屏
显示屏为 2.13 寸黑白电子墨水屏,于 微雪电子 购买,并利用树莓派 Pico 驱动以显示信息。
树莓派 Pico 环境搭建
于树莓派 5 上进行环境搭建。
创建 pico 文件夹并进入。
mkdir picocd picoRaspberry 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 ~/.bashrcpicotool
参考 GitHub 页面。
首先于 pico-sdk 路径下克隆相关库。
cd /home/ubuntu/pico/pico-sdkgit submodule update --init lib/mbedtlsgit 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 ~/picogit clone https://github.com/raspberrypi/picotool.git编译安装
cd picotoolmkdir buildcd buildcmake ..make -j8sudo make install去除 sudo 权限
cd ~/pico/picotoolsudo cp udev/99-picotool.rules /etc/udev/rules.d/树莓派 Pico 部分程序
例程下载
cd ~/picowget https://www.waveshare.net/w/upload/2/27/Pico_ePaper_Code.zipunzip Pico_ePaper_Code.zip -d Pico_ePaper_Codecd Pico_ePaper_Code编写程序
cd cmv main.c main.c.bakvi 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 directoryinclude_directories(./lib/e-Paper)编译程序
mkdir buildcd buildcmake ..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 updatesudo apt install python3-full编写程序
cd ~mkdir pythoncd pythonvi pico.py添加以下程序。
import psutilimport serialimport 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/bashsource /home/ubuntu/python/venv/bin/activatepython3 /home/ubuntu/python/pico.py添加执行权限。
chmod +x pico.sh添加系统服务。
cd /etc/systemd/systemsudo vi pico.service添加以下内容。
[Unit]Description=pico e-PaperAfter=network-online.targetWants=network-online.target
[Service]TimeoutStartSec=0ExecStart=/home/ubuntu/python/pico.shRestart=on-failureRestartSec=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-驱动墨水屏显示信息/