본문 바로가기
전자공학/아두이노

아두이노로 만든 작품 소개- 노래에 맞춰 입벌리는 휴지통

by ohj921189 2020. 2. 21.
반응형

 

https://youtu.be/Vuc6Mz4ErdA

세 번째로 소개해드릴 작품은 노래에 맞추어 입 벌리는 휴지통입니다. 어린이날에 전시용으로 만든 작품입니다. 아이들이 전자공학이란 것에 흥미를 갖게 함과 동시에 부담 없이 재미있게 즐길 수 있도록 만들었습니다. 지금 보면 별거 아닌 것처럼 보이지만 하루를 꼬박 새워 어서 만들었던 기억이 있습니다. 그 노력의 결과인지 전시하는 시간 내내 아이들이 줄을 서서히 전시물을 체험하였습니다.


이 아이디어는 닌텐도 리듬 세상이라는 게임에서 착안을 했습니다. 리듬 세상이라는 게임에 노래에 맞추어서 입을 벌리는 게임이 있습니다. 그것을 바탕으로 하여 휴지통이 노래에 맞추어 입을 벌려 그 안에 공을 넣는 방식으로 아이들이 재미있게 즐길 수 있도록 변형하였습니다.

 

동작 원리는 위의 그림과 같습니다. 버튼(택트 스위치)를 누르면 노래가 재생됨과 동시에 서보모터가 작동합니다. 여러 패턴으로 서보모터가 동작하면서 휴지통의 뚜껑을 여러 각도로 열리게 합니다. 휴지통의 뚜껑이 조금 열리게 하기도 하고 많이 열리게 하기도 하고 동시에 열리게 하기도 하고 차례대로 열리게 합니다. 또한 속도도 조절하여서 빨리 열리게 하고 느리게 열리게 하였습니다. 노래에 맞추어 뚜껑이 빠르게 또는 느리게, 많이 또는 조금 열리게 하였습니다.


이 작품에 들어간 부품은 다음과 같습니다. 서보모터, sparkfun MP3 player 실드, 아두이노 2개, 택트 스위치 모듈, 스피커, 휴지통이 있습니다. 부품에 대해 설명드리도록 하겠습니다.

 

SparkFun MP3 player 실드란? 이 SparkFun MP3 player 실드는 아두이노 우노 위에 적층하여 사용하는 실드로, SD카드에 저장되어 있는 노래 또는 음향효과를 넣을 수 있게 해주는 실드입니다. SparkFun MP3 player 실드는 SPI 통신을 통해 아두이노와 통신이 가능하고 MP3 형식의 파일을 지원합니다. Micro SD 소켓에 Micro SD 카드를 꽂아 음악파일을 불러올 수 있고, 헤드폰 소켓에 스피커를 연결하여 음악을 출력할 수 있습니다.

 

 

서보모터란? PWM을 이용하여 0부터 대략 180도까지의 각도를 조절할 수 있게 해주는 모터입니다. 서보모터는 제어회로와 기어 박스, 모터로 구성되어 있어, 어떠한 특정 위치로 이동하거나, 특정 수치(속도 등) 만큼 가동할 때, 모터를 통한 피드백으로 제어를 세밀하게 할 수 있습니다. 서보모터는 자동화 생산 시스템, 로봇, 장난감, 가전제품 등 광범위하게 쓰이고 있습니다. PWM 이란 아래 그림을 보면 이해하기 쉽습니다.

 

20ms의 시간 동안 펄스가 얼마나 유지되는지를 통해 서보모터의 각도를 제어할 수 있습니다. 예를 들어 1ms를 유지하면 0도, 1.25ms만큼 유지하면 45도, 1.5ms만큼 유지하면 90도, 1.75ms만큼 유지하면 135도, 2ms만큼 유지하면 180도만큼 각도가 움직입니다.

하나의 아두이노는 버튼 제어와 서 보모 터 제어를 담당하였고 다른 하나의 아두이노는 노래 재생을 담당하였습니다. 버튼과 연결되어 있는 아두이노에서 버튼에 대한 신호를 받으면 서보모터를 제어하여 휴지통의 뚜껑의 각도를 조절하여 열리게 하였고 그와 동시에 다른 아두이노와 통신하여 MP3 실드로 음악을 재생할 수 있게 하였습니다.

아래는 서보모터 제어, 버튼 제어 아두이노에 대한 코드입니다.

#include <Servo.h> //서보 라이브러리를 불러옵니다.

int dsv_1=5;//타이밍이 중요해서 delay에 대한 변수를 만들어서 싱크가 안 맞을시 조정할수 있게 함
int dsv_2=3;
int dsv_3=5;
int dsv_4=5;
//int button= 10;
int servoPin1=10;
int servoPin2=11;
int servoPin3=12;

Servo servo1; // 서보를 제어할 서보 오브젝트를 만듭니다.
Servo servo2;
Servo servo3;

int angle=0;

