基于STEP Pico实现电压表的制作
用开发板自带的可调电位计实现0-3.3V电压表的制作,并在OLED屏幕上将数值和对应的波形显示出来,并通过LED亮暗显示电压变化程度。
标签
嵌入式系统
数字逻辑
显示
2023寒假在家练
离屿之
更新2023-03-29
北京理工大学
381

一、项目介绍

项目要求:利用板上的电位计调节电压从0-3.3V之间变化,在OLED显示屏上显示电压值,可以以数字的方式,也可以以图形的方式来显示

拓展和优化:①以不少于两种输出方式显示电压值变化②OLED自带数值显示不美观且蹩脚,加入一种新的字体显示

实现方式:调节电位计产生0-3.3V之间变化的电压,树莓派Pico内部的ADC对该电压进行采集,得到0-65535之间的数值,经过计算后对应到相应的电压值,再通过OLED显示屏显示出来

二、硬件介绍

2.1 核心板:STEP Pico 是一款低成本,高性能的微控制器开发板,具有灵活数字接口,完全兼容Rasberry Pi Pico。硬件上,采用Rasberry Pi官方自主研发的RP2040微控制器芯片,搭载了ARM Cortex M0+双核处理器,高达133MHz的运行频率,内置264KB SRAM和2MB闪存,还板载有26个多功能GPIO引脚,支持SPI、I2C、PWM,。软件上,可选择树莓派提供的C/C++SDK,或者使用MicroPython进行开发,简单易上手。

2.2 扩展板:该项目用到的硬件有,一个可调电位计,一个OLED显示屏和12个WS2812b的led彩灯。电位计作为可调电压信号源,充当系统的输入,OLED和WS2812b作为显示器件充当该系统的输出。

三、设计思路

3.1 设计思路

项目的设计思路其实非常简单,首先用办卡自带的ADC模块进行一个数据采集和模数转换的操作,转换后的电压是靠16位二进制数表示的,之后将这16位二进制数通过一点的数学关系转换成对应的十进制数,将十进制数输出出来即可,可以是灯泡亮灭的形式,也可以是数值显示的形式,要将数值变换成波形,只需要调用一些oled module下的函数即可完成。波形以打点的方式显示,不直观且没有连贯性,考虑oled.line的向量显示方式。

3.2 项目流程图

FqdUym4teo5Rbk-AZfJMHXzLVDCZ

四、实现的功能

通过调节电位计实现电压变化,并将变压的变化输出出来。输出的方式有两种,第一种通过ws2812b的led灯的亮暗程度表示,电压越高,灯泡越亮,3.3V时灯泡达到最亮,0V时灯泡全灭;第二种通过OLED屏显示电压的数值,精度为小数点后一位,不用OLED自带字体,加入一种新的字体,并把数值转换成波形,实时显示在OLED屏幕上,电压越高,波形电平越高,电压越低,波形电平越低。以下是项目功能实现过程中的两张图片,分别显示初始0.0V和调节电位计过程中的一个中间值1.6V。

Fq9KEs4tVSBIGWJ2MJCubwtqw_z2FsEX813LNN48G90XuCGj9Esus09Z

4.1 代码实现:

4.1.1 module的调用

from board import pin_cfg
from time import sleep
import ws2812b
from machine import ADC, Pin
from oled import oled
import font6
import freesans20 #调用字体
from writer import Writer
import math

ADC 模块的调用,是将电压信号转换至数字信号的关键,然后writer是输出新字体的函数,math是python自带的函数,主要用在之后的数值转换中

4.1.2 初始化

wri = Writer(oled, freesans20)

#定义一个led输出值函数
def light_value(l):
    return "#{0:02x}{1:02x}{2:02x}".format(l, l, l)

这里主要是初始化一个led输出函数,方便之后直接用转换好的数值进行LED的亮暗控制。

4.1.3 数据采集和模数转换

#调用ADC获取电压值
pot = ADC(Pin(pin_cfg.pot))

调用ADC,函数返回值pot即为实时采集到的电位计的电压数值。

4.1.4 数制转换

while True:
    v_256 = math.floor(pot.read_u16() * 255 / 65535)
    v_64 = int(pot.read_u16() * 63.0 / 65535.0,)
    #求反逻辑,电压值保留一位小数
    v_3 = round(abs((pot.read_u16() * 3.3 / 65535.0)-3.3),1)

Led灯从0-255表示灯的亮暗程度,v_256作为函数“light_value”的输入控制led。OLED显示屏的范围是128*64,v_64规定波形显示范围。V_3表示显示的电压值,Round表示四舍五入取整,加绝对值是要实现反逻辑,为了和波形即灯的亮灭保持一致。

4.1.5 控制输出

   #反逻辑控制灯泡亮暗
    ws2812b.on_all(light_value((255 - v_256)))
   
    for i in range(127):
        hist[i] = hist[i + 1]
    hist[127] = v_64
    
    oled.fill(0)
    #显示波形
    for i in range(128):
        #oled.pixel(i, hist[i], 1)
        if i >= 1:
           oled.line(i - 1, hist[i - 1], i, hist[i], 1)
    #新字体显示电压数值
    wri.set_textpos(oled, 0, 0)
    wri.printstring(str(v_3)+"V")
    oled.show()
    sleep(0.1)

五、难题及解决办法

第一个问题是电压数值和波形显示不符,即电压显示3.3V,电平为低,且led灯全灭,所以要在数制转换的时候加入反逻辑,即对led输出函数来说,0代表全亮而255代表全灭,相应的0代表高电平,3.3V。而255代表低电平0.0V。

然后第二个问题,代码调试的时候电压显示为负值,加入abs函数使其为正。

第三个问题刚开始波形是以散点的方式显示,不能直观看出波形的变化趋势,加入oled.line函数,将散点转化为向量显示,使波形的显示更加平滑。

第四个问题OLED显示新数据会覆盖旧的而旧的数据不会消除,加入oled.fill(0)之后问题得到解决。

六、未来计划

该项目已经实现简易的电压表,但只能显示电位计变化范围内的电压,后续可以将核心板和面包板以及一些外接电路连接,实现更为复杂的电压测量,或者对该项目代码进行优化,可优化的地方有:

在进行数值计算时,会产生取整函数输出不稳定的情况,因为它不是完全的整型运算,取了对应的近似值,必然会数值的不稳定,导致led在0.0V的时候会出现闪烁。

板上的OLED屏幕分辨率较低,在拍照取证时闪烁不停,无法显示全部信号信息,可以使用分辨率更高的屏幕。

主控芯片rp2040的资源有限,可以更换采样率更高的芯片,从而实现更高的性能。

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