2016년 10월 6일 목요일

아두니티에서 사용 가능한 하드웨어

ArdunityApp (Arduino Board)
거의 모든 시리즈의 아두이노 보드를 사용할 수 있습니다. (호환 보드 포함)
본 블로그의 모든 글은 Arduino Uno를 기준으로 쓰여졌습니다.
아두니티에서는 Arduino Board 복수 개 동시 제어가 가능합니다.
  • Arduino Uno
  • Arduino Nano
  • Arduino Mega
  • Arduino Reonardo
  • Arduino Zero (ADC, PWM Resolution 선택 가능)
  • Arduino Due (ADC, PWM Resolution 선택 가능)
  • Arduino 101
  • Arduino Yun
  • Intel Edison


DigitalOutput
아두이노 보드의 Digital Pin을 OUTPUT 모드로 하여 제어가 가능한 모든 하드웨어


DigitalInput
아두이노 보드의 Digital Pin을 INPUT(or INPUT_PULLUP) 모드로 하여 제어가 가능한 모든 하드웨어

AnalogOutput
아두이노 보드의 PWM Pin으로 제어가 가능한 모든 하드웨어


AnalogInput
아두이노 보드의 ADC Pin으로 제어가 가능한 모든 하드웨어


PulseOutput
아두이노 보드의 Digital Pin으로 정확한 주기의 Pulse를 내보내야 하는 하드웨어
  • 카메라 플래시 제어


GenericServo
아두이노 Servo라이브러리로 제어 가능한 표준 PWM제어 방식을 사용하는 모든 서보 모터


GenericTone
아두이노 Tone라이브러리로 제어 가능한 Buzzer
RTTTL을 이용한 멜로디 연주가 가능합니다.

GenericMotor (ARDUnity Deluxe Only)
H-bridge 회로 기반으로 제어되는 모든 DC 모터 드라이버
DC 모터의 양 방향, 속도 제어가 가능합니다.
GenericStepper (ARDUnity Deluxe Only)
스테핑 모터 제어
WAVE(1상 여자), FULL STEP(2상 여자), HALF STEP(1-2상 여자)방식 제어 지원
속도 제어 모드, 각도 제어 모드 선택 가능
  • ULN2003A and 28BYJ-48


MPUSeries (ARDUnity Deluxe Only)
Invensense사에서 만든 IMU 센서 보드 제어
동시 2개 센서 제어를 지원합니다. (3개 이상 동시 제어는 아직 미 지원)


CommSerial
Windows/Mac에서 시리얼 포트를 사용하여 아두이노 보드와 통신할 수 있습니다.
Bluetooth SPP의 경우 Windows/Mac에서 시리얼 포트로 잡히기 때문에 사용 가능합니다.

CommBluetooth (ARDUnity Deluxe Only)
Android에서 Bluetooth SPP를 사용하여 아두이노 보드와 통신할 수 있습니다.

HM-10 (ARDUnity Deluxe Only)
Android/iOS에서 HM-10 모듈을 이용해서 사용하여 아두이노 보드와 Bluetooth LE 통신을 할 수 있습니다.


CommWifi (ARDUnity Deluxe Only)
모든 플랫폼에서 아두이노 보드와 TCP 연결을 할 수 있습니다.
아두이노 보드가 TCP Server, 유니티가 TCP Client가 됩니다.


DeviceRollReactor (ARDUnity Deluxe Only)
스마트 폰의 지면에 대한 기울기를 알려줍니다.
RC카의 조종 인터페이스로 활용 가능합니다.


DeviceRotationReactor (ARDUnity Deluxe Only)
스마트 폰의 후면 카메라 방향에 대한 기울기를 알려줍니다.
AR관련 어플리케이션 개발에 활용 가능합니다.


DeviceCamera (ARDUnity Deluxe Only)
PC 및 스마트 폰의 카메라 영상을 사용할 수 있습니다.
스마트 폰의 경우 전/후면 카메라 선택이 가능합니다.


2016년 10월 3일 월요일

CommWifi

CommWifi를 사용하면 아두이노 보드와 인터넷 통신을 할 수 있습니다.


인터넷 통신이란 말은 너무 폭넓은 의미이기에 조금 구체화할 필요가 있습니다.
인터넷은 전 세계적으로 모든 컴퓨터가 연결된 개념을 의미합니다.
인터넷은 모든 컴퓨터가 연결됨을 의미한다.

