【微雪 RP2040双核开发板】04.仪表盘显示-评测完成
[复制链接]
【微雪 RP2040双核开发板】04.仪表盘显示
上一个帖子介绍了使用《微雪 RP2040双核开发板》设计一个电脑资源监视器,可以将电脑上CPU、内存等使用情况在开发板上以文字形式显示出来。这次设计了一个用仪表盘形式显示的电脑资源监视器。
1、设计思路
要想在屏幕上显示仪表盘,最主要的是先实现画弧线,然后画多根弧线填充宽度,实现进度条的效果。然后根据串口收到的数据,将进度条分成使用百分比和空闲百分比,分别用不同颜色表示。再在合适的位置显示一下文字说明。预期做成和官方示例图片差不多的效果。
图1、官方示例图片
2、进度条设计
既然想做成官方示例图片的效果,当然是先找官方是否提供相关代码。经过一通查找,没在网站找到。然后联系技术支持,结果技术支持回复我,这个示例果真只是在屏幕上显示了一个图片,根本没有对应代码。这样一来只能自己想办法实现了。
我先是找到了用Micro Python画圆的代码,移植过来直接就好用。然后是设计进度条。由于是有宽度的,得用点填充起来。最开始用弧线填充,发现使用的画弧函数填充的比较稀疏,不能填满。尝试增加画点密度,发现单片机内存不够。后面想到用实心小圆圈填充,实测单片机运算太慢,填充一圈得几十秒才能算完,也不能用。然后测试用矩形填充,虽然也慢一些,但是能接收这个速度,不过填完的形状不怎么好看。最后想到用直线填充,实际发现和用弧线填充效果差不多,但是速度更快。
最终决定用直线填充,由于单片机资源限制,只能做到稀疏的点密度,不能完全填满。另外也没有做抗锯齿处理,边缘不光滑。各种填充方式对比如下图。
图2、进度条填充对比
3、作品实现
进度条方案定下后,就是将其移植到上一个帖子的代码中。其中值得一提的是字符转数字在Micro Python程序中实现起来貌似比C语言简单,这个对于我这个初学者来说还是比较有意思的事,具体测试代码如下图。
图3、字符转数字
经过一通调试,最终把这个仪表盘显示的作品弄完了,显示效果如下图。
图4、显示效果
具体代码如下。由于刚开始学习,代码都是东拼西凑的,其中好多可能出现异常的地方也没有处理,这个只是刚好能凑合用,各位大神请见谅。
代码:
from machine import Pin,I2C,SPI,PWM,ADC,UART
import framebuf
import time
import math
I2C_SDA = 6
I2C_SDL = 7
DC = 8
CS = 9
SCK = 10
MOSI = 11
RST = 12
BL = 25
Vbat_Pin = 29
class LCD_1inch28(framebuf.FrameBuffer):
def __init__(self):
self.width = 240
self.height = 240
self.cs = Pin(CS,Pin.OUT)
self.rst = Pin(RST,Pin.OUT)
self.cs(1)
self.spi = SPI(1,100_000_000,polarity=0, phase=0,sck=Pin(SCK),mosi=Pin(MOSI),miso=None)
self.dc = Pin(DC,Pin.OUT)
self.dc(1)
self.buffer = bytearray(self.height * self.width * 2)
super().__init__(self.buffer, self.width, self.height, framebuf.RGB565)
self.init_display()
self.red = 0x07E0
self.green = 0x001f
self.blue = 0xf800
self.white = 0xffff
self.fill(self.white)
self.show()
self.pwm = PWM(Pin(BL))
self.pwm.freq(5000)
def write_cmd(self, cmd):
self.cs(1)
self.dc(0)
self.cs(0)
self.spi.write(bytearray([cmd]))
self.cs(1)
def write_data(self, buf):
self.cs(1)
self.dc(1)
self.cs(0)
self.spi.write(bytearray([buf]))
self.cs(1)
def set_bl_pwm(self,duty):
self.pwm.duty_u16(duty)#max 65535
def init_display(self):
"""Initialize dispaly"""
self.rst(1)
time.sleep(0.01)
self.rst(0)
time.sleep(0.01)
self.rst(1)
time.sleep(0.05)
self.write_cmd(0xEF)
self.write_cmd(0xEB)
self.write_data(0x14)
self.write_cmd(0xFE)
self.write_cmd(0xEF)
self.write_cmd(0xEB)
self.write_data(0x14)
self.write_cmd(0x84)
self.write_data(0x40)
self.write_cmd(0x85)
self.write_data(0xFF)
self.write_cmd(0x86)
self.write_data(0xFF)
self.write_cmd(0x87)
self.write_data(0xFF)
self.write_cmd(0x88)
self.write_data(0x0A)
self.write_cmd(0x89)
self.write_data(0x21)
self.write_cmd(0x8A)
self.write_data(0x00)
self.write_cmd(0x8B)
self.write_data(0x80)
self.write_cmd(0x8C)
self.write_data(0x01)
self.write_cmd(0x8D)
self.write_data(0x01)
self.write_cmd(0x8E)
self.write_data(0xFF)
self.write_cmd(0x8F)
self.write_data(0xFF)
self.write_cmd(0xB6)
self.write_data(0x00)
self.write_data(0x20)
self.write_cmd(0x36)
self.write_data(0x98)
self.write_cmd(0x3A)
self.write_data(0x05)
self.write_cmd(0x90)
self.write_data(0x08)
self.write_data(0x08)
self.write_data(0x08)
self.write_data(0x08)
self.write_cmd(0xBD)
self.write_data(0x06)
self.write_cmd(0xBC)
self.write_data(0x00)
self.write_cmd(0xFF)
self.write_data(0x60)
self.write_data(0x01)
self.write_data(0x04)
self.write_cmd(0xC3)
self.write_data(0x13)
self.write_cmd(0xC4)
self.write_data(0x13)
self.write_cmd(0xC9)
self.write_data(0x22)
self.write_cmd(0xBE)
self.write_data(0x11)
self.write_cmd(0xE1)
self.write_data(0x10)
self.write_data(0x0E)
self.write_cmd(0xDF)
self.write_data(0x21)
self.write_data(0x0c)
self.write_data(0x02)
self.write_cmd(0xF0)
self.write_data(0x45)
self.write_data(0x09)
self.write_data(0x08)
self.write_data(0x08)
self.write_data(0x26)
self.write_data(0x2A)
self.write_cmd(0xF1)
self.write_data(0x43)
self.write_data(0x70)
self.write_data(0x72)
self.write_data(0x36)
self.write_data(0x37)
self.write_data(0x6F)
self.write_cmd(0xF2)
self.write_data(0x45)
self.write_data(0x09)
self.write_data(0x08)
self.write_data(0x08)
self.write_data(0x26)
self.write_data(0x2A)
self.write_cmd(0xF3)
self.write_data(0x43)
self.write_data(0x70)
self.write_data(0x72)
self.write_data(0x36)
self.write_data(0x37)
self.write_data(0x6F)
self.write_cmd(0xED)
self.write_data(0x1B)
self.write_data(0x0B)
self.write_cmd(0xAE)
self.write_data(0x77)
self.write_cmd(0xCD)
self.write_data(0x63)
self.write_cmd(0x70)
self.write_data(0x07)
self.write_data(0x07)
self.write_data(0x04)
self.write_data(0x0E)
self.write_data(0x0F)
self.write_data(0x09)
self.write_data(0x07)
self.write_data(0x08)
self.write_data(0x03)
self.write_cmd(0xE8)
self.write_data(0x34)
self.write_cmd(0x62)
self.write_data(0x18)
self.write_data(0x0D)
self.write_data(0x71)
self.write_data(0xED)
self.write_data(0x70)
self.write_data(0x70)
self.write_data(0x18)
self.write_data(0x0F)
self.write_data(0x71)
self.write_data(0xEF)
self.write_data(0x70)
self.write_data(0x70)
self.write_cmd(0x63)
self.write_data(0x18)
self.write_data(0x11)
self.write_data(0x71)
self.write_data(0xF1)
self.write_data(0x70)
self.write_data(0x70)
self.write_data(0x18)
self.write_data(0x13)
self.write_data(0x71)
self.write_data(0xF3)
self.write_data(0x70)
self.write_data(0x70)
self.write_cmd(0x64)
self.write_data(0x28)
self.write_data(0x29)
self.write_data(0xF1)
self.write_data(0x01)
self.write_data(0xF1)
self.write_data(0x00)
self.write_data(0x07)
self.write_cmd(0x66)
self.write_data(0x3C)
self.write_data(0x00)
self.write_data(0xCD)
self.write_data(0x67)
self.write_data(0x45)
self.write_data(0x45)
self.write_data(0x10)
self.write_data(0x00)
self.write_data(0x00)
self.write_data(0x00)
self.write_cmd(0x67)
self.write_data(0x00)
self.write_data(0x3C)
self.write_data(0x00)
self.write_data(0x00)
self.write_data(0x00)
self.write_data(0x01)
self.write_data(0x54)
self.write_data(0x10)
self.write_data(0x32)
self.write_data(0x98)
self.write_cmd(0x74)
self.write_data(0x10)
self.write_data(0x85)
self.write_data(0x80)
self.write_data(0x00)
self.write_data(0x00)
self.write_data(0x4E)
self.write_data(0x00)
self.write_cmd(0x98)
self.write_data(0x3e)
self.write_data(0x07)
self.write_cmd(0x35)
self.write_cmd(0x21)
self.write_cmd(0x11)
time.sleep(0.12)
self.write_cmd(0x29)
time.sleep(0.02)
self.write_cmd(0x21)
self.write_cmd(0x11)
self.write_cmd(0x29)
def show(self):
self.write_cmd(0x2A)
self.write_data(0x00)
self.write_data(0x00)
self.write_data(0x00)
self.write_data(0xef)
self.write_cmd(0x2B)
self.write_data(0x00)
self.write_data(0x00)
self.write_data(0x00)
self.write_data(0xEF)
self.write_cmd(0x2C)
self.cs(1)
self.dc(1)
self.cs(0)
self.spi.write(self.buffer)
self.cs(1)
def qs_parse(qs):
parameters = {}
ampersandSplit = qs.split("&")
# print(ampersandSplit)
for element in ampersandSplit:
equalSplit = element.split("=")
# print(equalSplit)
if len(equalSplit) > 1:
parameters[equalSplit[0]] = equalSplit[1]
return parameters
def draw_line(x1,y1,x2,y2,c):
LCD.line(x1,y1,x2,y2,c)
def draw_arc_CPU(per):
'''
绘制圆弧
:x,y 圆心坐标
:r 半径
:start_angle,end_angle 角度范围
'''
x=120
y=120
r=120
start_angle=40
end_angle=320
color = LCD.red
per_c = math.radians((end_angle - start_angle)*per/100 +start_angle + 90)
# 0度的位置有点怪,顺时针转了90度。+90度作为补偿。
angleList = [math.radians(i + 90) for i in range(start_angle, end_angle+1)]
for i in angleList:
if i<per_c:
color = LCD.red
else:
color = LCD.blue
draw_line(x+round(math.cos(i)*(r-20)), y+round(math.sin(i)*(r-20)), x+round(math.cos(i)*r), y+round(math.sin(i)*r),color)
def draw_arc_MEM(per):
'''
绘制圆弧
:x,y 圆心坐标
:r 半径
:start_angle,end_angle 角度范围
'''
x=120
y=120
r=90
start_angle=40
end_angle=320
color = LCD.red
per_c = math.radians((end_angle - start_angle)*per/100 +start_angle + 90)
# 0度的位置有点怪,顺时针转了90度。+90度作为补偿。
angleList = [math.radians(i + 90) for i in range(start_angle, end_angle+1)]
for i in angleList:
if i<per_c:
color = LCD.green
else:
color = 0x0073
draw_line(x+round(math.cos(i)*(r-20)), y+round(math.sin(i)*(r-20)), x+round(math.cos(i)*r), y+round(math.sin(i)*r),color)
uart_para = {'TIME': ' 21:39:29 ', 'MEM': ' 49% ', 'CPU': ' 2%'}
if __name__=='__main__':
LCD = LCD_1inch28()
LCD.set_bl_pwm(65535)
uart = UART(0,baudrate=9600,tx=Pin(0),rx=Pin(1))
while(True):
if uart.any() != False:
buf=uart.read().decode('utf-8')
uart_para = qs_parse(buf)
print(uart_para)
LCD.fill(0)
cpu_num = uart_para['CPU'].split("%")[0]
mem_num = uart_para['MEM'].split("%")[0]
draw_arc_CPU(int(cpu_num,10))
draw_arc_MEM(int(mem_num,10))
LCD.text(uart_para['TIME'],80,100,LCD.green)
LCD.text("AI-MONITOR",80,125,LCD.red)
LCD.text("MEM:"+uart_para['MEM'],90,190,0x0073)
LCD.text("CPU:"+uart_para['CPU'],95,215,LCD.blue)
LCD.show()
time.sleep(0.2)
下面是演示视频,可以看到,在Thonny的shell窗口输出的是来自AIDA64的数据,在开发板显示屏上是同步更新的。
演示视频:
至此,我使用Micro Python完成了电脑资源监视器这个作品的开发。在作品帖子中,我展示了两种方式显示,分别是字符型显示和仪表盘+字符型显示。通过本次开发板评测,我开起了Micro Python的学习大门,在实际操作中,感受到Python编程的易用性。对于初学者非常友好。
特别感谢EEWORLD给了我这次参与《微雪 RP2040双核开发板》评测的机会。这块开发板可玩性很高,配合Micro Python可以做很多好玩的东西,非常值得购买。
|