基于树莓派Pico的嵌入式系统学习平台制作一个电压表
利用板上的电位计调节电压从0-3.3V之间变化,在OLED显示屏上显示电压值,以数字或者图形的方式来显示,并且调节电压大小的同时RGB三色灯的亮度发生变化
标签
嵌入式系统
显示
2023寒假在家练
Young-diong
更新2023-03-29
深圳大学
735

1.项目介绍

学习板上有一可调电位计,可通过旋转电位计的大小来获得0-3.3V之间变化的电压,再通过树莓派Pico内部的ADC对该电压进行采集,得到一定范围的数值,经过计算以后对应到相应的电压值,再通过OLED显示屏以数字或者波形的方式显示出来,并且在调节电位器获得不同电压值的同时,12个RGB三色灯的亮度会随着电压值的改变而发生改变,并且通过按下两个按键,可以分别实现控制电压值在OLED屏幕上的显示方式和RGB三色灯的开关。

2.设计思路

  • 首先要读取电位计上的电压,需要使用ADC函数,通过阅读micropyhton的函数介绍,了解到ADC函数的使用方法,可知,接下来需要寻找电位计所对应的接口idFv6e3hKVQvIvSmcHRxevQ3S79Je9
  • 通过相关的手册查询,了解到了电位计内部的电路图如下,其对应的接口为GPIO_ADC2 

           FqzUoIApFQ2WkssrabLWILWNFhfx

  • 在OLED屏上使用波形输出电压值,需要在OLED屏上画短线,通过阅读micropython的文档,阅读到micropython内置的使用SSD1306 OLED输出的函数如下FqrCVCwGGyftBaUjpD8VrCM5MjUb
  • 按键和ws2812b灯的点亮则是通过使用库中的函数所实现,其函数的使用通过视频的课程学习即可

3.实现思路

  • ADC对电位器上的电压值进行采样
  • 将采样得到的ADC量化值输出到到屏幕上,可为数字显示,也可以采用画短线的方法实现波形显示
  • 同时将将采样得到的ADC量化值转化为ws2812b灯的亮度值,需要注意数值格式的切换
  • 按下两个按键,可分别实现数字输出和波形输出的转换和ws2812b灯的亮灭

4.实现过程

4.1流程框图

FuGEyWvh-fka2N-i44KrI9xt4gsI

