2016년 7월 30일 토요일

AnalogOutput

AnalogOutput은 아두이노 핀을 통해 Analog 신호를 출력 할 수 있도록 만든 ArdunityController입니다.


Analog 신호는 Digital 신호와 달리 0V ~ 5V사이의 모든 전압을 값으로 사용할 수 있습니다.

엄밀히 말하면 0V ~ 5V 사이의 모든 전압이 가능한 것은 아니고 양자화(Quantization)라 불리는 계단식으로 값을 끊어서 사용합니다.

이 양자화를 하기 위한 단계의 수를 해상도(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;
 }
}


2016년 7월 27일 수요일

DigitalInput 응용

DigitalInput의 대표적 응용 사례는 바로 Button 입력을 체크하는 것입니다.
Button 회로는 2가지로 꾸밀 수 있는데, Pull-up회로를 넣느냐 안 넣느냐로 나뉩니다.
(Pull-up 회로를 만들었기 때문에 DigitalInput의 Sketch Option 중 pullup을 체크하지 않습니다.)


(Pull-up 회로를 만들지 않았기 때문에 DigitalInput의 Sketch Option 중 pullup을 체크합니다.)

이 회로를 완성하고 아두이노 스케치를 업로드한다면 버튼의 입력을 유니티에서 사용할 수 있습니다.
유니티에서 버튼의 입력을 활용하는 방법을 몇 가지 소개하겠습니다.

Button으로 소리제어
AudioSourceReactor는 아두이노로 소리를 제어할 수 있는 컴포넌트입니다.


AudioSourceReactor를 추가하려면 해당 GameObject에 AudioSource가 반드시 추가되어있어야 합니다.
AudioSourceReactor는 프로그래밍없이 지정한 Audio Clip을 Play하거나 Volume을 조절하는 기능을 갖고 있습니다.
AudioSourceReactor와 DigitalInput을 다음과 같이 연결하면 Button을 누르면 소리가 Play되고 떼면 소리가 Stop됩니다.


Button으로 Light 제어
LightIntensityReactor를 사용하면 Button으로 Light의 Intensity를 제어할 수 있습니다.
LightIntensityReactor를 Button과 다음과 같이 연결하면 Button을 누르면 Light가 켜지고 떼면 Light가 꺼지게 됩니다.


Button입력으로 Trigger Event 발생시키기
Button은 누름과 뗌의 두가지 상태로 사용할 수 있지만, 때로는 어떤 이벤트를 발생시키는 용도로 사용해야 할 때도 있습니다.
Trigger Event란, TREU/FALSE가 아닌 오직 Active라는 한 가지 상태만 사용합니다. 즉, Trigger Event를 사용하면 Button을 눌러서 어떤 동작을 시킬 수 있습니다.
아두니티는 Bridge라 부르는 신호 변환 기능을 갖고 있습니다.

이 Bridge는 입력 신호용(Input)과 출력 신호용(Output)으로 나뉩니다.
우리가 사용할 Trigger Event는 입력 신호를 변환하는 것이므로 Input 메뉴에 있으며 TriggerInput이란 이름을 갖고 있습니다.


TriggerInput은 DigitalInput의 Value에 변화가 있을 때마다 Trigger Event를 발생시킵니다. 이 Value 변화의 기준을 정하는 것이 CheckEdge 항목이며 사용법은 다음과 같습니다.

  • Rising Edge: FALSE에서 TRUE로 변할 때
  • Falling Edge: TRUE에서 FALSE로 변할 때

이 TriggerInput과 DigitalInput을 다음과 같이 연결하면 Button 입력이 Trigger Event로 바뀝니다.
 


Trigger Event로 폭발 효과 발생
ExplosionReactor는 Trigger Event로 폭발 효과를 발생시켜서 주변의 물체를 날리는 기능을 갖고 있습니다.