이런 통신이 가능하려면 모든 컴퓨터는 자신을 구별하기 위해 고유한 식별자를 가져야 하는데, 이것을 IP 어드레스라고 부릅니다. 이 IP 주소 체계에 따라 IPv4, IPv6등으로 전문적인 용어가 사용됩니다.
또한, 컴퓨터에서 실행되는 프로그램을 구별해야 하기 때문에 포트(Port)라 부르는 통신 채널 번호가 존재합니다.
다시 정리하면 인터넷 통신을 하기 위해서는 다음 2가지가 있어야 한다는 의미입니다.
  • IP Address
  • Port
인터넷을 하기 위한 식별 정보는 아무나 할 수 없고 반드시 정식 서비스로 등록되어야만 전 세계 컴퓨터와 연결될 수 있습니다. 이것을 도메인(Domain)이라 부르고, 도메인 서비스 업체를 통해 일정한 비용을 지불하고 얻게됩니다.
이 도메인은 사람이 이해하기 쉽도록 www.mydomain.com 등의 형식으로 사용되지만, 내부적으로는 IP Address와 Port를 사용해서 통신하는 것입니다.

인터넷 통신을 이해하기 위한 중요한 개념은 프로토콜(Protocol)입니다. 앞에서 언급한 IP와 Port는 식별 정보이고 실제로 컴퓨터간에 데이터를 어떤 방법으로 주고받을 것인지를 정하는 것이 프로토콜입니다.
현재 인터넷상에서 규격화되어 널리 사용되는 프로토콜은 대략 다음과 같습니다.
  • TCP
  • UDP
  • HTTP
  • FTP
위에서 언급한 프로토콜 외에도 더 많은 종류가 있으며 새로운 프로토콜이 개발되고 있습니다.
따라서, 여러분이 만든 장치(아두이노)를 인터넷에 연결하려면 다음에 대해 생각해야 합니다.
  • 어떻게 고유한 IP와 Port를 얻을 것인가?
  • 무슨 프로토콜을 사용할 것인가?
이와 같이 인터넷 통신은 생각해야 할 문제가 많은 복잡한 작업입니다.

하지만, 다행히 집에서 혼자 테스트하는 정도라면 간단하게 해볼 수 있는 방법이 많이 나와있습니다.
우선, 집집마다 사용하는 유/무선 공유기는 자신에게 연결된 장치들의 IP 주소를 관리해줍니다. DHCP라고 부르는 기능은 유/무선 공유기가 자동으로 IP를 할당하여 관리하는 편리한 기능입니다.
유/무선 공유기는 IP를 관리해준다.

따라서, 여러분은 직접 IP를 정하거나 유/무선 공유기가 DHCP 기능으로 인해 자동 할당된 IP를 알아냄으로써 쉽게 IP를 정할 수 있습니다.
포트 번호는 다른 프로그램과 겹치지 않도록 고유 번호를 사용하면 됩니다.

다음으로 할 일은 프로토콜 선택입니다.
CommWifi는 TCP만 지원하기에 아두이노와 통신하기 위해서는 반드시 TCP 프로토콜이 가능해야 합니다.
TCP 프로토콜은 Server와 Client로 역할이 나뉩니다.
  • TCP Server: TCP Client 연결을 기다리며 접속 요청을 처리합니다.
  • TCP Client: TCP Server에 접속 요청을 하여 연결합니다.
아두이노는 TCP Server가 되어야 하고, 유니티는 TCP Client가 되어야 합니다.
이와 같은 이유로 CommWifi에서 Inspector 설정 정보는 다음과 같습니다.
  • IP Address: TCP Server의 IP 주소
  • Port: TCP Server와 통신할 포트 번호
  • OnOpen: TCP Server와 통신 연결되었을 때
  • OnClose: TCP Server와 통신 연결이 해제되었을 때
  • OnOpenFailed: TCP Server와 통신 연결 시도가 실패했을 때
  • OnErrorClosed: TCP Server와 통신 연결이 강제로 해제되었을 때
CommWifi는 ArdunityApp에 연결되어 아두이노 보드의 하드웨어를 제어할 수 있습니다.

WiFi 통신은 PC나 스마트 기기에서 모두 가능하기에 CommWifi는 Windows/Mac/Android/iOS에서 모두 가능합니다.
다만, 앞에서 언급했듯이 아두이노 보드가 도메인이 없는 관계로 유/무선 공유기를 통해서만 통신 테스트를 해야합니다.
반드시 유/무선 공유기에 연결하여 테스트해야 한다.

