본문 바로가기

아두이노 피아노

반응형

안녕하세요 Apple 입니다.


오늘은 아두이노와 프로세싱을 이용하여 독특한 피아노를 만들려 합니다.


일단 우리의 목표는 아래의 동영상처럼 구현하는것 입니다.

일단 하기전에 capacitive 라는 라이브러리를 다운 받으셔야 합니다.

http://playground.arduino.cc/Main/CapacitiveSensor?from=Main.CapSense


위의 사이트에 들어가셔서 다운 하시면 됩니다.


다운후 압축을 풀어 다음과같은 경로에 저장 합니다.

문서(Documents) > Arduino > libraries


그리고난후 아두이노스케치를 실행하셔서


상단에서

스케치 > 라이브러리 가져오기 > CapacitiveSensor(밑에 있어요)



가 있는지 확인하셔야 합니다.


이제 소프트웨어 설정이 끝났으니깐 하드웨어를 구성하면

일단 준비물은


점퍼핀 여러개, 1M옴짜리 저항 여러개(1M아니여도 됨)

아두이노 보드, 종이컵

이렇게 준비하시면 됩니다.


여기서부터 영상을 중심으로 설명 하겠습니다.


회로도는 다음과 같이 해주세요

저항의 한쪽은 모두 이어서 2pin에 꽂고

다른한쪽은 각각 3,4,5,6핀에 꽂은후 점퍼핀 같은걸로 따로 또 빼주세요(건반쪽으로 가는핀)


3번핀에는 도

4번핀에는 레

5번핀에는 미

6번핀에는 파

소리가 나게 할거에요.


하드웨어 구성은 끝났으니깐

다음으로 소프트웨어인 아두이노와 프로세싱 코드를

살펴보겠습니다.


일단 아두이노코드 부터 보면




#include <CapacitiveSensor.h>


CapacitiveSensor   cs_2_3 = CapacitiveSensor(2, 3);      

CapacitiveSensor   cs_2_4 = CapacitiveSensor(2, 4);      

CapacitiveSensor   cs_2_5 = CapacitiveSensor(2, 5);

CapacitiveSensor   cs_2_6 = CapacitiveSensor(2, 6);

void setup() {

  cs_2_3.set_CS_AutocaL_Millis(0xFFFFFFFF);

  Serial.begin(115200);

}

int boundary = 700;

