内容介绍
项目备注
内容介绍
基于RP2040开发板的水平仪
功能设计
1. 屏幕显示以中心为原点的十字坐标, 红色方块显示当前姿态
2. 以数值显示当前X/Y/Z方向坐标
3. 按B键锁定当前姿态, 屏幕显示空心蓝色方块, 之后移动显示实时姿态, 再次按B键清除锁定姿态数据
涉及硬件及所需基本功能
1. 屏幕 ST7789
- 绘制基本图形(圆, 矩形, 空心/实心)
- 绘制文字
2. IMU MMA7660
- 读取三轴X/Y/Z数据
- 6Bit精度, 3个刻度的误差, 需经均值滤波(8val或32阶)
3. 按键
- 获取按键按下状态
- 软件消抖
程序逻辑大概是这样的

一些必要的改进
1. 电子森林提供了一个mpy版的st7789驱动, 相比C版本驱动绘制速度稍慢, 故这里直接使用了包含了预编译C版本的ST7789驱动的uf2文件
2. MMA7660精度较低,只能用作学习演示用途,除了每个维度只有6bit外,就算静置不动,仍有3个刻度的跳动,所以用了均值滤波库,它是汇编实现的,效率很高(单次求均值操作2us),虽然过长的平均窗口会导致位置更新较慢,但总体效果可以接受
3. 全屏填充纯色后再绘制页面元素,会导致屏幕闪动,而且也没有必要,所以采用了记录上次位置,然后绘制相同大小的背景色图形,然后绘制新的图形
4. 经实验,MMA7660的输出值与角度非线性,故采用了分段系数计算角度
主函数说明
while True:
# 获取当前姿态信息, 由于芯片安装方向与实际观察方向不一致, 坐标在这里调整
curr_y, curr_x, _ = imu.getXYZ()
curr_x += 1 # 偏移一点
curr_y += 0
# 均值滤波
curr_x = avg(arr_x, curr_x, 4)
curr_y = avg(arr_y, curr_y, 4)
# 获取当前按键状态, 获取B键状态, 0=按下, 1=未按下
btn_stat = get_key()
button_b = btn_stat['B']
if button_b == 0 and ticks_diff(ticks_ms(), t) > 300:
if stor_flag == False: # 若之前未存储
stor_x, stor_y = curr_x, curr_y
else: # 之前已存储, 这里覆盖消除
draw_box(lcd, 120 - 2 * stor_x, 120 + 2 * stor_y, 60, st7789.BLACK, thick=1)
# 翻转存储状态, 记录按下时间, 用于消抖
stor_flag = not stor_flag
t = ticks_ms()
# 若比较不同则进行重绘, 绘制顺序: 底图, 存储方块, 活动方块, 数值区, 指示条
if last_x != curr_x or last_y != last_y:
draw_bg(lcd)
draw_legend(lcd)
draw_number(lcd, calc_degree(curr_x), calc_degree(curr_y), calc_degree(stor_x), calc_degree(stor_y), stor_flag)
draw_box(lcd, 120 - 2 * last_x, 120 + 2 * last_y, 60, st7789.BLACK)
draw_box(lcd, 120 - 2 * curr_x, 120 + 2 * curr_y, 60, st7789.RED, thick=1)
if stor_flag:
draw_box(lcd, 120 - 2 * stor_x, 120 + 2 * stor_y, 60, st7789.BLUE, thick=1)
# 记录本次姿态数据, 下次若不变则不再重绘
last_x, last_y = curr_x, curr_y
time.sleep(0.02)
完整代码见附件,或从gitee下载:eetree-homework-2022: 寒假在家练,硬禾学堂2022活动作业,基于RP2040开发板的水平仪 (gitee.com)
附件下载
eetree_homework_2022.rar
团队介绍
已毕业,业余爱好喜欢各种开发板及编程,业务无线电爱好者BI3QXJ,开源项目拥趸,三流Py程序员。
团队成员
大老韩
评论
0 / 100
查看更多