实验08:摇一摇与倾斜检测
这个实验做完你会得到什么
倾斜 micro:bit,手机上的小球跟着滚;用力摇一摇,手机弹出提示并换个颜色。
这是 micro:bit 系列的收尾篇,把前面学的订阅、阈值判断、平滑滤波用在一起。
| 项目 | 说明 |
|---|---|
| 难度 | ★★★☆☆ |
| 用时 | 约 40 分钟 |
| 前置 | 实验03:温度看板(订阅套路一样) |
一、器材清单
| 器材 | 数量 | 说明 |
|---|---|---|
| BBC micro:bit | 1 | 用板载加速度计,无需外接 |
固件:MakeCode 里加 Bluetooth 扩展 + 蓝牙加速度计服务,打开 No Pairing Required。
坐标系:正面朝上平放时,X 轴指向右(B 键方向),Y 轴指向上(USB 口反方向), Z 轴垂直板面向下。单位是毫重力加速度(mg):平放时 Z 约 -1000,X/Y 接近 0。
二、界面组件
在实验01 的连接界面基础上加:
| 组件 | 命名 | 关键属性 |
|---|---|---|
| 画布 | 画布1 |
宽度充满、高度 300、背景浅灰 |
| 图像精灵 | 图像精灵_小球 |
30×30 |
| 标签 | 标签_三轴 |
文本「X – Y – Z –」 |
| 标签 | 标签_姿态 |
字号 24,文本「平放」 |
| Microbit_Accelerometer | Microbit_Accelerometer1 |
不可见,BluetoothDevice = BluetoothLE1 |
三、分步搭代码块
第 1 步:连上就订阅,并把采样调快
when BluetoothLE1.Connected() {
Microbit_Accelerometer1.WriteAccelerometerPeriod(160)
Microbit_Accelerometer1.RequestAccelerometerDataUpdates()
标签_状态.Text = "已连接,倾斜试试"
}
中途验证:状态标签更新。
加速度计的周期只能取固定几档(1、2、5、10、20、80、160、640 毫秒), 填别的值会被就近取整。体感控制用 160 毫秒(约 6 次/秒)足够跟手, 调到 20 毫秒虽然更顺滑,但 BLE 通道会很挤、也更费电。
第 2 步:三轴数据驱动小球
global 平滑X = 0
global 平滑Y = 0
when Microbit_Accelerometer1.AccelerometerDataReceived(Accelerometer_X, Accelerometer_Y, Accelerometer_Z) {
global 平滑X = 平滑X * 0.6 + Accelerometer_X * 0.4
global 平滑Y = 平滑Y * 0.6 + Accelerometer_Y * 0.4
标签_三轴.Text = join("X ", round(Accelerometer_X), " Y ", round(Accelerometer_Y), " Z ", round(Accelerometer_Z))
var 新X = 画布1.Width / 2 + 平滑X / 1000 * (画布1.Width / 2)
var 新Y = 画布1.Height / 2 - 平滑Y / 1000 * (画布1.Height / 2)
图像精灵_小球.MoveTo(max(0, min(画布1.Width - 30, 新X)), max(0, min(画布1.Height - 30, 新Y)))
}
中途验证:micro:bit 平放时小球在画布中间;向右倾斜小球往右滚,向前倾往上走。
除以 1000 是量程换算:完全侧立时那一轴约 ±1000 mg,除完正好是 -1~1, 再乘半个画布宽就映射到了整个画布。
Y 轴前面是减号:micro:bit 的 Y 正方向朝上,而屏幕坐标 Y 正方向朝下,不取反会上下颠倒。
平滑系数 0.4 比实验06 的 0.3 大一些 —— 体感控制宁可略抖也不能迟钝。
第 3 步:判断姿态
global 平滑X = 0
global 平滑Y = 0
when Microbit_Accelerometer1.AccelerometerDataReceived(Accelerometer_X, Accelerometer_Y, Accelerometer_Z) {
if Accelerometer_X > 400 {
标签_姿态.Text = "右倾"
} else if Accelerometer_X < -400 {
标签_姿态.Text = "左倾"
} else if Accelerometer_Y > 400 {
标签_姿态.Text = "前倾"
} else if Accelerometer_Y < -400 {
标签_姿态.Text = "后仰"
} else if Accelerometer_Z > 700 {
标签_姿态.Text = "翻面朝下"
} else {
标签_姿态.Text = "平放"
}
}
中途验证:把 micro:bit 朝各个方向倾斜,姿态文字跟着变;翻过来显示「翻面朝下」。
阈值 400 mg 约等于倾斜 24°。调小了平放时会来回跳字,调大了要摆得很夸张才认。 判断顺序有讲究:先判 X 再判 Y,斜着放时以幅度大的那个为准。
第 4 步:摇一摇检测
global 上次强度 = 0
when Microbit_Accelerometer1.AccelerometerDataReceived(Accelerometer_X, Accelerometer_Y, Accelerometer_Z) {
var 强度 = abs(Accelerometer_X) + abs(Accelerometer_Y) + abs(Accelerometer_Z)
if 强度 - 上次强度 > 1200 {
标签_姿态.Text = "检测到摇晃!"
画布1.BackgroundColor = "&HFFFFC107"
对话框1.ShowAlert("摇一摇成功")
}
global 上次强度 = 强度
}
中途验证:用力晃一下 micro:bit,画布变黄并弹出提示;轻轻挪动不会误触发。
为什么比较的是”变化量”而不是绝对值:静止平放时三轴绝对值之和本来就有约 1000 (重力)。只有突然的变化才是摇晃,所以要跟上一次比。
阈值 1200 偏保守,误触发少但要用点力。想灵敏就降到 800。
四、排错表
| 现象 | 原因与处理 |
|---|---|
| 收不到数据 | ① 没调 RequestAccelerometerDataUpdates;② 固件没加「蓝牙加速度计服务」;③ BluetoothDevice 没设 |
| 小球上下方向反了 | Y 轴没取反。屏幕 Y 向下、micro:bit Y 向上,公式里要用减号 |
| 小球乱抖 | 加大平滑力度(把 0.4 降到 0.2);或把采样周期从 160 调到 640 |
| 小球反应迟钝 | 反过来,减小平滑力度、缩短采样周期 |
| 姿态文字疯狂跳动 | 阈值太小。400 mg 起步,抖得厉害就提到 600 |
| 摇一摇一直误触发 | 用了绝对值而不是变化量;或阈值太低,从 1200 往上调 |
| 数值范围和文档对不上 | 单位是 mg(毫重力加速度),1000 = 1g。不是 m/s² |
五、系列回顾
到这里 micro:bit 系列走完了:
| 实验 | 学到的东西 |
|---|---|
| 01 连接 + 点亮 | 扫描 / 连接 / 写数据 |
| 02 按钮 | 订阅通知,反向数据流 |
| 03 温度 | 连续数值、采样周期、全局变量 |
| 04 磁力计 | 三轴数据、查表映射、校准 |
| 05 引脚读按钮 | 引脚配置、数字输入、上拉 |
| 06 电位器 | 模拟输入、量程换算、滤波 |
| 07 RGB LED | 引脚输出、PWM 调光 |
| 08 加速度计 | 姿态判断、变化量检测 |
接下来可以把它们组合起来做完整作品:体感遥控车、环境监测站、简易乐器。
扫码添加客服咨询