基于树莓派RP2040的嵌入式系统学习平台制作模拟电压表
使用Micropython开发基于树莓派RP2040的嵌入式学习平台,制作的双通道电压表。
标签
嵌入式系统
数字逻辑
显示
接口
2022寒假在家练
ezio
更新2022-03-04
成都理工大学
948

  1 项目需求

  • 利用240*240的显示屏制作一个双通道电压表,通过指针的摆动显示当前的电压。
  • 被测对象为四向摇杆的x、y轴电位计,这两个电位计分压从0-3.3V摆动,推动摇杆,表盘上的指针摆动,并在下面用数字的方式显示当前的电压值。
  • 完成表盘的设计以及校准,能够准确测量电压,可以切换到12Pin扩展排针上的两个模拟通道输入端,对这两个输入信号进行测量 - 手指触碰表针摆动
  • 通过提供的杜邦线连接其它数据端口,编程数据端口输出低频率的数字波形(会在0-3.3之间摆动),看指针的摆动
  • 指针摆动做出连续移动的效果,真实仿真模拟表盘的工作机制

2 完成的功能及达到的性能

2.1 电压图表显示

利用240*240的显示屏制作一个双通道电压表,通过指针的摆动显示当前的电压。

Fs7e9bZbvEnzwuTT_0aPYq3cQpxL

2.2四向摇杆的x、y轴电位计控制电压显示

FjZGTP5StVIrIVnsuIfcqVpA0H8fFgQXh7L6elQth3_xa0u20kogsV3F

3 实现思路

  • 模数转换器 (ADC)将模拟信号(直流输入电压)转换成数字信号;
  • LCD模拟指针式显示显示方式实现双路电压表测量和显示
  • 通过四向遥感改变两路电压;
  • AD转换器采集四向摇杆的两路电压
  • 根据电压的值来控制指针的指示方向

流程图如图:Fsc86NTfkITTzTmDhXzkrkZy8BWB

4 硬件介绍

采用树莓派Pico核心芯片RP2040:

1、双核Arm Cortex M0+内核,可以运行到133MHz

264KB内存

2、性能强大、高度灵活的可编程IO可用于高速数字接口

3、片内温度传感器、并支持外部4路模拟信号输入,内部ADC采样率高达500Ksps、12位精度

4、支持MicroPython、C、C++编程

板上功能:

1、240*240分辨率的彩色IPS LCD,SPI接口,控制器为ST7789

2、四向摇杆 + 2个轻触按键 + 一个三轴姿态传感器MMA7660用做输入控制

3、板上外扩2MB Flash,预刷MicroPython的UF2固件

4、一个红外接收管 + 一个红外发射管

5、一个三轴姿态传感器MMA7660

6、一个蜂鸣器

7、双排16Pin连接器,有SPI、I2C以及2路模拟信号输入

8、可以使用MicroPython、C、C++编程

9、USB Type C连接器用于供电、程序下载

5 主要代码及说明

1、定义常量、变量,包括图片文件地址、屏幕引脚、屏幕像素等:

image_file0 = "back.bin" 

st7789_res = 0
st7789_dc  = 1
disp_width = 240
disp_height = 240
CENTER_Y = int(disp_width/2)
CENTER_X = int(disp_height/2)

x=60
y=40
f_x=60
f_y=60
x1=60
y1=40
f_x1=60
f_y1=40
f_pointer=0
f_pointer1=0
PWM_OUT_Time=0

2、初始化外设,包括初始化SPI、LCD、ADC、GPIO、PWM:

Joy_x = machine.ADC(29)
Joy_y = machine.ADC(28)
Joy_z = machine.ADC(26)
Joy_h = machine.ADC(27)

spi_sck=machine.Pin(2)
spi_tx=machine.Pin(3)
spi0=machine.SPI(0,baudrate=80000000, phase=1, polarity=1, sck=spi_sck, mosi=spi_tx)
#
display = st7789.ST7789(spi0, disp_width, disp_width,
                          reset=machine.Pin(st7789_res, machine.Pin.OUT),
                          dc=machine.Pin(st7789_dc, machine.Pin.OUT),
                          xstart=0, ystart=0, rotation=0)

3、开机画面,先显示文字信息,然后显示硬禾LOGO:

display.fill(st7789.BLACK)
display.text(font2, "Hello! RPi Pico", 10, 10)
display.text(font2, "HGF", 10, 40)
display.text(font2, "MicroPython", 35, 100)
display.text(font2, "EETREE", 35, 150)
display.text(font2, "www.eetree.cn", 30, 200)
utime.sleep(1)

