제4강 데이터 처리・micro:bit 연동
Pd에서 데이터를 처리하는 방법을 배우고, micro:bit의 센서 데이터를 Pd에서 수신해 소리로 변환하는 방법을 익힙니다.
이번 강의의 목표
- 임계값 처리・분기 처리로 데이터를 판정할 수 있게 된다
- micro:bit와 Pd를 시리얼 통신(OSC)으로 연결할 수 있게 된다
- 센서 데이터의 매핑・스무딩을 할 수 있게 된다
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이 출력됩니다.

임계값 처리 2: 범위 내의 판정
값이 특정 범위 안에 있는지 를 판정하려면 두 개의 비교 연산을 조합합니다.
>= 30 (30 이상인가?)
<= 70 (70 이하인가?)두 조건을 &&(AND)로 조합하면 「30〜70 범위 내」를 판정할 수 있습니다.

임계값 처리 3: change
change 는 입력값이 변화했을 때만 출력합니다. 같은 값이 연속으로 입력되어도 출력하지 않습니다.
change센서 데이터는 같은 값이 연속되는 경우가 많기 때문에, change 를 사용해 「값이 바뀌었을 때만 처리」함으로써 불필요한 처리를 줄일 수 있습니다.

분기 처리 1: sel에 의한 분기
sel 에 여러 개의 값을 지정하면 값에 따른 분기 를 할 수 있습니다.
sel 1 2 3- 첫 번째 아웃렛: 값이 1일 때 bang
- 두 번째 아웃렛: 값이 2일 때 bang
- 세 번째 아웃렛: 값이 3일 때 bang
- 마지막 아웃렛: 어느 것에도 일치하지 않을 때 값을 그대로 출력

분기 처리 2: 값의 범위에 의한 분기
값의 범위에 따라 서로 다른 처리를 하는 경우에는 여러 개의 비교 연산을 조합합니다.
예: 센서의 값을 3단계로 나누기
- 0〜30: 「약함」
- 31〜70: 「중간」
- 71〜100: 「강함」

분기 처리 3: change + 분기
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. Radio→change→sel 0 1 2 로 연결합니다.
Part 2: micro:bit와의 연동
micro:bit의 센서 데이터를 Pd로 전송하고, 실시간으로 소리를 제어하는 방법을 배웁니다.
시리얼 통신의 구조
micro:bit와 PC는 USB 케이블 을 통해 시리얼 통신으로 데이터를 주고받을 수 있습니다. 이 수업에서는 시리얼 데이터를 OSC(Open Sound Control) 라는 프로토콜로 변환해서 Pd로 보냅니다.
데이터의 흐름:
micro:bit → USB(시리얼 통신)→ SerialOSCConverter → OSC → PdOSC란
OSC(Open Sound Control) 는 음악・미디어 아트용으로 설계된 통신 프로토콜입니다.
- 네트워크(UDP)를 사용해 데이터를 주고받는다
- 주소 패턴(예:
/microbit/accelerometer/x)으로 데이터를 식별한다 - 숫자, 문자열 등의 데이터를 보낼 수 있다
SerialOSCConverter 사용법
SerialOSCConverter 는 micro:bit의 시리얼 데이터를 OSC로 변환하는 애플리케이션입니다.
실행 절차
- SerialOSCConverter를 실행한다
- micro:bit를 USB 케이블로 PC에 연결한다
- SerialOSCConverter의 화면에서:
- Serial Port: micro:bit가 연결된 포트를 선택한다
- Baud Rate:
115200을 선택한다(micro:bit의 기본값) - OSC Port:
8000(기본값)을 확인한다
- Connect 버튼을 클릭한다
- micro:bit에서 데이터가 도착하면 화면에 데이터가 표시된다
포트를 찾을 수 없는 경우
- micro:bit가 올바르게 USB로 연결되어 있는지 확인한다
- USB 케이블이 데이터 전송을 지원하는지 확인한다(충전 전용 케이블로는 데이터를 전송할 수 없습니다)
- 드라이버가 필요한 경우에는 설치한다
MakeCode 쪽 설정
micro:bit의 프로그램에서 시리얼 통신 을 사용해 데이터를 전송해야 합니다. MakeCode의 「시리얼 통신」 카테고리에서 「시리얼로 값 쓰기」 블록을 사용합니다.
OSC 데이터 수신
Pd에서 OSC 데이터를 수신하려면 else 라이브러리의 osc.receive 와 osc.route 를 사용합니다.
절차
else/osc.receive 8000을 배치한다(포트 8000에서 수신)else/osc.route /x /brightness /volume을 배치한다osc.route의 각 아웃렛에서 센서 데이터가 출력된다

트리거 메시지의 송수신
버튼이 눌렸을 때 등의 트리거(순간적인 이벤트) 도 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(중간값)

