Skip to content

第4讲 数据处理・micro:bit 联动

学习在 Pd 中处理数据的方法,掌握用 Pd 接收 micro:bit 的传感器数据并转换为声音的方法。

本讲目标

  • 能够用阈值处理・分支处理来判断数据
  • 能够用串口通信(OSC)连接 micro:bit 与 Pd
  • 能够对传感器数据进行映射・平滑处理

Part 1: 数据处理

「如何判断」从传感器接收到的数据,是交互作品的关键。这里学习用于数值判断的基本技巧。


阈值处理 1: sel, else/above

阈值 是指用于判断「是否超过了某个数值」的边界值。

sel(select)

sel 在输入与指定数值 一致时 输出 bang。

sel 100
  • 左出口: 数值为 100 时输出 bang
  • 右出口: 不是 100 时,原样输出该数值

else/above

else/above 在输入 超过 指定数值时输出 bang。

else/above 50

在数值超过 50 的瞬间输出 bang。

阈值处理1


阈值处理 2: 范围内的判断

要判断数值 是否处于特定范围内,可以组合两个比较运算。

>= 30   (是否在 30 以上?)
<= 70   (是否在 70 以下?)

&&(AND)把两个条件组合起来,就能判断「是否在 30〜70 的范围内」。

阈值处理2: 范围内


阈值处理 3: change

change 只在输入值 发生变化时 才输出。即使连续输入相同的数值,也不会输出。

change

传感器数据经常连续出现相同的数值,因此使用 change 做到「只在数值改变时才处理」,可以减少不必要的处理。

阈值处理3: change


分支处理 1: 用 sel 分支

sel 指定多个数值,就可以根据数值进行 分支

sel 1 2 3
  • 第 1 个出口: 数值为 1 时 bang
  • 第 2 个出口: 数值为 2 时 bang
  • 第 3 个出口: 数值为 3 时 bang
  • 最后的出口: 都不匹配时,原样输出数值

分支处理1


分支处理 2: 按数值范围分支

要根据数值范围进行不同的处理,就组合多个比较运算。

例: 把传感器的数值分为 3 个档次

  • 0〜30: 「弱」
  • 31〜70: 「中」
  • 71〜100: 「强」

分支处理2: 数值范围


分支处理 3: change + 分支

change 与分支组合起来,就能做出「只在状态改变时才处理」的模式。

例: 传感器数值超过阈值的瞬间发声,低于阈值的瞬间停止发声。

分支处理3: change+分支


数据处理 练习题

问题1

请制作一个补丁:当数字框的数值 在 50 以上 时输出「bang」。

提示

组合 >= 50 对象与 sel 1>= 50 在条件为真时输出 1,为假时输出 0。

问题2

请制作一个补丁:根据 V. Radio(纵向排列的开关。点击后输出 0〜(开关数-1)的数值。选中状态下可从画面右侧 Options 更改开关数量)的数值,分别播放 3 种衰减音(220Hz・440Hz・880Hz,持续 1 秒)。

提示

V. Radio 连接到 sel 0 1 2,再把 sel 0 1 2 的各个出口连接到分别通往生成 3 种衰减音的 vline~ 的各条消息。3 种衰减音可参考第 3 讲练习题 6 中制作的补丁。

问题3

请在问题 2 制作的补丁基础上,做成只有当 V. Radio 的数值 发生变化时 才播放这 3 种衰减音的补丁。

提示

V. Radiochangesel 0 1 2 连接。


Part 2: 与 micro:bit 的联动

学习把 micro:bit 的传感器数据发送到 Pd,并实时控制声音的方法。


串口通信的原理

micro:bit 与电脑可以通过 USB 线 以串口通信交换数据。在本课程中,我们把串口数据转换为 OSC(Open Sound Control) 协议后发送给 Pd。

数据的流向:

micro:bit → USB(串口通信)→ SerialOSCConverter → OSC → Pd

什么是 OSC

OSC(Open Sound Control) 是为音乐・媒体艺术设计的通信协议。

  • 使用网络(UDP)收发数据
  • 用地址模式(例: /microbit/accelerometer/x)来识别数据
  • 可以发送数值、字符串等数据

SerialOSCConverter 的使用方法

SerialOSCConverter 是把 micro:bit 的串口数据转换为 OSC 的应用程序。

