1.项目介绍
简介:本项目基于STEP Pico,利用开发板的姿态传感器,在OLED屏上通过方形的移动来显示板子的倾斜度。
硬件介绍:
1)核心板STEP Pico
STEP Pico是一款低成本,高性能的微控制器开发板,具有灵活数字接口(完全兼容Raspberry Pi Pico)
硬件上,采用Raspberry Pi官方自主研发的RP2040微控制器芯片,搭载了ARM Cortex M0+双核处理器,高达133MHz的运行频率,内置了264KB SRAM和2MB闪存你,还板载有多达26个多功能的GPIO引脚。
软件上看,可选择树莓派提供的C/C++SDK,或者使用MicroPython进行开发,且配套有完善的开发资料教程,可方便快速入门开发并嵌入到产品中。
图1 核心板STEP Pico 图2 扩展板
2)扩展板:基于STEP PICO的嵌入式系统学习平台
扩展板含有:2个按键输入;4个单色LED;12个WS2812B RGB三色灯;1个姿态传感器;1个128*64 OLED显示屏;1个蜂鸣器;1个可调电位计(用于电压表);1路音频信号输入(用于示波器);8位R-2R电阻网络构成的DAC(用于DDS信号发生器)
本次制作水平仪需要使用到的是其中的12个WS2812B RGB三色灯,姿态传感器MMA7660FC以及128*64 OLED显示屏。
3)MMA7660FC姿态传感器:
MMA7660FC是具有数字输出的I2C、低功耗、紧凑型电容式微机械加速度传感器,提供低通滤波器、零重力加速度偏移和增益误差补偿,并可以转化为6位数字值,用户可配置输出数据的传输速率。该器件可通过中断引脚(INT)识别传感器的数据变化、产品的朝向和姿态等。MMA7660FC采用非常小的3 mm x 3 mm x 0.9 mm DFN封装。
4)WS2812B RGB三色灯
WS2812B是一种智能控制LED光源,其控制电路和RGB芯片集成在一个5050个组件的包装。 内部包括智能数字端口数据锁存和信号重塑放大驱动电路。 还包括一个精密内部振荡器和一个12V电压可编程恒流控制部分,有效地确保了像素点的光色高度一致。
2 实现的功能
项目的整体功能是将姿态传感器数据可视化,使用户可以姿态传感器反馈的数据手动地控制开发板的水平姿态。将从以下三个角度实现数据的可视化:
1)打印姿态数据:将姿态数据输出成三个取值范围在(-23~23)可视化数值,并在Thonny中打印出来
2)OLED显示屏显示方形:生成一个可随开发板姿态移动的正方形,用于显示开发板的姿态
3)12个WS2812B RGB三色灯通过亮灭来显示开发板目前倾斜的方向
3 框图和软件流程图
图3 框图
4 设计思路
1)打印姿态数据:通过i2c通信读取姿态传感器的数据,通过编写twos_compliment函数,将姿态数据输出成三个取值范围在(-23~23)可视化数值,并在Thonny中打印出来
2)OLED显示屏显示方形:根据OLED的屏幕大小数值128×64以及转换后的姿态数据取值范围(-23~23),设计rect函数用于绘制OLED屏幕中的正方形,将姿态数据转换成坐标,使其在屏幕中显示出来。
图4 OLED屏幕坐标轴
3)12个WS2812B RGB三色灯通过亮灭来显示开发板目前倾斜的方向:
分别设计distance和deng函数。distance函数用于计算正方形坐标到OLED屏幕中心点的距离。deng函数用于计算正方形坐标到OLED中心点的连线与屏幕x轴的夹角,并通过夹角反馈理应亮灯的灯号
因为需要让开发板发生一定倾斜时,三色灯才会亮,所以可以理解成正方形需要偏离中心点一定距离才会亮灯,故设置distance值,使distance值≥15时,才进行亮灯的判断。
亮灯的判断逻辑基于正方形的坐标位于中心点的位置,本作者通过坐标值首先判断正方形在中心点(64,32)的左边或者右边,再计算角度的正切值,通过下图一一对应,从而返回一个灯号,用于主函数中的点亮操作。
图5 亮灯原理图
例:图中正方形由于开发板的倾斜,位于中心点左下方位置,首先偏离位置大于阈值,将会亮灯;然后,坐标位于中心点左边,并且tanΘ在(-1~-0.414)区间内,所以可以判断出Θ在(-165°,-135°)区间内,返回灯号为8,主函数中使8号灯亮。
5 功能展示
项目功能如下图展示
以图6为例,OLED屏幕中正方形由于开发板的倾斜,位于中心点左上方,当正方形偏离中心的距离达到一定程度,会使2号灯亮。同理,图7、8、9分别展示了4号灯,8号灯,10号灯的发亮情况
图6 2号灯亮展示 图7 4号灯亮展示
图8 8号灯亮展示 图9 10号灯亮展示
6 主要代码片段
6.1 获取姿态传感器的姿态信息
def twos_compliment(n, nbits):
sign_bit = 1 << nbits - 1
sign = 1 if n & sign_bit == 0 else -1
val = n & ~sign_bit if sign > 0 else sign * ((sign_bit << 1) - n)
return val
6.2 rect函数通过姿态传感器生成的(-23~23)的数值用于生成OLED屏幕中正方形的坐标,并对正方形进行绘制
def rect(x,y):
rectx=59-int(64/23*x)
recty=27-int(32/23*y)
oled.fill(0)
oled.fill_rect(rectx, recty, 10, 10, 1)
oled.show()
6.3 distance函数用于计算正方形坐标到OLED屏幕中心的距离
def distance(x,y):
rectx=64-int(64/23*x)
recty=32-int(32/23*y)
s = math.sqrt((rectx-64)*(rectx-64)+(recty-32)*(recty-32))
return s
6.4 deng函数计算正方形偏离OLED屏幕中心的角度的同时,计算应该亮哪个灯
def deng(x,y,d):
rectx=64-int(64/23*x)+0.1
recty=32-int(32/23*y)
jiao=(recty-32)/(rectx-64)
if d >=15:
if rectx >= 64:
if jiao < -2.414:
return 12
elif jiao < -1:
return 1
elif jiao < -0.414:
return 2
elif jiao < 0.414:
return 3
elif jiao < 1:
return 4
elif jiao < 2.414:
return 5
else:
return 6
else:
if jiao < -2.414:
return 6
elif jiao < -1:
return 7
elif jiao < -0.414:
return 8
elif jiao < 0.414:
return 9
elif jiao < 1:
return 10
elif jiao < 2.414:
return 11
else:
return 12
else:
return 0
6.5 屏幕不断地刷新,若没有偏离,则让所有的灯灭掉
if ws != 0:
ws2812b.off_all()
ws2812b.on(ws)
else:
ws2812b.off_all()
7 遇到的难题以及解决办法
难点1:对于正方形在OLED屏幕中的显示位置的规划
解决方法:创建rect参数,将姿态传感器返回的数值与OLED屏幕中的坐标对应起来,两个(-23,23)区间的数值结合128×64的屏幕大小进行正方形坐标在OLED屏中的映射。
难点2:12个WS2812B RGB三色灯的亮灭控制
解决方法:创建distance函数以及deng函数,计算正方形坐标与OLED屏幕的位置关系,根据夹角的tan值返回对应的灯号,在主函数进行点亮。
8 未来的计划或建议
这个寒假接触了micropython,可以一边连着设备一边实时进行调试,非常方便好用。未来希望能够在硬禾平台接触更多有趣的项目。