基于树莓派Pico的嵌入式系统学习板制作的水平仪
基于STEP Pico嵌入式系统学习,完成水平仪制作,基本能够保证水平仪的检测精度和速度,小球在显示屏上滚动,可以将开发板的姿态的可视化
标签
显示
OLED
水平仪
2023寒假在家练
如梦伊始
更新2023-03-29
北京理工大学
315

2023寒假在家练——水平仪制作实现

本项目为2023寒假在家练项目,选取了基于step micro的嵌入式系统学习平台水平仪的搭建的任务,学习使用了I2C (Inter-Integrated Circuit)协议的使用,了解了I2C作为一种通用的总线协议,如何快速的进行数据的交互,使各模块之间互联互通。通过连接姿态传感器mma7660,向控制显示模块OLED的驱动芯片ssd1306传输数据,实现相关的功能。

STEP Pico是一款由电子森林推出的嵌入式开发板,它基于树莓派Pico模块,内置RP2040微控制器,可以用MicroPython和C/C++语言编程。同时,它集成了OLED显示屏、温湿度传感器、光敏电阻、蜂鸣器、按键等多种外设,便于进行各种实验。因为初次接触到嵌入式开发,能够了解到的东西还是很多。

项目中调用了板卡中已编写完善的模块,如pin_cfg中的参数,framebuf等等,进行了功能的组合,完成并实现了在开发板上进行实时水平检测的能力。

流程图:

FtAFK4Of-U47OQQPFQRKiZ2fe_We

代码介绍:

初始化连接:

利用I2C协议连接mma7660,构造出姿态传感器模块:

i2c1 = I2C(1, scl=Pin(pin_cfg.i2c1_scl), sda=Pin(pin_cfg.i2c1_sda))
acc = MMA7660(i2c1)
acc.on(True)

连接控制显示模块OLED的驱动芯片ssd1306,构造出显示模块:

spi = SPI(1, 100000, mosi=Pin(pin_cfg.spi1_mosi), sck=Pin(pin_cfg.spi1_sck))
oled = SSD1306_SPI(128, 64, spi, Pin(pin_cfg.spi1_dc),Pin(pin_cfg.spi1_rstn), Pin(pin_cfg.spi1_cs))

 

构造图像缓存:

构造图像的缓存fb_1fb_2,fb_1用于显示小球,fb_2用于显示基准线和基准圆,在后续的显示更新上,fb_1会随倾角发生改变,fb_2不会改变。

在绘制fb_1时,缓存区域大小为10*10,因为采用framebuf.RGB565色彩模式,大小需要再乘2,在其中以(3,3)为顶点的位置上,绘制一个大小为5*5的图形。因为micro python版本较老的原因,遇到了没有framebuf.FrameBuffer.ellipse ()函数的问题,本来打算改用了矩形块代替,后来通过线填充的方式也可以得到圆,于是用了循环描出每一条竖线,填充成一个球形。

在绘制fb_2时,所占的大小为整个屏幕,128*64,也采用framebuf.RGB565色彩模式,大小乘2,在长边中心绘制长度为宽的一条线,在宽边中心绘制长度为长的一条线,接着绘制一个半径为20像素的圆,构造一段长20的序列range(20),其中的元素是圆在x轴上的坐标,利用勾股定理得到在y轴上的坐标为math.sqrt(20**2-i**2),这调用了math库函数求平方根,利用圆心的坐标分别加减x轴和y轴上的距离,在四个域中便绘出了圆形。

Fow7jyCA3iu4kYfTEy2fOfmMVJZZ

fb_1 = framebuf.FrameBuffer(bytearray(10*10*2), 10, 10, framebuf.RGB565)
for i in range(5):
    fb_1.vline(5-i, 5-int(math.sqrt(5**2-i**2)), 2*int(math.sqrt(5**2-i**2)), True)
    fb_1.vline(5+i, 5-int(math.sqrt(5**2-i**2)), 2*int(math.sqrt(5**2-i**2)), True)