이제 인터넷 통신을 위한 아두이노 장치에 대해 알아보겠습니다.
아두이노를 위한 수 많은 인터넷 통신이 가능한 모듈들이 있지만, CommWifi를 사용하려면 반드시 TCP Server가 가능한 부품을 사용해야 합니다.
아두니티 예제에서 테스트된 부품은 다음의 2종류입니다.
아두이노 윤(Yun) 보드

DFRobot사의 Wifi Shield

안타깝지만, 아두이노에서 많이 언급되는 ESP8266은 CommWifi와 통신할 수 없습니다. 향후, ESP8266도 가능하도록 업데이트할 예정입니다.
ESP8266은 아직 지원하지 않습니다.

아두이노 Yun과 DFRobot의 Wifi Shield는 모두 TCP Server로 작동시킬 수 있습니다.
다만, 아두이노 Yun과 DFRobot의 Wifi Shield는 아두이노 스케치가 다르기때문에 이에 맞는 설정이 필요합니다.
아두이노 Yun은 인터넷 통신을 위한 칩과 아두이노 Uno 보드가 합쳐져있습니다. 아두이노 Yun에서는 인터넷 통신을 위해 UART를 사용할 수 없고, Bridge라고 부르는 라이브러리를 사용하여 SPI통신을 해야 합니다.
즉, 아두이노 Yun과 CommWifi가 통신하려면 ArdunityApp에서 Stream Class를 Bridge로 선택해야 합니다.


DFRobot의 Wifi Shield는 아두이노 보드와 인터넷 통신 칩이 UART로 연결되어 있습니다. 따라서, 아두이노 스케치에서 기존과 동일하게 Serial Stream Class로 통신할 수 있습니다.

아두이노 Yun과 DFRobot의 Wifi Shield를 유/무선 공유기에 연결하거나 IP와 Port를 알아내는 방법은 각자의 매뉴얼을 참고하시기 바랍니다.


아두이노에서 HC-06 다루기

HC-06은 Bluetooth SPP 통신을 위한 장치입니다.
HC-06

HC-06의 Pin은 다음과 같이 구성되어 있습니다.
  • VCC: 전원(+) 핀
  • GND: 접지(-) 핀
  • TX: 데이터 송신 핀
  • RX: 데이터 수신 핀
주의할 점은 HC-06은 2가지 타입이 있는데, 데이터 송수신 핀의 전압에 따라 3.3V와 5V 타입으로 나뉩니다. 자신이 갖고 있는 HC-06 모듈이 어떤 타입인지 잘 알고 있어야 합니다.
HC-06 3.3V 타입

HC-06 5V 타입

아두이노 Uno는 5V로 부품을 제어 하기때문에 HC-06 5V 타입은 그대로 연결해도 되지만, HC-06 3.3v 타입은 전압을 맞춰줘야만 사용할 수 있습니다.
3.3v 전압을 맞추기 위해서 사용하는 회로는 전압 분배(Voltage Divider) 회로입니다.
전압 분배 회로

R1과 R2의 크기를 1:2 비율로 맞춘다면 공식에 의해 5 * (2/3) = 3.33의 계산이 이루어집니다. 따라서, HC-06 3.3v 타입은 전압 분배 회로와 같이 사용해야 합니다.

아두이노 보드는 외부 장치와 통신할 수 있는 UART를 1개만 보유하고 있습니다. 이것은 USB에 연결되어 있어서 PC와 통신할때 사용합니다.
만약, HC-06을 UART에 연결하면 USB통신을 할 수 없습니다.
따라서, HC-06을 연결하여 USB 통신을 포기하던가 아니면 HC-06과의 연결을 선택할 수 있도록 만들어서 USB와 HC-06을 번갈아 사용해야 합니다.

아두이노에는 UART가 부족할 때, UART 기능을 만들 수 있는 유용한 라이브러리가 있습니다.
이것의 이름은 SoftwareSerial이며 이것을 사용하면 UART를 추가할 수 있습니다.
많은 아두이노 HC-06 예제를 보면 SoftwareSerial을 이용해서 통신을 하는 것을 볼 수 있습니다.
실제 UART를 이용한 통신 소스와 SoftwareSerial을 이용한 통신 소스를 비교해보면 그 사용법이 유사한 것을 알 수 있습니다.

<실제 UART 통신 소스>
void setup()
{
    Serial.begin(9600);
}

void loop()
{
    if(Serial.available() > 0)
    {
        char data = Serial.read();
        Serial.write(data);
    }
}


<SoftwareSerial 통신 소스>
#include<SoftwareSerial.h>

SoftwareSerial softSerial(10, 11);

void setup()
{
    softSerial.begin(9600);
}