void setup(){
  Serial.begin(9600);
  servo1.attach(servoPin1);
  servo2.attach(servoPin2);
  servo3.attach(servoPin3);
  //pinMode(,INPUT);
}

void loop(){
 while(Serial.available()){
  int data=Serial.read();
  Serial.println(data);
  if(data=='a'){
   delay(12000);
   for(int i=0;i<2;i++){
    for(angle=60;angle<150;angle++){
    servo1.write(angle);
    delay(dsv_1);
  }

  for(angle=150;angle>60;angle--){
    servo1.write(angle);
    delay(dsv_1);
    }
   delay(170);
   Serial.println('a');
  for(angle=60;angle<150;angle++){
    servo2.write(angle);
    delay(dsv_1);
    }

  for(angle=150;angle>60;angle--){
    servo2.write(angle);
    delay(dsv_1);
  }
  delay(180);
  for(angle=60;angle<150;angle++){
    servo3.write(angle);
    delay(dsv_1);
    }
   for(angle=150;angle>60;angle--){
    servo3.write(angle);
    delay(dsv_1);
  }
  if(i==0){
  delay(5000);
  }
  else if(i==1){
  delay(300);
  }

    }
  //두번째패턴
   for(angle=60;angle<150;angle++){
    servo1.write(angle);
    servo2.write(angle);
    servo3.write(angle);
    delay(dsv_2);
  }
   for(angle=150;angle>60;angle--){
    servo1.write(angle);
    servo2.write(angle);
    servo3.write(angle);
    delay(dsv_2);
  }
  delay(4000);
  //세번째패턴_1
   for(int j=0;j<2;j++){
     for(angle=60;angle<150;angle++){
    servo1.write(angle);
    delay(dsv_3);
  }
  delay(300);
  for(angle=60;angle<150;angle++){
    servo2.write(angle);
    delay(dsv_3);
  }
    delay(300);
  for(angle=60;angle<150;angle++){
    servo3.write(angle);
    delay(dsv_3);
  }
  if(j==0){
  delay(1500);
  }
  else if(j==1){
  delay(1300);
  }
   for(angle=150;angle>60;angle--){
    servo1.write(angle);
    servo2.write(angle);
    servo3.write(angle);
    delay(dsv_3);
   }
 if(j==0){
 delay(4000);
 }
 else if(j==1){
 delay(2300);
 } 
     }
  //네번째
 for(angle=60;angle<100;angle++){
  servo1.write(angle);
  delay(dsv_4);
 }
  for(angle=100;angle>60;angle--){ 
  servo1.write(angle);
  delay(dsv_4);
}  
  for(angle=60;angle<100;angle++){
  servo2.write(angle);
  delay(dsv_4);
 }
  for(angle=100;angle>60;angle--){ 
  servo2.write(angle);
  delay(dsv_4);
}  
  for(angle=60;angle<100;angle++){
  servo3.write(angle);
  delay(dsv_4);
 }
  for(angle=100;angle>60;angle--){ 
  servo3.write(angle);
  delay(dsv_4);
}
    }
  }
 
}

아래는 mp3 쉴드 아두이노에 관한 코드입니다.

#include<SPI.h>
#include<SdFat.h>
#include<SFEMP3Shield.h>

SdFat sd;
SFEMP3Shield MP3player;

void setup() {
  randomSeed(analogRead(0)); 
  Serial.begin(9600);
  sd.begin(SD_SEL, SPI_HALF_SPEED);
  MP3player.begin();
  MP3player.setVolume(10,10);
  pinMode(12,INPUT);
  Serial.println("UART");
}

void loop() {  
   int i;
   if(digitalRead(12)==HIGH){
    Serial.write('a');
    MP3player.begin();
    MP3player.playMP3("1.mp3.mp3");
    delay(45000);
    MP3player.stopTrack();
    }
  while(1){   
    i=(int)random(3,5);
    if(i==3){
         MP3player.begin();
         MP3player.playMP3("3.mp3");
         if(digitalRead(12)==HIGH){
          MP3player.stopTrack();
          continue;
          }
         delay(45000);
         MP3player.stopTrack();
      }
    else if(i==4){
         MP3player.begin();
         MP3player.playMP3("4.mp3");
         if(digitalRead(12)==HIGH){
          MP3player.stopTrack();
          continue;
          }
         delay(45000);
         MP3player.stopTrack();
          } 
    }

    delay(2000);
}

새로운 작품을 만드는 것은 항상 힘든 일입니다. 그렇지만 포기하지 않고 원하는 기능의 작품을 만들고 나면 그 뒤에는 뿌듯함과 동시에 이 일을 해내었다는 성취감이 뒤따라 오는 것 같습니다. 작품을 만들다 보면 생각지도 못한 곳에서 난관을 만나게 됩니다. 그렇지만 그 난관을 극복하고 나면 경험이 생겨 그것이 자신만의 노하우가 될 것입니다.

 

 

반응형

댓글