启动步骤

  1. 启动 SerialOSCConverter
  2. 用 USB 线把 micro:bit 连接到电脑
  3. 在 SerialOSCConverter 的画面中:
    • Serial Port: 选择连接着 micro:bit 的端口
    • Baud Rate: 选择 115200(micro:bit 的默认值)
    • OSC Port: 确认为 8000(默认值)
  4. 点击 Connect 按钮
  5. 当 micro:bit 的数据传来时,画面上会显示数据

找不到端口时

  • 确认 micro:bit 是否已正确通过 USB 连接
  • 确认 USB 线是否支持数据传输(充电专用线无法传输数据)
  • 如果需要驱动程序,请安装

MakeCode 一侧的设置

需要在 micro:bit 的程序中使用 串口通信 来发送数据。请使用 MakeCode「串口通信」类别中的「串口写入数值」积木。


OSC 数据的接收

要在 Pd 中接收 OSC 数据,可以使用 else 库的 osc.receiveosc.route

步骤

  1. 放置 else/osc.receive 8000(在端口 8000 接收)
  2. 放置 else/osc.route /x /brightness /volume
  3. 传感器数据会从 osc.route 的各个出口输出

OSC 数据的接收

触发消息的收发

按下按钮之类的 触发(瞬时事件) 也可以用 OSC 收发。

  • micro:bit 一侧: 按下按钮 A 时,按 串口通信 写出字符串 "/ButtonA"串口通信 写出一行 "1" 的方式进行串口发送
  • Pd 一侧: 用 osc.route 路由 /ButtonA,作为 bang 接收

传感器数据的映射

需要把 micro:bit 的传感器数值(例: 加速度 -1024〜1024)转换到在 Pd 中想使用的范围(例: 频率 200〜2000 Hz)。

cyclone/scale

cyclone/scale 把数值的范围映射(转换)到另一个范围。

cyclone/scale -1024 1024 200 2000
  • 输入范围: -1024 〜 1024
  • 输出范围: 200 〜 2000

输入值 0 → 输出值 1100(中间值)

刻度映射


裁剪(数值的限制)

传感器数据有时会出现预料之外的数值。可以用 clipmaxmin 限制数值的范围。

对象功能
clip 0 100把数值限制在 0〜100 的范围内
max 0数值小于 0 时变为 0(下限)
min 100数值超过 100 时变为 100(上限)

注意 max / min 的名称

Pd 的 max 是「限制最小值」(设定下限)的对象,min 是「限制最大值」(设定上限)的对象。可能会觉得与一般的含义相反,不妨记成「输出的最大值至少为这个数」(max)、「输出的最小值至多为这个数」(min)。

裁剪


平滑处理(Smoothing)

传感器数据含有 噪声(细微的抖动),直接使用会导致控制变得抖动不稳。用 平滑(smoothing) 让数值的变化变得顺滑。

方法1: 用 lop~ 平滑信号

lop~(低通滤波器)会除去信号的高频成分,结果就是数值变得平滑。

sig~ → lop~ 5 → snapshot~

截止频率越低(例: lop~ 1)越平滑,但反应会变慢。

用 lop~ 平滑

方法2: else/smooth~

else/smooth~ 是专门用于平滑的对象。

else/smooth~ 50

参数的数值越大越平滑。

用 smooth~ + s2f~ 平滑

else/s2f~ — 把信号变回数值

平滑后的结果仍然是信号(~),要传给接收数值(消息)的对象,就需要再转换回数值。使用 else/s2f~snapshot~ + metro 的组合更简洁地转换为数值。

平滑的程度

平滑过强会导致反应迟钝,过弱则会残留噪声。请配合作品的特性进行调整。


【进阶】变化量的检测

不看数值本身,而是检测数值的 变化量(变化得有多急剧),就能判断「快速移动」「缓慢移动」这类动作的性质。

方法

  1. 计算当前值与前一个值的差值
  2. 若差值的绝对值超过阈值,就判定为「急剧变化」

变化量的检测

应用示例

  • 加速度的变化量大 → 像打击乐器那样发出短促的声音
  • 变化量小 → 像弦乐器那样发出持续音
  • 根据变化的方向(正/负)给予不同的效果

micro:bit 联动 练习题

问题1