void loop()
{
    if(softSerial.available() > 0)
    {
        char data = softSerial.read();
        softSerial.write(data);
    }
}

차이점은 Serial과 달리 SoftwareSerial은 TX, RX에 대한 핀 번호가 필요하다는 것입니다. 그 이유는 UART를 사용하는 Serial은 TX, RX 핀 번호가 고정되어 있지만, SoftwareSerial은 아무 핀이나 사용할 수 있기때문에 여러분이 정해줘야 한다는 것입니다.
이 이유로 SoftwareSerial을 통한 HC-06의 아두이노 연결 회로는 다음과 같습니다.
HC-06 3.3v 타입 연결

HC-06 5v 타입 연결

아두이노 보드와 HC-06이 시리얼 통신을 하기 위해서 가장 중요한 것은 통신 속도를 맞추는 것입니다. 시리얼 통신에서 통신 속도는 보레이트(Baudrate)라고 부르며, 아무 숫자나 사용하는 것이 아니고 규격이 정해져있습니다.
  • 4800bps
  • 9600bps
  • 19200bps
  • 38400bps
  • 57600bps
  • 115200bps
이 중에 골라서 사용해야 하는데, 값이 클수록 고속 통신이기에 주고받을 수 있는 데이터 양이 많아집니다. 문제는 아두이노 보드에서 보레이트는 스케치 작성을 통해 설정할 수 있지만, HC-06은 그렇지 못하다는 것입니다.
HC-06의 보레이트를 변경하기 위해서는 다른 방법을 사용해야 합니다.
HC-06은 통신에 필요한 설정을 위해 AT Command라는 방식을 사용합니다.
이것은 HC-06의 TX, RX선을 사용해서 AT+데이터라는 특별한 형식으로 정보를 보내주면 필요한 설정을 할 수 있는 방식입니다.
AT Command 사용 방법은 인터넷을 통해 쉽게 찾을 수 있는데, 여기서는 자주 사용하는 몇 가지만 소개하겠습니다.
AT CommnadResponseFunction
ATOKHC-06이 연결되었는지 확인
AT+NAMEOOOOKsetname블루투스 장치 검색 시 나타나는 이름 설정
AT+BAUD4OK9600보레이트를 9600bps로 설정
AT+BAUD5OK19200보레이트를 19200bps로 설정
AT+BAUD6OK38400보레이트를 38400bps로 설정
AT+BAUD7OK57600보레이트를 57600bps로 설정
AT+BAUD8OK115200보레이트를 115200bps로 설정

이 명령어를 HC-06에 전달하는 방법은 2가지 입니다.
  • 아두이노 스케치 코드로 전달한다.
  • 아두이노 시리얼 모니터를 이용해서 전달한다.

아두이노 스케치 코드로 전달하는 예는 아래와 같습니다.


void setup()
{
    Serial.begin(9600);
    Serial.write("AT+NAMEmyHC-06"); // Change name to "myHC-06"
}

아두이노 시리얼 모니터는 아두이노 UART를 통해 사용자와 정보를 주고받을 수 있는 유틸리티이며 Arduino IDE에 포함되어있습니다.
시리얼 모니터를 통해 아두이노 보드 상태를 알 수 있다.

시리얼 모니터를 통해 AT Command를 전달하려면 아두이노 스케치가 중간에서 역할을 해줘야 합니다.
다음 스케치 소스는 시리얼 모니터를 통해 HC-06에 AT Command를 전달할 수 있게 해줍니다.

#include<SoftwareSerial.h>

SoftwareSerial softSerial(10, 11);

void setup()
{
    Serial.begin(9600);
    softSerial.begin(9600);
}

void loop()
{
    while(Serial.available() > 0)
    {
        char command = Serial.read();
        softSerial.write(command);
    }

    while(softSerial.available() > 0)
    {
        char response = softSerial.read();
        Serial.write(response);
    }
}


마지막으로 다룰 내용은 고속 통신 방법에 관한 것입니다.
HC-06은 115200bps까지 통신 속도를 올릴 수 있습니다. 물론, 이 통신 속도는 앞에서 언급한 AT Command를 이용해서 설정해야 합니다.
앞에서는 SoftwareSerial을 이용해서 아두이노 보드와 HC-06이 통신하는 방법을 설명했는데, SoftwareSerial은 높은 보레이트에서 안정적이지 않아서 통신이 잘 되지 않습니다. 알려진바로는 9600bps 이상을 넘어가면 통신이 되지 않는다고 합니다.
따라서, SoftwareSerial을 사용할 때는 9600bps로 설정할 것을 권장드립니다.
만약, 그 이상의 보레이트를 원하는 경우는 UART에 연결해서 사용해야 합니다.
하지만, HC-06 3.3v 타입의 경우는 전압 분배 회로를 사용한다해도 UART 연결 시 통신이 잘 되지 않을 수 있습니다.
그 이유는 고속 통신 시에는 정보 손실을 최소화하기 위한 부가 회로들이 필요한데, 전압 분배 회로만으로는 해결되지 않기 때문입니다.
이 문제는 아주 전문적인 내용이기때문에 아두이노에서 해결하는 것은 맞지 않습니다.
따라서, 되도록이면 HC-06 5V 타입을 사용할 것을 권장합니다.



