Skip to content

제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이 출력됩니다.

임계값 처리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일 때 bang
  • 두 번째 아웃렛: 값이 2일 때 bang
  • 세 번째 아웃렛: 값이 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. 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 → Pd

OSC란 ​

OSC(Open Sound Control) 는 음악・미디어 아트용으로 설계된 통신 프로토콜입니다.

  • 네트워크(UDP)를 사용해 데이터를 주고받는다
  • 주소 패턴(예: /microbit/accelerometer/x)으로 데이터를 식별한다
  • 숫자, 문자열 등의 데이터를 보낼 수 있다

SerialOSCConverter 사용법 ​

SerialOSCConverter 는 micro:bit의 시리얼 데이터를 OSC로 변환하는 애플리케이션입니다.

실행 절차 ​

  1. SerialOSCConverter를 실행한다
  2. micro:bit를 USB 케이블로 PC에 연결한다
  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.receive 와 osc.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(중간값)

스케일 매핑


클립(값의 제한) ​

센서 데이터는 예상 밖의 값이 나올 때가 있습니다. 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) 매끄러워지지만 반응이 느려집니다.

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: 눌림)을 전송하는 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~ 의 오른쪽 인렛에 연결합니다.