void loop() {

  long total1 = cs_2_3.capacitiveSensor(30);

  long total2 = cs_2_4.capacitiveSensor(30);

  long total3 = cs_2_5.capacitiveSensor(30);

  long total4 = cs_2_6.capacitiveSensor(30);


  if (total1 >= boundary) Serial.print(1);

  else if (total1 < boundary) Serial.print(0);

  Serial.print("a");

  if (total2 >= boundary) Serial.print(1);

  else if (total2 < boundary) Serial.print(0);

  Serial.print("a");

  if (total3 >= boundary) Serial.print(1);

  else if (total3 < boundary) Serial.print(0);

  Serial.print("a");

  if (total4 >= boundary) Serial.println(1);

  else if (total4 < boundary) Serial.println(0);                             




이런식으로 되있는데

좀 복잡하죠?



설명드리자면

일단 아까 다운받은 capacitiveSensor라이브러리를 가져와 줍니다

코드 맨 윗줄에


#include <CapacitiveSensor.h>

라고 해주시면 됩니다.

다음으로
CapacitiveSensor   cs_2_3 = CapacitiveSensor(2, 3);      
CapacitiveSensor   cs_2_4 = CapacitiveSensor(2, 4);      
CapacitiveSensor   cs_2_5 = CapacitiveSensor(2, 5);
CapacitiveSensor   cs_2_6 = CapacitiveSensor(2, 6);

이부분은 입력핀과 출력핀을 설정하는 부분 입니다(자세한건 위의 사이트 들어가서 보세요)

그다음은 capacitiveSensor를 시작하는 함수에요
바로 이부분
cs_2_3.set_CS_Autocal_Millis(0xFFFFFFFF);
입니다. 그대로 작성하시면 문제 없어요.



여기까지하면 준비는 끝났고
다음로 신호를 받아야 겠죠?


바로 이부분 인데요.

capacitiveSensor함수는 신호를 읽어오는 함수 입니다.

안의 값은 "몇번보낸것의 평균을 낼것이냐"

입니다. 저는 30으로 설정했어요.


값이 높을수록 정밀하지만 느려지고

낮을수록 비정밀하지만 빨라요


보통 손을대면 값이 커지고 때면 값이 작아져요

저는 boundary라는 변수를 만들어서 boundary값이상이면

감지된것으로 인식

반대로 값이작으면 땐것으로 인식하게 만들었어요.


그런다음 감지되면 1을

감지 안됬으면 0을 Serial.print로 보냅니다.



여기까지하면 아두이노코드는 끝났습니다.

다음은 프로세싱 코드에요




import processing.serial.*;


import ddf.minim.spi.*;

import ddf.minim.signals.*;

import ddf.minim.*;

import ddf.minim.analysis.*;

import ddf.minim.ugens.*;

import ddf.minim.effects.*;

Serial port;


AudioSample Do;

AudioSample Re;

AudioSample Mi;

AudioSample Fa;

AudioSample So;

Minim minim;

color[] c = new color[8];

String s[]={"Do","Re","Mi","Fa","So","Ra","Ti","Do"};

void setup() {

size(500,500);

  minim = new Minim(this);

  port = new Serial(this, Serial.list()[0], 9600);

  println(Serial.list());

  Do = minim.loadSample("sound1.wav");

  Re = minim.loadSample("sound2.wav");

  Mi = minim.loadSample("sound3.wav");

  Fa = minim.loadSample("sound4.wav");

  //  So = minim.loadSample("sound5.wav");

  c[0] = color(255,0,0);

  c[1] = color(255,127,0);

  c[2] = color(255,255,0);

  c[3] = color(0,255,0);

  c[5] = color(0,0,255);

  c[6] = color(127,127,255);

  c[7] = color(255,0,255);

  textSize(300);

  textAlign(CENTER,CENTER);

}

boolean[] tone = new boolean[8];

void draw() {

  if (tone[0]) {

    Do.trigger();

    while (tone[0]) {

      println("Do");

      if (tone[0] == false) break;

    }

  } else if (tone[1]) {

    Re.trigger();

    while (tone[1]) {

      println("Re");

      if (tone[1] == false) break;

    }

  } else if (tone[2]) {

    Mi.trigger();

    while (tone[2]) {

      println("Mi");

      if (tone[2] == false) break;

    }

  } else if (tone[3]) {

    Fa.trigger();

    while (tone[3]) {

      println("Fa");

      if (tone[3] == false) break;

    }

  }

}


void serialEvent(Serial p) {

  String getData = p.readStringUntil('\n');

  if (getData != null) {

    if (getData.startsWith("s"));

    String[] serialData = getData.trim().replace("s", "").split("a");

    if (serialData.length > 1) {

      for (int i=0; i<serialData.length; i++) {

        int [] Tone = new int[8];

        Tone[i]=Integer.parseInt(serialData[i]);

        if (Tone[i] > 0) tone[i] = true;

        else tone[i] = false;

        if (tone[i]){ background(c[i]); text(s[i],width/2,height/2-3);}

      }

    }

  }

}



일단 소리와 시리얼 통신을 위해

Sketch > Import Library > serial과 minim을 가져옵니다.


아두이노와 프로세싱 연결은

Serial myPort;

myPort = new Serial(this, Serial.list()[0], 9600);

이구문을 통해 가능하다.


Serial.list()[0]는 "컴퓨터와 연결된 포트중 첫번째 포트와 연결하겠다" 라는 뜻입니다.


println(Serial.list()[0]);로 볼수있습니다.


프로세싱에서는 minim이라는 내장 라이브러리를 사용합니다. minim은 프로세싱에서 음악파일을 재생할 수 있게 해주는 라이브러리입니다.

음악을 재생할때는 일단 저장한후 저장된 폴더에다가 음악 파일을 넣으셔야 합니다


이런식으로요


아두이노 스케치에서는 건반의 상태를 확인하고 그 정보를 1과 0의 형태로 프로세싱으로 전송하고 프로세싱에서는 그냥 그 데이터를 통해 건반에맞는 음악 파일을 재생하는것 뿐입니다.

음원파일은 setup()에서 loadSample()을 통해 불러오게 되고, draw()에서는 스케치에서 보낸 값을 비교하고 trigger를 통해 해당 건반에 해당하는 음계음을 재생시킵니다.

최종 완성 동영상




CapacitiveSensorSketch.zip

music.zip


반응형