CommBluetooth

아두니티에서 블루투스 통신을 하려면 CommBluetooth를 사용해야 합니다.


CommBluetooth는 Bluetooth SPP 통신을 의미하고 안드로이드에서만 사용할 수 있습니다.
PC에서 블루투스 통신을 할 때는 CommBluetooth가 아닌 CommSerial을 사용해야 합니다. 그 이유는 Windows/Mac에서는 Bluetooth SPP가 시리얼 포트를 통해 이루어지기 때문입니다.
CommBluetooth가 iOS를 지원하지 않는 이유는 Bluetooth SPP의 경우 Apple에 별도 인증을 받은 모듈만 가능하기 때문입니다.
즉, 일반 블루투스 장치를 통해 Bluetooth SPP 통신을 하려면 안드로이드에서만 가능합니다.
CommBluetooth의 Inspector 설정은 다음과 같습니다.
  • searchTimeout: 블루투스 장치 검색 시간
  • OnOpen: 블루투스 장치가 연결되었을 때
  • OnClose: 블루투스 장치 연결이 해제되었을 때
  • OnOpenFailed: 블루투스 장치 연결을 실패했을 때
  • OnErrorClosed: 블루트스 장치 연결이 강제로 해제되었을 때
  • OnStartSearch: 블루투스 장치 검색이 시작되었을 때
  • OnStopSearch: 블루투스 장치 검색이 종료되었을 때
CommBluetooth를 사용하려면 ArdunityApp과 연결되어야 합니다.

유니티 에디터에서는 CommBluetooth를 테스트할 수 없는데, 그 이유는 실제 안드로이드 기기에서만 작동되기 때문입니다.
따라서, 회로 작동 제어를 테스트할 때는 CommSerial을 사용하고 안드로이드 기기에서 테스트할 때만 CommBluetooth를 연결하여 사용할 것을 추천합니다.
유니티 에디터에서 테스트할 때는 각 컴포넌트의 Inspector 메뉴를 사용할 수 있었지만, 빌드가 된 이후에는 오직 GUI로만 테스트해야 합니다.
유니티 에디터에서는 Inspector 메뉴를 이용해 테스트할 수 있다.

유니티 빌드 후에는 GUI가 있어야 테스트할 수 있다.

이 말은 CommBluetooth를 사용하기 위해서는 먼저 유니티 UI로 사용자가 조작할 수 있는 GUI를 만들어줘야 한다는 의미입니다.
아두니티에는 CommBluetooth 테스트를 위해 예제를 제공하고 있습니다.
(ARDUnity/Examples/ConnectionUI/BluetoothConnection)
이 예제를 사용하면 CommBluetooth를 위한 GUI를 쉽게 구현할 수 있습니다.
기본으로 Connect/Quit 버튼이 생깁니다.

블루투스 장치 검색 및 선택을 위한 UI가 있습니다.

이제 남은 것은 유니티에서 안드로이드 빌드를 해서 APK파일을 만드는 것입니다.
유니티에서 안드로이드 빌드 절차는 "유니티 안드로이드 빌드" 글을 참고하시기 바랍니다.
그냥 안드로이드 빌드를 하면 블루투스 장치가 검색되지 않는 문제를 겪게 될 것입니다.
이 문제가 발생하는 이유는 한 가지를 빼먹었기 때문인데, 바로 AndroidManifest.xml을 수정하지 않았기 때문입니다.

모든 안드로이드 앱은 AndroidManifest.xml을 갖고 있으며 이 파일에는 앱 관리 및 실행에 필요한 모든 정보가 기입되어 있습니다.
AndroidManifest.xml 파일의 내용 예

