부품설명

자주 사용하는 부품들의 사용법에 대하여 알아봅니다.

푸시버튼 x 피에조 부저-버튼으로 멜로디 재생하기

2014-08-13 10:00:15

개요


아두이노는 다양한 입력과 출력을 지원합니다.
빛과 움직임 뿐만 아니라 소리의 입력과 출력 또한 가능합니다.


출처 : 'Simple note' 프로젝트 -  simple-note-an-arduino-musical-instrument

 


손쉽게 자신 만의 미니 건반을 만들 수도 있고.

 

출처 : 아두이노 테레민 - lab3 - Theremin as a capacitive Sensing Device

센서와 결합하여 우아한 모양의 테레민도 만들 수 있습니다.

본 예제에서는 
  • 디지털 출력의 HIGH 와 LOW을 일정한 주기로 반복하여 소리를 재생하는 방법에 대해 알아보고 
  • 이를 응용하여 멜로디- '학교종이 땡땡땡'을 연주 해 보겠습니다.

이밖에도 PCM(Pulse Code Modulation)처럼 음의 세기를 0과 1의 조합인 디지털 신호로 변환하여 재생하거나,
외부 쉴드와 결합하여 Wav파일의 음악을 재생 할 수 있습니다.


 

 


부품목록

NO 부품명 수량 상세설명
1 오렌지 보드 1 아두이노 호환보드
2 피에조 1 피에조
3 브레드보드 1 브레드보드
4 10㏀ 저항 1 저항
5 점퍼 케이블 5 점퍼 케이블
6 푸시버튼 1 푸시버튼
 
부품명 오렌지 보드 10㏀ 저항 브레드보드 점퍼케이블 푸시 버튼
파트 x1 x1 x1 x5  x1
부품명 피에조
파트 x1

 

 

하드웨어 Making

 

회로도 

브레드보드 레이아웃

 

소프트웨어 Coding

1. 푸시버튼을 누르면 약 1000Hz의 스퀘어파를 0.1초간 재생하는 코드 입니다.

아래의 코드를 아두이노에 업로드 합니다.
 

//출처: www.kocoafab.cc
const int buttonPin = 7;    // 버튼을 7번 핀에 연결합니다.
const int buzzer =  8;      // 부저를 8번 핀에 연결합니다.


int buttonState = 0; // 버튼의 현재 상태를 저장합니다.        

void setup() {

  pinMode(buzzer, OUTPUT);      // 부저를 출력으로 설정합니다.
 
  pinMode(buttonPin, INPUT);     // 버튼을 입력으로 설정합니다.
}

void loop(){

  buttonState = digitalRead(buttonPin); //버튼의 현재상태를 읽습니다.
 if (buttonState == HIGH) {     
    digitalWrite(8,1);
    delayMicroseconds(500);
    digitalWrite(8,0);
    delayMicroseconds(500);
    
  } 
  else {

    digitalWrite(buzzer, LOW); // 부저를 끕니다.
  }
}


스케치 설명 

 

 

const int buttonPin = 7;    // 버튼을 7번 핀에 연결합니다.
const int buzzer =  8;      // 부저를 8번 핀에 연결합니다.


int buttonState = 0; // 버튼의 현재 상태를 저장합니다.        

void setup() {

  pinMode(buzzer, OUTPUT);      // 부저를 출력으로 설정합니다.
 
  pinMode(buttonPin, INPUT);     // 버튼을 입력으로 설정합니다.
}
void loop(){ buttonState = digitalRead(buttonPin); //버튼의 현재상태를 읽습니다. if (buttonState == HIGH) { digitalWrite(8,1); delayMicroseconds(500); digitalWrite(8,0); delayMicroseconds(500);
else {

    digitalWrite(buzzer, LOW); // 부저를 끕니다.
  }
}


버튼의 현재 상태를 읽고,
만약에 버튼이 눌린상태 ( HIGH일떄) 디지털 8번 핀에 연결된 부저를 1의상태 ( ON)의 상태로 두고
500마이크로초를 대기합니다.
그다음 부저를 0의 상태로 두고 500마이크로초를 대기합니다.

