본문 바로가기

아두이노로 장난하기

아두이노 기초지식_아날로그 입력/출력


안녕하세요 고군입니다.

이번시간에는 아날로그 입력과 출력에 대해 알아보겠습니다.


▶ 아날로그 입력


그림 1과 같이 배선을 하고 아두이노 IDE로 업로드한 다음 가변 저항의 손잡이를 좌우로 돌려보세요. 손잡이 위치에 따라 LED의 밝기가 변하는 것을 보실 수 있습니다.




그림 1. 가변 저항과 LED를 연결한 배선도와 회로도


아두이노 예제 소스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//가변 저항에 연결한 핀 번호
const int sensorPin = 0;
 
//LED에 연결한 핀 번호
const int ledPin = 9;
 
void setup()
{
  //LED에 연결한 핀의 모드를 출력으로 설정
  pinMode(ledPin, OUTPUT);
}
 
void loop()
{
  //가변저항에 연결한 핀의 값을 읽어 들인다
  int value = analogRead(sensorPin);
 
  //가변저항의 값을 기초로 LED의 밝기를 구한다.
  // 0~1023의 입력을 0~255범위로 변환
  int intensity = map(value, 010230255);
 
  //LED에 연결한 핀의 값을 설정
  analogWrite(ledPin, intensity);
}
cs

위의 소스에서 analogRead는  지정한 핀의 아날로그 값을 읽어 들이는 명령입니다. 아두이노 보드는 아날로그 입력을 0 ~ 1023까지  1204단계로 표현합니다. 이에 비해 analogWrite는 0~255까지 256 단계가 있기 때문에 map이라는 메서드를 사용해 범위를 맞추고 있습니다.

그럼 가변 저항을 돌리면 전압은 어떻게 변하는 것일까요? 가변 저항의 안에는 이중의 링이 있습니다. 손잡이를 돌리면 외측 링과 내측 링을 연결하는 전극이 회전하여 각도에 따라 1과 2 사이, 2와 3사이의 저항이 변합니다.


그림 2. 가변 저항의 내부 구조, 왼쪽으로 돌린 상태(가운데), 오른쪽으로 돌린 상태(오른쪽), 왼쪽으로 돌린 상태에서는 1과 2 사이의 저항값이 작고 2와 3 사이의 저항값이 크다. 오른쪽으로 돌린 상탱에서는 1과 2사이의 저항값이 크고 2와 3사이의 저항값이 작다.


2와 3사이의 저항값을 R1, 1과 2사이의 저항값을 R2라고 하면 그림3과 같이 타나낼 수 있습니다. R1의 비율이 크면 중간 점의 전압이 낮아집니다. 반대로 R2의 비율이 크면 중간 점의 전압이 높아집니다. 이와같이 전압을 저항기 2개의 비율에 따라 나는 것을 저항분압이라고 부릅니다. 이제 저항값이 변화하는 센서의 출력을 전압의 변화로 측정할 수 있습니다.


그림3. 저항분압의 개념도. R1과 R2의 비율에서 R1의 비율이 크면 중간 점의 전압은 낮고 R2의 비율이 크면 중간 점의 전압은 높다. R1은 센서, R2는 저항를 사욜하는 경우도 많다.



▶ PWM을 이용한 아날로그 출력


아래 코드의 dealy의 값을 점점 작게 해 보십시요. 500이나 100으로 하면 빠른 속도로 깜박이는 것처럼 보이겠지만, 값을 더 작게 하면 깜빡인다고 느껴지기 보다 착시현상으로 인해 항상 켜져 있는 것처럼 보입니다. loop를 다음과 같이 변경하면서 LED의 밝기가 어떻게 변하는지 확인해 보십시요.




그림4. 디지털 핀 9번(D9)에 저항과 LED를 연결한 배선도 와 회로도


아두이노 예제 소스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// LED에 연결한 핀 번호
int ledPin = 13;
// setup은 처음에 한 번만 실행된단.
void setup() {
  // LED에 연결한 핀의 모드를 출력으로 설정
  pinMode(ledPin, OUTPUT);
}
 
// loop는 아두이노 보드의 전원이 켜져 있는 동안 반복해서 실행된다
void loop()
{
    // LED에 연결한 핀의 값을 HIGH로 설정하고 LED를 켠다
    digtalWrite(ledPin, HIGH);
    dealy(5);
    // LED에 연결한 핀의 값을 LOW로 설정하고 LED를 끈다
    digtalWrite(ledPin, HIGH);
    dealy(5);
}
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// LED에 연결한 핀 번호
int ledPin = 13;
// setup은 처음에 한 번만 실행된단.
void setup() {
  // LED에 연결한 핀의 모드를 출력으로 설정
  pinMode(ledPin, OUTPUT);
}
 
// loop는 아두이노 보드의 전원이 켜져 있는 동안 반복해서 실행된다
void loop()
{
    // LED에 연결한 핀의 값을 HIGH로 설정하고 LED를 켠다
    digtalWrite(ledPin, HIGH);
    dealy(1);
    // LED에 연결한 핀의 값을 LOW로 설정하고 LED를 끈다
    digtalWrite(ledPin, HIGH);
    dealy(9);
}
cs


확인을 해보셨다면 켜지는 시간과 꺼지는 시간 양쪽 다 5ms로 한 경우와 비교해서 켜져 있는 시간을 1ms, 꺼져 있는 시간을 9ms로 한 경우가 훨씬 어둡게 느깨질 것입니다. 이렇게 빠른 속도로 켜진 상태와 꺼진 상태를 반복하여, 켜진 구간과 꺼진 구간의 비율을 바꿈으로써 연속적으로 출력을 조절하는 것을 PWM(펄스폭 변조:Pulse Width Modulation)라고 합니다.


그림5. PWM개념도. ON/OFF를 고속으로 반복하면서 각각의 비율을 연속적으로 바꿈으로써 전압을 변화시킬 때와 마찬가지로 연속적인 변화를 만들어 낼 수 있다. 아날로그는 아니지만, 사람이 인지하기에는 아날로그처럼 느껴지므로 아두이노에서는 anlogWrite라고 씁니다.


  아두이노에서는 PWM을 이용해서 출력을 연속적으로 바꾸기 위해 analogWrite라는 함수가 있습니다. digitalWrite는 ON/OFF 두 단계밖에 없지만, analogWrite는 0~255까지 256단계의 연속적인 변화를 만들어 낼 수 있습니다. 이것을 사용한 예제가 Exampledm의 Analog/Fading입니다.


아두이노 예제 소스(예제>Analog>Fading)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//LED에 연결한 핀 번호
int ledPin = 9;
 
void setup() {
  // setup은 아무것도 하진 않음
}
 
void loop() {
  // 최소값에서 최대값까지 5씩 늘린다
  for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 5
{
    // 값을 설정(0~255까지)
    analogWrite(ledPin, fadeValue);
    // 30ms 대기
    delay(30);
  }
 
  // 최소값에서 최대값까지 5씩 줄인다
  for (int fadeValue = 255 ; fadeValue >= 0; fadeValue -= 5
{
    // 값을 설정(0~255까지)
    analogWrite(ledPin, fadeValue);
    // 30ms 대기
    delay(30);
  }
}
cs