여러분이 이 파일을 직접 작성하는 것이 아니고 Android Studio와 같은 안드로이드 앱 개발 도구가 자동으로 만들어줍니다.
유니티도 마찬가지로 AndroidManifest.xml 파일을 자동으로 만들어주기때문에 여러분들이 신경쓸 필요가 없었습니다.
문제는 유니티가 제공해주지 않는 기능을 사용할 때는 여러분이 직접 AndroidManifest.xml을 수정해야 한다는 것입니다.
블루투스 통신은 유니티가 제공하지 않는 기능입니다. 안드로이드 블루투스와 유니티가 서로 연결되도록 하는 것은 아두니티의 역할입니다.
그러나, 여러분이 만든 앱의 실행 권한은 여러분이 직접 AndroidManifest.xml에 기입해줘야 합니다.
작성할 주 내용은 다음과 같습니다.
  • 본 앱은 블루투스 장치를 사용합니다.
    <uses-permission android:name="android.permission.BLUETOOTH"/>
  • 본 앱은 블루투스 장치 관리자 권한이 필요합니다.
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
  • 본 앱이 실행하는 기기에는 블루투스 장치가 내장되어야 합니다.
    <uses-feature android:name="android.hardware.bluetooth" android:required="true"/>
위와 같은 내용을 AndroidManifest.xml에 삽입해야 블루투스 장치를 검색하고 테스트할 수 있습니다.

아두니티는 이런 번거로움을 최소화하기 위해 미리 수정된 AndroidManifest.xml 파일을 제공합니다. 따라서, 여러분은 이 파일을 사용하면 AndroidManifest.xml파일을 찾거나 수정하는 번거로움없이 블루투스 통신을 성공할 수 있습니다.
먼저, 아두니티 에셋에서 AndroidManifest.xml파일을 찾습니다.
(ARDUnity/Plugins/Android/AndroidManifest.xml)
그 다음으로 Project Window에서 Plugins/Android 폴더를 만듭니다.
이 에셋 폴더를 만드는 이유는 유니티가 수정된 AndroidManifest.xml를 Plugins/Android 폴더에서 찾기 때문입니다.
마지막으로 아두니티 에셋에 있는 AndroidManifest.xml 파일을 복사하여 앞에서 만든 Plugins/Android 폴더에 넣습니다.

이 과정을 마친 다음 다시 유니티에서 안드로이드 빌드를 한 후 스마트 기기에서 앱을 실행하면 블루투스 장치가 검색되는 것을 확인할 수 있습니다.

만약, 다른 에셋이 이미 수정된 AndroidManifest.xml을 사용하고 있어서 아두니티 에셋의 AndroidManifest.xml파일을 복사할 수 없는 경우는 앞에서 언급한 내용을 직접 이미 사용 중인 AndroidManifest.xml에 삽입하면 됩니다.

버저(Buzzer) 다루기

버저(Buzzer)는 소리를 낼 수 있는 대표적인 부품입니다.

버저의 원리는 얇은 전극판을 전기적 신호로 떨리게 만들어서 소리를 내는 것입니다. 여기서 소리를 내는 전기적 신호는 진동수(Frequency)를 의미하며 Digital 신호로 이 효과를 만들어 냅니다.
버저를 제어하는 아두이노 회로도는 다음과 같습니다.

이 회로에서 쓰는 저항의 역할은 소리 볼륨(Volume)을 조절하는 것입니다. 저항의 크기가 클수록 소리 크기가 작아지고 저항의 크기가 작을수록 소리 크기는 커집니다.
이 회로를 유니티에서 다룰려면 아두니티 Wire Editor에서 다음과 같이 연결합니다.

아두이노 스케치를 Export하고 Upload하면 유니티에서 버저를 제어할 준비가 끝납니다.
아두이노 보드를 연결한 후, GenericTone의 ToneFrequency를 변경하면 버저에서 소리가 납니다.



전자 피아노 만들기
유니티의 UI Button으로 버저 음계를 선택하도록 한다면 전자 피아노를 쉽게 만들 수 있습니다.
우선, 음계를 제어할 UI Button을 만듭니다.

각 버튼이 눌릴때마다 GenericTone의 ToneFrequency를 변경하면 됩니다.
ButtonReactor를 사용하면 버튼의 눌림 상태를 알아낼 수 있습니다.

그러나, ButtonReactor는 ToneFrequency 값을 바꿀 수는 없기에 이 역할을 할 기능이 필요합니다.
ToneOutput은 지정한 ToneFrequency 값을 GenericTone에게 전달할 수 있는 기능을 갖고 있습니다.



ToneOutput에 필요한 ToneFrequency를 선택하고 GenericTone에 연결하면 됩니다.



