1454|12

141

帖子

3

资源

一粒金砂(高级)

【微雪 RP2040双核开发板】04.仪表盘显示-评测完成 [复制链接]

 

【微雪 RP2040双核开发板】04.仪表盘显示

上一个帖子介绍了使用《微雪 RP2040双核开发板》设计一个电脑资源监视器,可以将电脑上CPU、内存等使用情况在开发板上以文字形式显示出来。这次设计了一个用仪表盘形式显示的电脑资源监视器。

 

1、设计思路

要想在屏幕上显示仪表盘,最主要的是先实现画弧线,然后画多根弧线填充宽度,实现进度条的效果。然后根据串口收到的数据,将进度条分成使用百分比和空闲百分比,分别用不同颜色表示。再在合适的位置显示一下文字说明。预期做成和官方示例图片差不多的效果。

image-20221207005519-1.png  

图1、官方示例图片

2、进度条设计

既然想做成官方示例图片的效果,当然是先找官方是否提供相关代码。经过一通查找,没在网站找到。然后联系技术支持,结果技术支持回复我,这个示例果真只是在屏幕上显示了一个图片,根本没有对应代码。这样一来只能自己想办法实现了。

我先是找到了用Micro Python画圆的代码,移植过来直接就好用。然后是设计进度条。由于是有宽度的,得用点填充起来。最开始用弧线填充,发现使用的画弧函数填充的比较稀疏,不能填满。尝试增加画点密度,发现单片机内存不够。后面想到用实心小圆圈填充,实测单片机运算太慢,填充一圈得几十秒才能算完,也不能用。然后测试用矩形填充,虽然也慢一些,但是能接收这个速度,不过填完的形状不怎么好看。最后想到用直线填充,实际发现和用弧线填充效果差不多,但是速度更快。

最终决定用直线填充,由于单片机资源限制,只能做到稀疏的点密度,不能完全填满。另外也没有做抗锯齿处理,边缘不光滑。各种填充方式对比如下图。

image-20221207005519-2.jpeg  

图2、进度条填充对比

3、作品实现

进度条方案定下后,就是将其移植到上一个帖子的代码中。其中值得一提的是字符转数字在Micro Python程序中实现起来貌似比C语言简单,这个对于我这个初学者来说还是比较有意思的事,具体测试代码如下图。

image-20221207005519-3.png  

图3、字符转数字

经过一通调试,最终把这个仪表盘显示的作品弄完了,显示效果如下图。

image-20221207005519-4.jpeg  

图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可以做很多好玩的东西,非常值得购买。

此帖出自移动便携论坛

回复

2873

帖子

3

资源

版主

这表盘看起来没有DEMO好看呀。
此帖出自移动便携论坛

点评

画点算法效率低,画密了单片机跑不动,只能这样了  详情 回复 发表于 2022-12-7 09:53

回复

2578

帖子

0

资源

版主

进度条中间有黑线,这是为啥?控件问题?

此帖出自移动便携论坛

点评

画点算法效率低,画密了单片机跑不动,只能这样了  详情 回复 发表于 2022-12-7 09:53

回复

4561

帖子

236

资源

管理员

又发现一枚学python的坛友、

要是遇到问题,可以来论坛求助,论坛micropython有资深的dcexpert

此帖出自移动便携论坛

扫一扫,关注 EEWORLD 微信订阅号

行业资讯、电子趣闻、技术干货、精彩活动……尽可掌握~

点评

谢谢,我去请教一下  详情 回复 发表于 2022-12-7 09:54

回复

141

帖子

3

资源

一粒金砂(高级)

lugl4313820 发表于 2022-12-7 07:41 这表盘看起来没有DEMO好看呀。

画点算法效率低,画密了单片机跑不动,只能这样了

此帖出自移动便携论坛

回复

141

帖子

3

资源

一粒金砂(高级)

wangerxian 发表于 2022-12-7 09:21 进度条中间有黑线,这是为啥?控件问题?

画点算法效率低,画密了单片机跑不动,只能这样了

此帖出自移动便携论坛

点评

话说不是画这么老多线吧 写的是否不合适呀?  详情 回复 发表于 2022-12-8 06:35
所以写底层还是C比较好~Micro Python写一些应用还是非常香的!  详情 回复 发表于 2022-12-7 14:13

回复

141

帖子

3

资源

一粒金砂(高级)

nmg 发表于 2022-12-7 09:49 又发现一枚学python的坛友、 要是遇到问题,可以来论坛求助,论坛micropython有资深的dcexpert

谢谢,我去请教一下

此帖出自移动便携论坛

回复

2578

帖子

0

资源

版主

sipower 发表于 2022-12-7 09:53 画点算法效率低,画密了单片机跑不动,只能这样了

所以写底层还是C比较好~Micro Python写一些应用还是非常香的!

此帖出自移动便携论坛

回复

61

帖子

10

资源

一粒金砂(中级)

嗯,不错,可以参考,顺便灌灌水哈,不然积分哪儿来呢?

此帖出自移动便携论坛

回复

1389

帖子

15

资源

版主

wangerxian 发表于 2022-12-7 09:21 进度条中间有黑线,这是为啥?控件问题?
画点算法效率低,画密了单片机跑不动,只能这样了

话说不是画这么老多线吧 写的是否不合适呀?

此帖出自移动便携论坛

点评

我也没想到更好的两个弧线之间填充点的方式  详情 回复 发表于 2022-12-8 17:30

回复

1605

帖子

1

资源

版主

我感觉这样效果更好,这样更有意境,只要是规律性的就会有一种美

此帖出自移动便携论坛

回复

141

帖子

3

资源

一粒金砂(高级)

吾妻思萌 发表于 2022-12-8 06:35 话说不是画这么老多线吧 写的是否不合适呀?

我也没想到更好的两个弧线之间填充点的方式

此帖出自移动便携论坛

回复

141

帖子

3

资源

一粒金砂(高级)

秦天qintian0303 发表于 2022-12-8 09:06 我感觉这样效果更好,这样更有意境,只要是规律性的就会有一种美

此帖出自移动便携论坛

回复
您需要登录后才可以回帖 登录 | 注册

相关帖子
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/5 下一条

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2022 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表