본문 바로가기

Arduino/응용 프로젝트(1학기)

립싱크로봇 제작


사운드 센서를 이용하여 립싱크 로봇을 만들어 보자

구현방법

1. 사운드 센서로 입력 받은 값에 따라 다른 입모양을 출력하는 립싱크 로봇을 만든다.

- 기존의 shift register를 이용하는 대부분의 립싱크 로봇보다 코드가 짧고 회로가 단순한 립싱크 로봇을 구현한다. (본래에는 shift register를 사용하고자 했지만 후에 사용하지 않기로 결정했다)

- 센서 입력값에 따라 로봇의 표정이 자연스럽게 변할 수 있도록 입력받은 센서값을 알맞게 변형 시킨다.

- shift register를 사용하지 않음으로써 생기는 마지막 열의 지연 현상을 최대한 없애고 그에 따라 나오는 문제인 과도한 깜빡임 문제를 알맞게 해결한다.

2. 아두이노를 이용한 아두이노 스피커를 만들어서 노래를 출력한다.

-Free MP3 Wma Converter라는 프로그램으로 mp3형식의 음악파일을 wav 파일로 변환한다.


1.8x8도트매트릭스란?

8x8도트매트릭스는 위 그림과 같이 8개의 행과 8개의 열로 이루어진 배열과 같다. 64개의 LED를 행8개, 열8개의 포트로 조절하는 것이다. 이러한 매트릭스의 기본은 한줄씩 킨다는 것이다. 각 열의 집합을 데이터라인이라고 하며 한줄의 행을 스캔라인이라고 한다. 첫 번째 행과 첫 번쨰 열의 즉, (1,1)위치의 LED를 킬려면 1번째 행의 포트와 1번쨰 열의 포트에 신호를 보내주면 된다. 함수의 좌표로 이해하면 더 쉬울 수도 있다. 그런데 LED배열의 모양을 고려할 때 어느 스캔라인에 신호를 주는지까지 고려할 필요는 없으므로  스캔라인은 for문을 돌려서 다 켜준다. 이제 각 열에서 어떤 LED에 신호를 줘야 할지만 고려하면 된다. 필요한 표정의 개수만큼의 행의 개수를 가진 2차원 배열을 선언해준다. 이것은 문서 뒤편의 코드를 참고하기로 한다. 1의 신호가 들어오는 곳의 LED는 켜지고 0의 신호가 들어오는 LED의 불은 꺼지게 된다. 1번쨰 열의 모든 LED에 불이 들어오게 해주고 싶으면 이진법(11111111)의 신호를 보내주면 되는 것이다. 그런데 이 이진법으로 배열을 만들어주면 코드가 너무 길어지므로 16진법으로 바꾼다. 숫자 15를 이진법으로 나타내려면 4자리가 필요한데 16진법을 사용하면 첫째 자리에 15까지의 숫자를 표현할 수 있다. 10진법을 쓰면 한 자리에 숫자를 9까지 쓰는데, 16진법에서는 10부터 15까지를 알파벳 A부터 E까지로 대입해서 표현한다.16진법을 나타내기 위해서는 앞에 0X라는 표현을 쓰면 된다. 15라는 숫자를 16진법으로 나타내면 0X0E가 될 것이고 32라는 숫자를 16진법으로 나타내면 0X20이 될것이다. 1열의 모든 LED를 키려면 16진법으로 0xEE의 신호를 보내주면 된다. 


처음에 고려헀던 얼굴 모양의 배열 작성한것,

센과 치히로 괴물을 만들기로 결정한 후에 입모양만을 배열로 작성한 것.

2.사운드센서란?

주변 소리의 크기를 0부터 1023까지 아날로그(연속적)으로 입력을 받는 센서이다. 입력 받는 값을 이용하여 조건문을 만들어 코딩을 하면 된다. 사운드 센서를 브레드보드에 연결하기 위해서는 우선 납땜을 해야 한다는 것을 잊지 않도록 한다. 세핀이 있는데 vcc는 전압, gnd는 아두이노의 gnd에 연결하고 나머지 하나는 아두이노에 연결될 핀과 연결하는 자리이며 뒷부분의 나사를 돌림으로써 감도를 조절할 수 있다.

2. 회로도

사운드 센서는 위에 사운드 센서에 관련해서 설명했던 파트에 나와있는 사진에서처럼

GND에는 아두이노의 GND혹은 브레드보드에서 GND를 연걸한 부분, OUT은 각자가 설정한

신호를 전송해줄 포트, VCC에는 전압을 공급 받을 부분에 연걸하면 된다.



5. 완성된 작품

 

1. 밑부분 달기 전 예비 완성작                                   2. 예비 완성작 내부 모습

3. 밑단 부착후 완성작 모습  


 5. 최종 사용 코드

총 16개의 핀을 shift register를 사용하지 않아도 조절 할 수 있도록 for문을 사용했다. 사용중인 아두이노의 0~7까지의 디지털핀은 스캔라인으로 사용되었고 디지털핀 8~13 아날로그핀 0,1핀은 데이터핀으로 사용되었다. 데이터핀은 레지스터로 보면 포트가 PORTB와 PORTC로 나누어져 있기 때문에 데이터를 각 레지스터로 나누어준다.

PORTB=(data[scan]&0x3F);

PORTC=data[scan]>>6;

데이터 하위 6비트를 취해서 PORTB에 넣어 주고 데이터의 상위 2비트를 PORTC에 넣어주기 위해 시프트 연산을 한다. scan_line[]은 스캔라인을 한열씩 선택하기 위해 배열로 만들어 놓은 것이다. scan line[scan]에서 scan이 0부터 7까지 증가하면서 한라인씩 선택해서 한열 씩 차례로 HIGH(신호가 들어오는 상태)가 된다.