전자 기타 소리 내기
ToneFrequency를 사용하면 버저의 음계를 쉽게 잡을 수 있습니다. 그러나, 음계간의 부드러운 소리 연결이나 바이브레이션(Vibration)등의 소리 효과는 내기가 어렵습니다.
CurveOutput을 이용하면 쉽게 이런 효과를 낼 수 있습니다.


CurveOutput의 Start/Loop/End Curve를 아래와 같이 만들어주면 마치 전자 기타 소리같은 효과를 낼 수 있습니다.

CurveOutput과 ToneOutput을 결합하면 ToneFrequency값이 Curve형태로 전달됩니다.



RTTTL Song
버저를 활용할 때 빠질 수 없는 것은 멜로디 연주입니다. 음악은 악보로 표현되고 이 악보를 컴퓨터로 표현하려면 아주 많은 노력이 필요합니다.
악보에는 음악 표현에 필요한 정보가 포함되어 있다.

일반적으로 음악을 표현하려면 다음과 같은 정보가 필요합니다.
  • 음의 순서
  • 연주 속도
  • 음의 길이
  • 음의 높낮이
따라서, 이와 같은 모든 정보를 코드로 표현하려면 프로그램이 매우 복잡해집니다. 더 큰 문제는 곡마다 이 정보가 다르므로 매번 다르게 만들어야 한다는 것입니다.
RTTTL(Ring Tone Text Transfer Language)는 핸드폰 벨소리를 표현하기 위해 노키아(Nokia)에서 제정한 멜로디 표현에 대한 표준 규격입니다. (위키피디아에서 RTTTL에 대해 알아보기)
RTTTL을 이용하면 멜로디 연주를 아주 쉽게 할 수 있습니다.
RTTTL Song은 인터넷에서 쉽게 구할 수 있고, 그 문법이 간단하기 때문에 자신이 직접 음악을 만들 수도 있습니다.



  • songAsset: RTTTL Song이 기입된 Text 파일

아두니티 에셋에 포함된 SampleSong을 선택하고 유니티를 Play하면 SampleSong에 포함된 멜로디 목록을 선택하고 연주할 수 있습니다.

GenericTone과 다음과 같이 연결하면 RTTTL Song이 연주됩니다.


지금까지 버저 활용을 동영상으로 확인하기 바랍니다.




2016년 10월 2일 일요일

GenericTone

GenericTone은 아두이노의 Tone라이브러리를 사용하기 위한 Controller입니다.
Tone라이브러리는 Buzzer와 같은 소리를 내는 부품을 제어할 때 사용합니다.
소리는 물체의 진동으로 인해 발생되기 때문에 컴퓨터가 소리를 내려면 진동을 만들어야 합니다.
컴퓨터의 소리 출력 장치로 사용되는 스피커는 작은 진동도 효과적으로 전달할 수 있는 구조를 갖고 있습니다.
컴퓨터의 소리 전달 장치인 스피커

아주 단순하면서 값싼 스피커는 피에조 부저(Piezo Buzzer)입니다. 얇은 전극판으로 이루어져서 전기적 신호의 변화로 떨림을 만들어낼 수 있는 부품입니다.
피에조 부저(Piezo Buzzer)

소리는 신호로 표현할 수 있는데 이때 사용하는 것이 진폭(Amplitude)와 진동수(Frequency)입니다.
  • 진폭(Amplitude): 소리의 크기를 표현
  • 진동수(Frequency): 소리의 높낮이를 표현
진폭의 개념

진동수의 개념

현실 세계에서는 여러 종류의 진폭과 진동수가 섞여서 전달되므로 아래와 같은 그림이 될 것입니다.
현실에서의 소리 파형 모습

아두이노 Tone 라이브러리는 멜로디 소리를 낼 수 있도록 음계(Musical Scale)에 해당되는 진동수를 쉽게 만들어 줍니다.
도, 레, 미, 파 등의 음계는 모두 고유한 진동수를 갖고 있기때문에 피에조 부저에 전기 신호를 이와 같이 만들어주면 멜로디 소리를 만들 수 있습니다.
GenericTone은 이와같은 음계 진동수를 제어할 때 사용합니다.


GenericTone을 설정하려면 다음의 정보가 필요합니다.
  • id: ArdunityApp이 ArdunityController를 구분하기 위한 식별자
  • pin: 음계 진동수를 만들어낼 핀 번호
  • Tone Frequency: 음계 진동수
  • Mute: 소리내는 것을 멈춤
GenericTone에서는 음계 진동수를 쉽게 선택할 수 있도록 각 진동수에 이름을 붙였습니다.