클립(값의 제한)
센서 데이터는 예상 밖의 값이 나올 때가 있습니다. clip, max, min 을 사용해 값의 범위를 제한합니다.
| 오브젝트 | 기능 |
|---|---|
clip 0 100 | 값을 0〜100 범위로 제한한다 |
max 0 | 값이 0 미만이면 0으로 만든다(하한) |
min 100 | 값이 100을 넘으면 100으로 만든다(상한) |
max / min 이름에 주의
Pd의 max 는 「최솟값을 제한하는」(하한을 설정하는) 오브젝트이고, min 은 「최댓값을 제한하는」(상한을 설정하는) 오브젝트입니다. 일반적인 의미와 반대로 느껴질 수 있지만, 「출력의 최댓값은 적어도 이 값」(max), 「출력의 최솟값은 많아도 이 값」(min)으로 외웁시다.

평활화 처리(스무딩)
센서 데이터는 노이즈(미세한 흔들림)를 포함하기 때문에, 그대로 사용하면 덜컹거리는 제어가 됩니다. 평활화(스무딩) 로 값의 변화를 매끄럽게 만듭니다.
방법1: lop~ 으로 시그널 평활화
lop~(로우패스 필터)는 시그널의 고주파 성분을 제거하기 때문에, 결과적으로 값이 매끄러워집니다.
sig~ → lop~ 5 → snapshot~컷오프 주파수를 낮출수록(예: lop~ 1) 매끄러워지지만 반응이 느려집니다.

방법2: else/smooth~
else/smooth~ 는 평활화에 특화된 오브젝트입니다.
else/smooth~ 50인수의 값이 클수록 매끄러워집니다.

else/s2f~ — 시그널을 값으로 되돌리기
평활화한 결과는 시그널(~)인 채이므로, 값(메시지)을 받는 오브젝트에 전달하려면 다시 값으로 변환해야 합니다. else/s2f~ 를 사용하면 snapshot~ + metro 조합보다 간단하게 값으로 만들 수 있습니다.
평활화의 정도
평활화가 너무 강하면 반응이 둔해지고, 너무 약하면 노이즈가 남습니다. 작품의 특성에 맞춰 조정해 주세요.
【심화】변화량의 검출
값 자체가 아니라 값의 변화량(얼마나 급격하게 바뀌었는지)을 검출하면, 「빠르게 움직였다」「천천히 움직였다」와 같은 움직임의 질을 판정할 수 있습니다.
방법
- 현재 값과 바로 앞의 값의 차분을 계산한다
- 차분의 절댓값이 임계값을 넘으면 「급격한 변화」로 판정한다

응용 예
- 가속도의 변화량이 크다 → 타악기처럼 짧은 소리를 낸다
- 변화량이 작다 → 현악기처럼 지속음을 낸다
- 변화의 방향(양/음)에 따라 서로 다른 효과를 준다
micro:bit 연동 연습 문제
문제1
micro:bit의 A, B 버튼을 누르면 각각 /buttonA, /buttonB 라는 주소로 0/1(0: 눌리지 않음, 1: 눌림)을 전송하는 micro:bit 프로그램과, 그것을 수신하는 Pd 패치를 만들어 주세요.
힌트
MakeCode에서 버튼A, 버튼B라는 변수를 준비합니다. 그리고 「무한 반복」 블록의 맨 앞에 만약 버튼 A가 눌렸다면 변수 버튼A를 1로 설정 아니면 변수 버튼A를 0으로 설정 이라는 블록을 만듭니다. 버튼B도 같은 방법으로 만듭니다. 그 아래에 시리얼 통신 문자열 쓰기 "/ButtonA" → 시리얼 통신 한 줄 쓰기 버튼A 라는 블록을 만들고, 버튼B도 마찬가지로 만듭니다. Pd 쪽은 else/osc.receive 8000 → else/osc.route /buttonA /buttonB → 넘버 박스(왼쪽과 가운데 두 곳)로 연결합니다.
문제2
micro:bit의 A, B 버튼을 누르면 각각 500 Hz, 1000 Hz로 사인파를 계속 재생하는 기능을 만들어 주세요.
힌트
osc.route /buttonA /buttonB → sel 1 로 버튼이 눌린 순간(값이 1일 때)에 bang을 출력하고, 각각의 주파수를 메시지로 osc~ 에 보냅니다. 다만 이대로는 A, B를 계속 누르고 있을 때의 동작이 불안정하므로, sel 1 바로 앞에 change 를 넣어서 버튼 상태에 변화가 있을 때만 osc~ 에 주파수를 보내는 형태로 만듭니다.
문제3
사칙연산을 사용해서 밝기 센서의 최대・최솟값이 대략 0〜100의 값이 되도록 변환한 수치를 표시해 주세요.
힌트
밝기 센서의 값은 0〜255입니다. / 255 → * 100 순으로 연결하면 0〜100으로 변환할 수 있습니다(expr $f1 / 255 * 100 도 OK). 다만 현실 환경에서는 255의 값이 나오지 않으므로, 실제 환경에서의 밝기 최댓값으로 나눈 뒤 100을 곱하는 것이 좋습니다.
문제4
scale 과 clip 을 사용해서 밝기 센서의 최대・최솟값이 반드시 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의 출력을 > 0 → sel 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의 출력을 > 0 → sel 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~ 의 오른쪽 인렛에 연결합니다.