ExplosionReactor는 다음과 같은 설정을 할 수 있습니다.

  • effectRadius: 폭발 효과가 미치는 범위
  • explosionForce: 폭발력
  • oneShotOnly: 한번만 실행할 지 여부
  • layerMask: 폭발 효과가 미칠 GameObject Layer
  • Use Gizmo: Scene에서 effectRadius를 위한 Editor 기능 사용 여부
(ExplosionReactor의 Gizmo 기능)
ExplosionReactor와 TriggerInput이 다음과 같이 연결되면 Trigger Event가 발생할 때마다 폭발 효과가 실행됩니다.


Trigger Event로 물체에 Force 적용하기
ForceReactor는 Rigidbody에 Force를 적용하는 기능을 갖고 있습니다.


ForceReactor를 사용하려면 다음과 같은 설정이 필요합니다.
  • rigidBody: Force를 적용할 RigidBody
  • position: Force를 적용할 위치 (설정한 GameObject의 Position)
  • direction: Force를 적용할 방향 (설정한 GameObject의 Forward 방향)
  • force: 힘의 크기
  • forceMode: 힘을 적용하는 방법 (참고 링크)
  • oneShotOnly: 한번만 실행할 지 여부
ForceReactor와 TriggerInput이 다음과 같이 연결되면 Trigger Event가 발생할 때마다 지정한 GameObject에 Force가 적용됩니다.



Button입력을 Toggle입력으로 바꾸기
Toggle이란, 변화가 일어날때마다 TRUE/FALSE를 바꾸는 방식을 의미합니다. Button은 누르면 TRUE, 떼면 FALSE인데, 만약, 누를때마다 상태가 바뀌어서 마치 스위치처럼 사용하려면 Toggle입력이 필요합니다.
ToggleInput은 DigitalInput의 변화가 있을때마다 TRUE/FALSE를 바뀌게 만들 수 있습니다.


ToggleInput을 사용하려면 CheckEdge라 부르는 변화의 기준을 설정해야 합니다.

  • Rising Edge: FALSE에서 TRUE로 바뀔 때 상태 변화
  • Falling Edge: TRUE에서 FALSE로 바뀔 때 상태 변화
DigitalInput의 값을 ToggleInput 값으로 변경하려면 다음과 같이 연결합니다.

ToggleInput을 LightIntensityReactor와 연결시키면 DigitalInput으로 Light 제어할 때와 달리 Button을 누를 때마다 Light Intensity가 바뀌는 것을 확인할 수 있습니다.



지금까지 소개한 활용 방법을 영상으로 확인하시기 바랍니다.


DigitalInput

DigitalInput은 아두이노 보드의 핀을 통해 Digital 입력을 다룰 수 있도록 만든 ArdunityController입니다.

유니티에서 DigitalInput을 테스트하기 위해서 필요한 최소 구성은 다음과 같습니다.

다음으로 할 일은 아두이노 스케치를 생성하고 업로드하는 것입니다.
이를 위해 DigitalInput의 Sketch Option을 설정해야 합니다.
  • id: ArdunityApp이 ArdunityController를 구분하기 위한 식별자
  • pin: Digital 입력을 받을 핀 번호
  • pullup: 내부 Pull-up 사용 여부
여기서 Pull-up이란 새로운 용어가 등장했기에 잠시 설명하고 넘어가겠습니다.
Digital 신호는 5V를 기준으로 0V는 0, 5V는 1로 인식합니다. 이러한 Digital 신호를 다른 말로 TTL(Transistor to Transistor Logic)이라고 부릅니다.
실제로, 0V 혹은 5V로 딱 떨어질 수 없으니 어느 정도 마진(Margin)을 두고 인식하게 됩니다.

만약, 전압이 마진 사이에 존재하게되면 0도 아니고 1도 아닌 애매한 값을 가지게되는데 이것을 Tri-State Level이라 부릅니다.
이것은 Digital 신호로 변환할 수 없기에 0과 1을 왔다갔다하는 이상한 값을 가지게 됩니다.
Pull-up 혹은 Pull-down이라 부르는 회로는 바로 이 상황을 막기 위해 사용합니다.