이 이름 규칙을 이해하려면 먼저 국제적으로 음계를 어떻게 표기하고 있는지 알아야 합니다. 우리는 도, 레, 미, 파 등으로 부르지만 국제적으로는 C, D, E, F 등으로 표기됩니다.
음계 표기 방법

반음 올림 표시인 #은 Sharp의 약자로 S만 표기하고, 제일 뒤의 숫자는 옥타브(Octave)를 뜻합니다. 따라서 DS3은 3 옥타브 D#이라는 뜻입니다.

아두니티에서 피에조 버저를 제어하기 위한 연결은 Wire Editor에서 다음과 같이 표현됩니다.

위 정보를 아두이노 스케치로 Export한 후 Upload하면 제어할 준비가 완료됩니다.

GenericTone에서 사용하는 ToneFrequency는 Enum으로 다음과 같이 정의되어 있습니다. 각 숫자는 실제 진동수인 Hz를 의미합니다.

using UnityEngine;
public enum ToneFrequency
{
 MUTE = 0,
 B0 = 31,
 C1  = 33,
 CS1 = 35,
 D1  = 37,
 DS1 = 39,
 E1  = 41,
 F1  = 44,
 FS1 = 46,
 G1  = 49,
 GS1 = 52,
 A1  = 55,
 AS1 = 58,
 B1  = 62,
 C2  = 65,
 CS2 = 69,
 D2  = 73,
 DS2 = 78,
 E2  = 82,
 F2  = 87,
 FS2 = 93,
 G2  = 98,
 GS2 = 104,
 A2  = 110,
 AS2 = 117,
 B2  = 123,
 C3  = 131,
 CS3 = 139,
 D3  = 147,
 DS3 = 156,
 E3  = 165,
 F3  = 175,
 FS3 = 185,
 G3  = 196,
 GS3 = 208,
 A3  = 220,
 AS3 = 233,
 B3  = 247,
 C4  = 262,
 CS4 = 277,
 D4  = 294,
 DS4 = 311,
 E4  = 330,
 F4  = 349,
 FS4 = 370,
 G4  = 392,
 GS4 = 415,
 A4  = 440,
 AS4 = 466,
 B4  = 494,
 C5  = 523,
 CS5 = 554,
 D5  = 587,
 DS5 = 622,
 E5  = 659,
 F5  = 698,
 FS5 = 740,
 G5  = 784,
 GS5 = 831,
 A5  = 880,
 AS5 = 932,
 B5  = 988,
 C6  = 1047,
 CS6 = 1109,
 D6  = 1175,
 DS6 = 1245,
 E6  = 1319,
 F6  = 1397,
 FS6 = 1480,
 G6  = 1568,
 GS6 = 1661,
 A6  = 1760,
 AS6 = 1865,
 B6  = 1976,
 C7  = 2093,
 CS7 = 2217,
 D7  = 2349,
 DS7 = 2489,
 E7  = 2637,
 F7  = 2794,
 FS7 = 2960,
 G7  = 3136,
 GS7 = 3322,
 A7  = 3520,
 AS7 = 3729,
 B7  = 3951,
 C8  = 4186,
 CS8 = 4435,
 D8  = 4699,
 DS8 = 4978
}

다음 예제는 아두이노 보드가 연결되면 1초에 한번씩 도, 레, 미, 파, 솔, 라, 시, 도를 연주합니다.

using UnityEngine;
using System.Collections;
using Ardunity;

public class MyComponent : MonoBehaviour
{
 public GenericTone genericTone;

 private float _time = 0f;
 private int _musicalScale = 0;
 
 void Update ()
 {
  if(genericTone.connected)
  {
   _time += Time.deltaTime;
   if(_time >= 1f)  // per 1 second
   {
    _time = 0f;

    switch(_musicalScale)
    {
     case 0:
      genericTone.toneFrequency = ToneFrequency.C3;
      break;

     case 1:
      genericTone.toneFrequency = ToneFrequency.D3;
      break;

     case 2:
      genericTone.toneFrequency = ToneFrequency.E3;
      break;

     case 3:
      genericTone.toneFrequency = ToneFrequency.F3;
      break;

     case 4:
      genericTone.toneFrequency = ToneFrequency.G3;
      break;

     case 5:
      genericTone.toneFrequency = ToneFrequency.A3;
      break;

     case 6:
      genericTone.toneFrequency = ToneFrequency.B3;
      break;

     case 7:
      genericTone.toneFrequency = ToneFrequency.C4;
      break;
   }

   _musicalScale++; // Increase Musical Scale
   if(_musicalScale > 7)
    _musicalScale = 0;
  }  
 }
}