4.2代码实现过程

  1. 开机动画的设置,实现的方法是设置不同的OLED屏幕输出内容,然后清屏,输出,再暂停一会,实现动画的逐帧输出
    def opening_animation():     #opening animation
        oled.fill(1)
        oled.show()
        sleep(1)
            
        oled.fill(0)
        oled.show()
        sleep(1)
            
        oled.rect(0, 0, 128, 64, 1)
        oled.show()
        sleep(1)
            
        oled.rect(32, 16, 64, 32, 1)
        oled.show()
        sleep(1)
  2. 转化电压值为ws2812b的亮度值格式
    def light_value(l):         #leturn the value of leds
        return "#{0:02x}{1:02x}{2:02x}".format(l, l, l)
  3. 开机动画的运行。先是在主循环外设置了一个start的变量,再在循环内判断是否是第一次执行
        if(start==0):          #run opening animation
            opening_animation()
            start=1
        oled.fill(0)
  4. 利用ADC对电位器上的电压值进行采样,并将采样得到的值转化为范围从0~3.3V的电压值和适合WS2812b灯带的亮度变化范围。并且将电压值转化为一个数组,该数组的大小为128,符合OLED屏幕的尺寸范围。特别需要注意的是,要注意电压值要符合实际,因此多了一些判断获取到的电压值是不是符合范围的代码
        x=machine.ADC(2)             
        y = (x.read_u16()-256)*0.00005     #the voltage value is obtained and converted to a 3.3V amplitude
        v=x.read_u16()* 255.0 / 65535.0    #the brightness value is obtained and converted to the range of 255
        for i in range(127):
            wave[i] = wave[i + 1]
        wave[127] = int(x.read_u16() * 63.0 / 65535.0)   #set waveform output
        if y<0:
            y=0.0
        elif y>3.3:
            y=3.3
  5.  控制WS2812b灯带的亮灭,先是在主循环外设置了一个ktwo的变量,然后在循环内可通过判断其值,从而来判断灯带的亮灭。按下K2可以改变ktow的值,从而来控制。并且按下K2按键后,OLED屏幕上会提示灯带的状态变化情况
        if(k2.value()==1):                #control leds
            if(ktwo==True):
                oled.fill(0)
                wri.set_textpos(oled, 0, 0)
                wri.printstring("The leds will be closed")
                oled.show()
                sleep(1)
            if(ktwo==False):
                oled.fill(0)
                wri.set_textpos(oled, 0, 0)
                wri.printstring("The leds will be opened")
                oled.show()
                sleep(1)
            ktwo=1-ktwo    
        if(ktwo==True):
            ws2812b.on_all(light_value(int(v)))
        if(ktwo==False):
            ws2812b.off_all()
  6. 选择电压值的在OLED屏幕上的输出方式,先是在主循环外设置了一个kone的变量,然后在循环内可通过判断其值,从而来选择输出方式。按下K1可以改变kone的值,从而来控制。并且按下K1按键后,OLED屏幕上会提示输出方式的变化情况
        if (k1.value()==1):             #switch the mode
            if(kone==True):
                oled.fill(0)
                wri.set_textpos(oled, 0, 0)
                wri.printstring("Switch to waveform display")
                oled.show()
                sleep(1)
            if(kone==False):
                oled.fill(0)
                wri.set_textpos(oled, 0, 0)
                wri.printstring("Switch to digital display")
                oled.show()
                sleep(1)
            kone=1-kone
        oled.fill(0)
  7. 电压值的输出,输出方式与规定的变量kone的值有关
        if(kone==False):
            for i in range(128):
                if i >= 1:
                    oled.line(i - 1, 63-wave[i - 1], i, 63-wave[i], 1)     #waveform output
            oled.show()
        if(kone==True):
            wri.set_textpos(oled, 25, 48)
            wri.printstring(str('%.1f'%y)+"V")        #digital output       
        oled.show()

     

 

5.功能实现展示

Fur9FSXHbr6GkswNFbet8JNnloWG

实现了电压值的波形输出和数值输出,并且WS2812b灯带的亮灭

6.使用到的库函数

 

from button import k1,k2
from machine import ADC, Pin
from time import sleep
import ws2812b
import freesans20
from writer import Writer
from oled import oled

使用到了button.py、machine.py、time.py、ws2812b.py、writer.py和oled.py函数,其中需要特别说明writer.py函数,该函数是实现了OLED屏幕上的字符输出,相对于OLED函数,该函数的优点是可以实现自动换行,并且字体较大。

7.遇到的主要问题和解决办法

  • 在将ADC采样得到的值转化为范围从0~3.3V的电压值时,发现ADC采样得到的数值范围并不是从0开始的,因而会出现没有办法得到符合要求的范围。解决办法为用print函数输出ADC采样得到的数据范围,确认数据的范围后,再进行数值转换公式的优化
  • 在设置WS2812b灯带的亮度范围时,不清楚亮度的范围如何,并且发现,亮度值超过一定值时会变成非白光,因此将ADC采样得到的值转化为WS2812b灯带的亮度值时,需要特别注意这一点。解决办法为写一循环,通过隔0.5s不断增大亮度值,来确定亮度范围

8.项目总结与未来的期待

总体来说,该项目的完成并不复杂,比较适合初学者,我在项目的要求上多加了一些创意,实现了功能的丰富性。完成该项目只需要查阅相关的数据手册,能够准确地找到所需的资料,便可以简单地完成该项目。在运行该项目时,发现运行的速度较慢,原因可能如下:1.代码中使用太多判断,判断会使得运行速度降低。2.使用micropyhton的原因,相对与C语言而言,micropython在运行上的速度确实会相对较慢。因此在未来,我会更加精简我的代码,少一些判断语句。

 

附件下载
Code.zip
可编译代码
团队介绍
深圳大学电子与科学技术学生
团队成员
陈中阳
电子科学与技术在校本科生
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号