f_image = open(image_file1, 'rb')
for column in range(1,240):
                buf=f_image.read(480)
                display.blit_buffer(buf, 1, column, 240, 1)
utime.sleep(1)

4、电压表初始化显示,显示静态背景、读数显示

f_image = open(image_file0, 'rb')
for column in range(1,240):
                buf=f_image.read(480)
                display.blit_buffer(buf, 1, column, 240, 1)
freq=machine.freq()
print(freq)

5、电压表主要功能(while True内),测量并显示电压,读取摇杆两路电压:

while True: 
    PWM_OUT_Time = PWM_OUT_Time+1
    if PWM_OUT_Time<30:
        PWM_OUT.value(1) 
    else:
        PWM_OUT.value(0) 
        if PWM_OUT_Time == 60:
            PWM_OUT_Time=0
            
    if INPUT.value() == 1:         
        xValue = Joy_x.read_u16()     
        yValue = Joy_y.read_u16()
    else:
        xValue = Joy_z.read_u16()     
        yValue = Joy_h.read_u16()
    pointer = int(xValue * (330-0)/0xffff)/100
    display.text(font2, str(pointer), 170, 33)   
    pointer1 = int(yValue * (330-0)/0xffff)/100
    display.text(font2, str(pointer1), 170, 153) 
    if f_pointer<pointer-0.3:            
       f_pointer = f_pointer + 0.2
    else:
        if f_pointer>pointer+0.3:
            f_pointer = f_pointer - 0.1
        else:
            f_pointer = pointer
    if f_pointer1<pointer1-0.3:
       f_pointer1 = f_pointer1 + 0.2
    else:
        if f_pointer1>pointer1+0.3:
            f_pointer1 = f_pointer1 - 0.1
        else:
            f_pointer1 = pointer1
    angle1=round(30+(f_pointer*120/4))  
    if angle1<90:
        A1=angle1*3.1415926/180.0    
        divy=math.sin(A1)*40
        divx=math.cos(A1)*40
        x=int(95-divx)
        y=int(100-divy)
        if f_x!=x:
            display.line(f_x-1,f_y,95,100,st7789.WHITE)
        else:
            if f_y!=y:
                display.line(f_x-1,f_y,95,100,st7789.WHITE)
        f_x=x
        f_y=y
        display.line(x-1,y,95,100,st7789.BLACK)
    else:
        angle1=180-angle1
        A1=angle1*3.1415926/180.0 
        divy=math.sin(A1)*40
        divx=math.cos(A1)*40
        x=int(95+divx)
        y=int(100-divy)
        if f_x!=x:
            display.line(f_x-1,f_y,95,100,st7789.WHITE)
        else:
            if f_y!=y:
                display.line(f_x-1,f_y,95,100,st7789.WHITE) 
        f_x=x
        f_y=y
        display.line(x-1,y,95,100,st7789.BLACK)
    
    angle2=round(30+(f_pointer1*120/4)) 
    if angle2<90:
        A2=angle2*3.1415926/180.0  
        divy=math.sin(A2)*40
        divx=math.cos(A2)*40
        x1=int(95-divx)
        y1=int(220-divy)
        if f_x1!=x1:
            display.line(f_x1-1,f_y1,95,220,st7789.WHITE)
        else:
            if f_y1!=y1:
                display.line(f_x1-1,f_y1,95,220,st7789.WHITE)
        f_x1=x1
        f_y1=y1
        display.line(x1-1,y1,95,220,st7789.BLACK)
    else:
        angle2=180-angle2
        A2=angle2*3.1415926/180.0  
        divy=math.sin(A2)*40
        divx=math.cos(A2)*40
        x1=int(95+divx)
        y1=int(220-divy)
        if f_x1!=x1:
            display.line(f_x1-1,f_y1,95,220,st7789.WHITE)  
        else:
            if f_y1!=y1:
                display.line(f_x1-1,f_y1,95,220,st7789.WHITE)  
        f_x1=x1
        f_y1=y1
        display.line(x1-1,y1,95,220,st7789.BLACK) 

6遇到的主要难题和解决办法

对bin格式图片不了解,前期花费大量时间调试image2lcd软件,通过修改输出灰度以及扫描模式使得图片能在单片机上正常显示。通过不断调参使电压表指针刻度相对精确。

7.项目总结

通过这次寒假一起练活动,我对于RP2040开发板有了更加深入的了解,在项目开发的过程中,也充分锻炼了我的代码能力。同时一个完整的项目经历,让我对于项目开发的基本流程有了新的认识。

附件下载
源码.zip
团队介绍
团队成员
ezio
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号