fb_2 = framebuf.FrameBuffer(bytearray(128*64*2), 128, 64, framebuf.RGB565)
fb_2.hline(0, 32, 128, True)
fb_2.vline(64, 0, 64, True)

for i in range(20):
    fb_2.pixel(64+i, 32+int(math.sqrt(20**2-i**2)),True)
    fb_2.pixel(64-i, 32-int(math.sqrt(20**2-i**2)),True)
    fb_2.pixel(64+i, 32-int(math.sqrt(20**2-i**2)),True)
    fb_2.pixel(64-i, 32+int(math.sqrt(20**2-i**2)),True)

 

功能实现部分:

构造缓存空间用于读取和存储倾角信息,x_move和y_move用于移动平均,避免小球在显示屏上剧烈跳动导致的不易于观察。

d = bytearray(3)
r = [0 for x in range(3)]
x_move = 0
y_move = 0

 

主循环模块实现检验和显示的功能,首先从MMA7660中读取到倾角的信息到二进制数d中,对于d中的二进制数采用twos_compliment的函数模块进行转换,得到三个方向的倾角信息,存储到r之中,在进一步操作之前需要先清空屏幕上的显示内容,采用oled.fill(0),然后找出小球在屏幕上所处的位置信息,将其加载到显示器模块上。

这里只需要对x轴和y轴的夹角,即r[0]、r[1],通过移动平均,x_move和y_move保存着上一次移动的距离信息,与本次的移动信息进行加权和,使小球平稳地在显示屏上移动,采用oled.blit(fb_2, 0, 0)和 oled.blit(fb_1, 64-5-y_move*4, 32-5-x_move*2)分别绘出小球和基准图标,其中fg_2是缓存大小为全屏,fg_1缓存大小为10*10,因此安排fg_2的位置为(0,0)安排fg_1的位置为显示屏中心位置减fg_1大小的一半(64-5,32-5),使其能位于屏幕中心,为了适应屏幕大小,使小球的移动显示更合适,这里将长度方向上的移动距离乘4,将宽度方向上的移动距离乘2,经测试,显示合适且易于观察,最后更新显示屏,显示图像,在每次的显示之间间隔0.1秒。

while True:
    acc.getSample(d)
    for i in range(3):
        r[i] = twos_compliment(d[i], 6)
    # Clear the oled display in case it has junk on it.
    oled.fill(0)
    
    x_move = int(r[0] * 0.3 + x_move * 0.7)
    y_move = int(r[1] * 0.3 + y_move * 0.7)
    
    oled.blit(fb_2, 0, 0)
    oled.blit(fb_1, 64-5-y_move*4, 32-5-x_move*2)

    # Finally update the oled display so the image & text is displayed
    oled.show()
    
    sleep(0.1)

 

一些收获和展望:

通过这次的项目的学习和体会,首先是让接触到了嵌入式开发的基本原理和概念,不同组件之间的连接配合,如何有效完成一个功能。对于在开发板上的开发学习,学到了如何尽可能利用已经开发出来的库函数,通过学习micro python的语法结构以及相关的控制语句,阅读开发文档,解决问题如版本问题,参数设置问题等,对于集成开发环境的使用如何控制板卡都有了进一步的了解和体会。

对于开发文档的阅读是项目中比较困难的一块,需要找到需要的函数,并且要明白里面参数各种含义以及对照硬件应如何联系实现应有的功能,往往出来的结果并不能一次就很满意,需要反复理解和尝试,在此之上,对于python的语法,对象的构建使用也是能够理解这些内容的必要基础。

水平仪工作中始终保持开启状态,且需要人观察是否水平,未来可以引入相关的读数或是报警机制,同时开发板上的按钮灯光等模块没有用到该项目中,在之后可以添加更多的组件丰富其功能。对于项目中仍存在的一些问题,感觉水平仪的显示的能力还有待提高,认为小球的显示变化不够流畅,且不够自然,如何能提高速度更清晰地表示也是之后进一步完善的要求。

 

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