위에 상황이 아니라면 (버튼이 눌리지 않았다면) 
부저를 LOW의 상태로 둡니다.

결과적으로 1밀리초 마다 반복하여 1000Hz의 주파수를 생성하여 소리로 인식되게 됩니다.


2. 위 코드를 응용하여 이번에는 버튼이 눌리면 멜로디를 재생하는 코드를 작성해 보겠습니다.

아래의 코드를 아두이노에 업로드 합니다.

 

 

 

//출처:www.kocoafab.cc

const int buttonPin = 7;    
const int buzzer =  8;      

int buttonState = 0;         

void setup() {

  pinMode(buzzer, OUTPUT);      
  pinMode(buttonPin, INPUT);     
}

void loop(){

  buttonState = digitalRead(buttonPin);
 if (buttonState == HIGH) {   
for(long i=0; i<1000000; i=i+2552){
  //sol
  digitalWrite(8,1);   delayMicroseconds(1276);
  digitalWrite(8,0);   delayMicroseconds(1276);
  }
  //sol
  delay(100);
  for(long i=0; i<1000000; i=i+2552){
  digitalWrite(8,1);   delayMicroseconds(1276);
  digitalWrite(8,0);   delayMicroseconds(1276);
  }
  //la
  delay(100);
  for(long i=0; i<1000000; i=i+2274){
  digitalWrite(8,1);   delayMicroseconds(1137);
  digitalWrite(8,0);   delayMicroseconds(1137);
  }
  //la
  delay(100);
  for(long i=0; i<1000000; i=i+2274){
  digitalWrite(8,1);   delayMicroseconds(1137);
  digitalWrite(8,0);   delayMicroseconds(1137);
  }
  //sol
  delay(100);
  for(long i=0; i<1000000; i=i+2552){
  digitalWrite(8,1);   delayMicroseconds(1276);
  digitalWrite(8,0);   delayMicroseconds(1276);
  }
  //sol
  delay(100);
  for(long i=0; i<1000000; i=i+2552){
  digitalWrite(8,1);   delayMicroseconds(1276);
  digitalWrite(8,0);   delayMicroseconds(1276);
  }
  //mi
  delay(100);
  for(long i=0; i<2000000; i=i+3034){
  digitalWrite(8,1);   delayMicroseconds(1517);
  digitalWrite(8,0);   delayMicroseconds(1517);
  }
  //sol
  delay(100);
  for(long i=0; i<1000000; i=i+2552){
  digitalWrite(8,1);   delayMicroseconds(1276);
  digitalWrite(8,0);   delayMicroseconds(1276);
  }
  //sol
  delay(100);
  for(long i=0; i<1000000; i=i+2552){
  digitalWrite(8,1);   delayMicroseconds(1276);
  digitalWrite(8,0);   delayMicroseconds(1276);
  }
  //mi
  delay(100);
  for(long i=0; i<1000000; i=i+3034){
  digitalWrite(8,1);   delayMicroseconds(1517);
  digitalWrite(8,0);   delayMicroseconds(1517);
  }
  //mi
  delay(100);
  for(long i=0; i<1000000; i=i+3034){
  digitalWrite(8,1);   delayMicroseconds(1517);
  digitalWrite(8,0);   delayMicroseconds(1517);
  }
  //le
  delay(100);
  for(long i=0; i<2000000; i=i+3405){
  digitalWrite(8,1);   delayMicroseconds(1703);
  digitalWrite(8,0);   delayMicroseconds(1703);
  }
  //sol
  delay(100);
  for(long i=0; i<1000000; i=i+2552){
  digitalWrite(8,1);   delayMicroseconds(1276);
  digitalWrite(8,0);   delayMicroseconds(1276);
  }
  //sol
  delay(100);
  for(long i=0; i<1000000; i=i+2552){
  digitalWrite(8,1);   delayMicroseconds(1276);
  digitalWrite(8,0);   delayMicroseconds(1276);
  }
  //la
  delay(100);
  for(long i=0; i<1000000; i=i+2274){
  digitalWrite(8,1);   delayMicroseconds(1137);
  digitalWrite(8,0);   delayMicroseconds(1137);
  }
  //la
  delay(100);
  for(long i=0; i<1000000; i=i+2274){
  digitalWrite(8,1);   delayMicroseconds(1137);
  digitalWrite(8,0);   delayMicroseconds(1137);
  }
  //sol
  delay(100);
  for(long i=0; i<1000000; i=i+2552){
  digitalWrite(8,1);   delayMicroseconds(1276);
  digitalWrite(8,0);   delayMicroseconds(1276);
  }
  //sol
  delay(100);
  for(long i=0; i<1000000; i=i+2552){
  digitalWrite(8,1);   delayMicroseconds(1276);
  digitalWrite(8,0);   delayMicroseconds(1276);
  }
  //mi
  delay(100);
  for(long i=0; i<2000000; i=i+3034){
  digitalWrite(8,1);   delayMicroseconds(1517);
  digitalWrite(8,0);   delayMicroseconds(1517);
  }
  //sol
  delay(100);
  for(long i=0; i<1000000; i=i+2552){
  digitalWrite(8,1);   delayMicroseconds(1276);
  digitalWrite(8,0);   delayMicroseconds(1276);
  }
  //mi
  delay(100);
  for(long i=0; i<1000000; i=i+3034){
  digitalWrite(8,1);   delayMicroseconds(1517);
  digitalWrite(8,0);   delayMicroseconds(1517);
  }
  //le
  delay(100);
  for(long i=0; i<1000000; i=i+3405){
  digitalWrite(8,1);   delayMicroseconds(1703);
  digitalWrite(8,0);   delayMicroseconds(1703);
  }
  //mi
  delay(100);
  for(long i=0; i<1000000; i=i+3034){
  digitalWrite(8,1);   delayMicroseconds(1517);
  digitalWrite(8,0);   delayMicroseconds(1517);
  }
  //do
  delay(100);
  for(long i=0; i<2000000; i=i+3822){
  digitalWrite(8,1);   delayMicroseconds(1911);
  digitalWrite(8,0);   delayMicroseconds(1911);
  }
  delay(3000);
} 
   else {

    digitalWrite(buzzer, LOW); 
  }
}

  
 



  
 

 


