이 양자화를 하기 위한 단계의 수를 해상도(Resolution)라 부르는데, 컴퓨터에서는 2의 배수로 이것을 만들어갑니다. 아두이노에서 Analog 신호를 다루기 위한 Resolution은 다음 중 선택하게 됩니다.
- 8 bit = 2^8 = 256단계
- 10 bit = 2^10 = 1024단계
- 12 bit = 2^12 = 4096단계
Resolution이 높을 수록 더 정밀하고 세밀한 제어가 가능하니 좋은 것이지만, 하드웨어 가격은 그 만큼 더 비싸지게 됩니다.
실제로 Analog신호를 컴퓨터에서 다룰 수 없기에 앞에서 말한 양자화란 단계를 거쳐서 숫자로 변환하게 됩니다. 이러한 역할을 하는 장치를 다음과 같이 부릅니다.
- DAC (Digital-Analog Converter): 숫자를 Analog 신호로 변환
- ADC (Analog-Digital Converter): Analog 신호를 숫자로 변환
아두니티의 AnalogOutput은 위에서 DAC를 제어하기 위한 ArdunityController입니다.
안타깝게도 아두이노 보드에는 DAC가 내장되어 있지 않습니다. 그러면 어떻게 Analog 신호 출력을 할 수 있느냐하면 바로 PWM 신호로 흉내를 냅니다.
PWM이란 Pulse Width Modulation의 약자로 Digital 신호로 Analog 신호를 흉내내는 대표적인 방법입니다.
위 그림과 같이 Digital 신호의 5V일때의 시간이 평균 전압에 영향을 주기때문에 마치 Analog 신호 출력같은 효과가 나오게 됩니다.
따라서, 아두이노에서는 실제로 DAC를 사용하는 것이 아니라 PWM으로 Analog 신호 출력을 하는 것이고, AnalogOutput은 PWM을 제어할 수 있는 ArdunityController가 됩니다.
이 PWM 신호는 아두이노의 아무 핀에서 만들어지는 것이 아니며, ~표시로 가능한 핀을 표기하고 있습니다. 아두이노 보드 종류에 따라 PWM 핀의 개수는 다릅니다.
PWM 신호도 앞에서 말한 Resolution이 존재하며 대부분의 아두이노 시리즈는 8bit 해상도 PWM을 사용합니다. 아두이노 Due와 Zero의 경우에는 10bit 혹은 12bit 해상도를 사용할 수 있으며 ArdunityApp에서 이를 설정할 수 있습니다.
AnalogOutput의 Sketch Option을 설정 항목은 다음과 같습니다.
- id: ArdunityApp이 ArdunityController를 구분하기 위한 식별자
- pin: 아두이노 보드의 PWM 핀 번호
- defaultValue: 아두이노 보드 구동 시 기본 값
- resetOnStop: 유니티와 연결 해제 시 기본 값으로 되돌릴 지 여부
Analog값은 설정한 해상도와 무관하게 사용할 수 있도록 0 ~ 1 범위의 Normalize된 값을 사용합니다.
유니티에서 AnalogOutput을 테스트하기 위한 최소 구성은 다음과 같습니다.
설정이 완료되었다면 ArdunityApp의 Export Sketch를 통해 아두이노 스케치를 생성 한 후 아두이노 보드에 업로드합니다.
(스케치 업로드는 한번만 하면 되며 ArdunityController가 변경되거나 Sketch Option이 수정된다면 다시 업로드해야 합니다.)
유니티를 실행한 후, CommSerial의 포트 번호를 선택하고 ArdunityApp의 Connect를 실행하여 아두이노 보드를 연결하면 AnalogOutput을 제어할 수 있게됩니다. (아두니티 연결 방법 참고)
AnalogOutput은 Inspector View를 통해 핀 상태를 바꿀 수 있는 UI를 제공하므로 프로그래밍없이 바로 회로를 테스트할 수 있습니다.
정상적으로 회로가 제어된다면 모든 준비가 끝난 것입니다.
이제 남은 것은 유니티에서 AnalogOutput을 제어하는 것입니다.
C# Script에서 AnalogOutput의 Value를 변경할 수 있으며 코드는 다음과 같습니다.
(아래 예제는 매 프레임마다 Analog 신호를 변경합니다.)
using UnityEngine;
using System.Collections;
using Ardunity;
public class MyComponent : MonoBehaviour
{
public AnalogOutput analogOutput;
private bool _toggle = true;
private float _value = 0f;
void Update ()
{
if(_toggle == true)
{
_value += 0.01f;
if(value >= 1f)
{
_value = 1f;
_toggle = false;
}
}
else
{
_value -= 0.01f;
if(_value <= 0f)
{
_value = 0f;
_toggle = true;
}
}
analogOutput.Value = _value;
}
}