Pull-up은 애매한 전압을 강제로 5V로 만들어 1로 인식할 수 있도록 만들며, Pull-down은 애매한 전압을 강제로 0V로 만들어 0으로 인식할 수 있도록 만듭니다.

Digital 입력에서 Tri-State Level이 만들어지는 이유는 바로 스위치와 같은 Open(회로가 끊긴 상황) 회로를 사용하기 때문입니다.
이 Open 회로는 Tri-State Level을 만들기 때문에 Pull-up 혹은 Pull-down 회로가 같이 사용되어야 Digital 입력으로 활용할 수 있습니다.
그래서, Digital 입력의 정식 회로는 아래와 같습니다.


아두이노는 내부 Pull-up이라 부르는 기능을 가지고 있는데, Pull-up회로를 별도로 꾸밀 필요 없이 회로를 간소화시킬 수 있습니다.
DigitalInput의 Pullup 옵션은 바로 이 내부 Pull-up을 사용하느냐이며 Pull-up 회로를 만들었다면 체크를 해제하고 만들지 않았다면 체크를 해야 합니다.

만약, 두 Chip간의 Digital 신호를 체크하기 위함이면 Pullup 체크를 하지 않고 사용하면 됩니다. 그 이유는 두 Chip의 Pin이 연결된 경우는 Open 회로가 아니므로 Tri-State Level이 만들어지 않기 때문입니다.

설정이 완료되면 ArdunityApp의 Export Sketch 기능을 이용해서 아두이노 스케치를 생성하고 보드에 업로드하면 유니티에서 제어할 준비가 끝납니다.

유니티를 실행한 후, CommSerial의 포트 번호를 선택하고 ArdunityApp의 Connect를 실행하여 아두이노 보드를 연결하면 DigitalOutput을 제어할 수 있게됩니다. (아두니티 연결 방법 참고)
DigitalInput은 Inspector View를 통해 핀 상태를 볼 수 있는 UI를 제공하므로 프로그래밍없이 바로 회로를 테스트할 수 있습니다.
정상적으로 Digital 입력이 유니티에서 보여진다면 모든 준비가 끝난 것입니다.

C# Script에서 DigitalInput의 Value를 확인하는 방법은 다음과 같습니다.

using UnityEngine;
using System.Collections;
using Ardunity;

public class MyComponent : MonoBehaviour
{
 public DigitalInput digitalInput;
 
 void Update ()
 {
  Debug.Log(digitalInput.Value);
 }
}


DigitalInput은 값의 변화가 일어날 때마다 Event를 알려줄 수 있으며 활용법은 다음과 같습니다.

using UnityEngine;
using System.Collections;
using Ardunity;

public class MyComponent : MonoBehaviour
{
 public DigitalInput digitalInput;

 void Start ()
 {
   digitalInput.OnValueChanged.AddListener(OnDigitalInputChanged);
 }
 
 void OnDigitalInputChanged (bool value)
 {
  Debug.Log(value);
 }
}

2016년 7월 1일 금요일

DigitalOutput 응용

DigitalOutput의 대표적 응용 사례는 바로 LED 제어입니다.

LED는 Digital상태의 0V, 5V로 On, Off 제어를 할 수 있습니다.
아두이노에서 LED회로를 꾸미는 방법은 구글 검색 등으로 쉽게 찾을 수 있고, ARDUnity 에셋내에도 Users Guide 문서에 회로도가 포함되어 있습니다.

위 회로는 아두이노 Digital 핀이 (+)극 역할을 합니다. Digital 핀을 0V, 5V상태로 바꾸는 것이 회로에 전압이 인가되느냐 되지 않느냐로 제어할 수 있기에 LED가 On되거나 Off되는 것입니다.
LED는 핀에 극성이 존재하므로 다리 길이가 긴 쪽이 (+)극이 되도록 연결해야 합니다.
한가지 궁금한 점은 바로 저항이라는 부품의 용도일 것입니다.
저항(Resistor)의 역할은 회로에 흐르는 전류의 크기를 조절하는 것입니다.