스케치 설명

기본 설정은 위의 코드와 동일하며 , 새롭게 등장한 for문과 그 역할에 대해서 알아 보겠습니다.

 

 

 

 

for(long i=0; i<2000000; i=i+3822){
digitalWrite(8,1);   delayMicroseconds(1911);
digitalWrite(8,0);   delayMicroseconds(1911);
  }
 


i 라는 변수를 int 대신 long 이라는 형식의 변수로 선언했습니다.
왜냐하면 int는 -32,769 ~ 32,767의 값을 사용하지만 long형식의 변수는 -2,147,483,648 ~ 2,147,483,647의 큰 값까지 사용할수 있습니다.
따라서 1000000 이라는 값을 저장할때 int형 변수로는 담을수가 없어서 long형식의 변수를 사용하였습니다.
for문이 매번 실행 할때 마다 i라는 변수가 1000000 혹은 2000000 보다 작은지 확인하고 , 작을 경우에
아래의 동작을 수행하면서  1번의 진동( 해당 주파수의 음계)를 만들어 냅니다.
또한 i는 시간의 흐름을 측정하는 타이머의 역할을 하며,
i에 3822(각 음계마다의 주기는 다른 값을 지니고 있습니다.)를 더해 2000000 혹은 1000000 보다 커지는 순간을 1초가 넘어갔다고 인식하여,
for문 아래 진동을 만들어 내는 코드가 작동되며 결과적으로 1초 동안 해당 음을 지속하게 됩니다.

 

 

 

 

kocoafabeditor

항상 진취적이고, 새로운 것을 추구하는 코코아팹 에디터입니다!

푸시버튼, 피에조 부저, 아두이노, 오렌지보드

김민중 2016-02-11 16:37:24

오... 신기하네요....;;

사포 2018-12-04 14:34:58

int와 long은 같은 형식의 다른 이름입니다. int의 범위 역시 -21억~+21억입니다. short의 범위가 -32,769 ~ 32,767이구요.