请制作一个 micro:bit 程序,按下 A、B 按钮时分别向 /buttonA/buttonB 这两个地址发送 0/1(0: 未按下, 1: 已按下),并制作接收它的 Pd 补丁。

提示

在 MakeCode 中准备名为「按钮A」「按钮B」的变量。然后在「一直重复」积木的开头,创建 如果 按钮 A 被按下 则 把变量 按钮A 设为 1 否则 把变量 按钮A 设为 0 这样的积木。按钮 B 也同样创建。在其下方创建 串口通信 写出字符串 "/ButtonA"串口通信 写出一行 按钮A 这样的积木,按钮 B 同理。Pd 一侧按 else/osc.receive 8000else/osc.route /buttonA /buttonB → 数字框(左侧与中间两处)连接。

问题2

请制作一个功能:按下 micro:bit 的 A、B 按钮时,分别持续播放 500 Hz、1000 Hz 的正弦波。

提示

osc.route /buttonA /buttonBsel 1,在按钮被按下的瞬间(数值为 1 时)输出 bang,并用消息把各自的频率发送给 osc~。不过就这样的话,一直按住 A、B 时的行为会不稳定,因此在 sel 1 之前加入 change,做成只有按钮状态发生变化时才向 osc~ 发送频率的形式。

问题3

请使用四则运算,把光线传感器的最大・最小值转换为大致 0〜100 的数值并显示。

提示

光线传感器的数值是 0〜255。按 / 255* 100 的顺序连接即可转换为 0〜100(用 expr $f1 / 255 * 100 也可以)。不过,在现实环境中不会取到 255,因此除以实际环境下亮度的最大值再乘以 100 会更好。

问题4

请使用 scaleclip,把光线传感器的最大・最小值转换为必定处于 0〜100 的数值并显示。

提示

cyclone/scale (实际传感器数据的下限值) (实际传感器数据的上限值) 0 100 进行映射,再用 clip 0 100 确实地限制范围。

问题5

请适当地转换光线传感器的数值,制作一个频率会随之变化的特雷门琴。

提示

cyclone/scale 把光线传感器的数值映射到合适的频率范围(例: 200〜2000 Hz),并连接到 osc~ 的频率入口。

问题6

请进行转换,使得用手机的手电筒照射时数值大于 0,不照射时始终显示 0(不照射时的亮度为 0,照射时的亮度为 100)。

提示

cyclone/scale (无灯光时的传感器值) (有灯光时的传感器值) 0 100 进行映射。

问题7

请使用第 6 题制作的功能,做出用手机手电筒照射 micro:bit 时,播放 1000 Hz 正弦波并在 1 秒内衰减的功能。

提示

把问题 6 的输出用 > 0sel 1 转换为 bang。按 bang → vline~ 的包络(例: 1 0, 0 1000 0)→ *~output~ 来发出衰减音。也可参考第 3 讲练习题 6 中制作的衰减音补丁。


【进阶】练习题

进阶1

请转换声音传感器的数值,使得在 micro:bit 附近拍手时数值大于 0,不拍手时始终显示 0。

提示

cyclone/scale (不拍手时的声音传感器值) (拍手时的传感器值) 0 100 进行映射,再用 clip 0 100 确实地把范围限制在 0-100。

进阶2

请使用第 1 题制作的补丁,做出拍手时播放 1000 Hz 正弦波并在 1 秒内衰减的功能。

提示

把进阶 1 的输出用 > 0sel 1 转换为 bang,按 bang → vline~ 包络(例: 1 0, 0 1000 0)→ *~output~ 的流程发出 1000 Hz 的衰减音。

进阶3

请对练习题 2 制作的补丁追加平滑处理,使切换时的频率变化变得平缓(声音逐渐变高/变低)。

提示

把频率的数值用 else/smooth~ 处理后再连接到 osc~else/smooth~ 的参数越大变化越平缓。

进阶4

请在生成白噪声的状态下,让低通滤波器的截止频率随着声音传感器的大小而增大。此外,请对传感器的数值追加适度的映射与平滑处理,使声音的变化更自然。

提示

noise~lop~output~ 连接。把声音传感器的数值用 cyclone/scale 映射到合适的频率范围(例: 200〜5000 Hz),用 else/smooth~ 平滑之后再连接到 lop~ 的右入口。