LED는 5V인가 시 전류는 약 20mA 이내로 흘러야 망가지지 않습니다. 이 전류 크기를 제어하기 위해 저항을 사용합니다.
저항 크기의 단위는 옴(Ω)이며, 색깔 띠로 그 크기를 표현합니다.
사실, 전자 회로에서 가장 기초적이면서 필수적인 공식은 바로 옴의 법칙입니다.

이 공식에 의해서 R = V / I = 5 / 0.02 = 250Ω 이 계산될 수 있습니다. 즉, LED는 250Ω 보다 큰 저항을 사용하면 된다는 것을 알 수 있습니다.
대부분의 아두이노 회로는 이미 전자 회로 전문가에 의해서 검증되었으므로 골치 아프게 위와 같은 계산을 하지 않아도 됩니다.
하지만, 자신만의 독창적인 회로를 꾸밀 경우 전자 회로 이론에 따른 검증이 필요합니다.

회로를 구현한 후, 아두니티 Wire Editor 작성을 하고 아두이노 스케치를 업로드한다면 유니티에서 LED를 제어할 수 있게 됩니다.
유니티에서 LED를 재미있게 제어할 수 있는 방법을 연구하는 것은 여러분의 몫입니다.
우선은 가장 간단하게 생각해볼 수 있는 방법들을 소개하겠습니다.

UI 버튼으로 LED 제어
ButtonReactor는 바로 이 아이디어를 프로그래밍없이 바로 적용해볼 수 있는 컴포넌트입니다.


ButtonReactor는 반드시 UI Button에만 추가될 수 있으니 먼저, Scene에 UI Button을 만들어야 합니다.
ButtonReactor는 Click뿐 아니라 Down 및 Up 이벤트까지 알아낼 수 있습니다.
ButtonReactor와 DigitalOutput을 다음과 같이 연결하면 UI 버튼이 눌릴때마다 LED가 제어됩니다.



Light Intensity로 LED 제어
Light 컴포넌트의 Intensity 값으로 LED를 제어하는 방법을 생각할 수 있습니다.
이와 같은 역할을 하는 것은 바로 LightIntensityReactor입니다.


LightIntensityReactor는 반드시 Light 컴포넌트가 있어야 추가됩니다. 이것의 기능은 Light의 Intensity값을 Controller에 전달하는 역할입니다. Digital/Analog 방식을 모두 지원하며 Digital 방식으로 사용할 때는 TRUE/FALSE의 기준이 되는 Cutoff 값을 정해줘야 합니다.

LightIntensityReactor를 DigitalOutput에 연결한다면 다음과 같이 됩니다.



Trigger 이벤트로 LED 제어
유니티의 Trigger 이벤트를 이용해서 LED를 제어한다면 더 재미있는 효과를 낼 수 있습니다.
우선, Scene에 RigidBody와 Collider를 이용해서 Trigger 이벤트를 발생시킬 수 있도록 준비합니다.
Trigger 이벤트에 따라 DigitalOutput을 제어할 수 있는 역할을 하는 것은 바로 ColliderReactor입니다.


ColliderReactor는 반드시 Collider가 있어야 추가됩니다.
이것의 기능은 Collider에서 발생하는 이벤트를 받아서 Controller에 전달하는 역할입니다. Trigger와 Collision 이벤트를 모두 받을 수 있습니다.
ColliderReactor와 DigitalOutput을 연결한다면 다음과 같습니다.


이 밖에도 응용 방법은 유니티에서 매우 많을 것이고, 하드웨어 또한 LED말고도 Digital로 제어할 수 있는 어떤 부품이라도 사용 가능합니다.