본문 바로가기
Arduino&RasberryPi/Arduino Uno

8. Arduino - analogWrite() 함수를 이용한 신호 세기 조절

by Rosmary 2019. 10. 25.
728x90
반응형

지금까지의 Arduino 실습 내용은, 발광 다이오드 점멸과 관련된 내용이 전부였다. 따라서 발광 다이오드는 꺼지거나 켜지는 이상의 행위는 진행할 수 없었다. 이번 포스팅에서는 analogWrite() 이라는 함수를 이용해, 발광 다이오드가 내는 빛의 밝기를 조절해보려고 한다.

 

 

1. 회로의 구성.

 

지금까지와는 다르게, 단 하나의 발광 다이오드 회로만 제작하여 실습을 진행한다. 초록색 발광 다이오드 1개, 저항 1개, 그리고 전선 2개로 회로를 구성하며, 전원 공급 핀의 번호는 9번으로 설정하였다.

 

<사진>

 

 

2. analogWrite() 함수

 

지금까지, 회로와 연결된 전기 부품(거의 발광 다이오드였다)에 신호를 공급하기 위한 코드로 digitalWrite() 함수를 사용해왔다. 하지만, digitalWrite() 함수의 경우, 전기신호를 주거나(HIGH), 차단(LOW)하는 옵션밖에 설정할 수 없었기 떄문에, 밝기를 조절하기 위해 작성할 코드로는 적합하지가 않다. 

 

이처럼, 정량적인 수치로 특정 신호의 세기를 조절해야 할 필요가 있을 때, 사용하는 함수가 바로 analogWrite() 함수다. 포맷은 digitalWrite() 함수와 매우 유사하다.

 

==============================

analogWrite( #Pin, 0~ 255 )

==============================

 

위의 포맷을 보면 알겠지만, digitalWrite() 함수의 두 번째 인자에 사용되는 HIGH와 LOW 대신, 0부터 255까지의 정수를 사용한다는 것을 알 수 있다. 조금 더 깊이있게 들어가자면, 회로에 공급하는 전원의 세기를 8비트 숫자로 표현함을 알 수 있다.

 

analogWrite() 함수 사용 시 주의점

 

Arduino Uno 제품에서, analogWrite() 함수는 OUTPUT핀 번호가 3, 5, 6, 9, 10, 11번으로 고정되어 있다.

 

 

4. 코드

 

int pinNumber = 9;
int intensity;

void setup() {
    pinMode(pinNumber, OUTPUT);
    Serial.begin(9600);
}

void loop() {
    Serial.println("digitalWrite Test");
  
    digitalWrite(pinNumber, HIGH);
    Serial.print("Signal Intensity: ");
    Serial.println(digitalRead(pinNumber));
    delay(1000);

    digitalWrite(pinNumber, LOW);
    Serial.print("Signal Intensity: ");
    Serial.println(digitalRead(pinNumber));
    delay(1000);

    Serial.println("analogWrite Test") ;
    for(intensity = 1 ; intensity < 252 ; intensity += 10 )
    {
      analogWrite(pinNumber, intensity);
      Serial.print("Signal Intensity: ");
      Serial.println(analogRead(pinNumber));
      delay(200); 
    }

 

    for(intensity = 255 ; intensity > 0 ; intensity -= 10 ) 
    { 
      analogWrite(pinNumber, intensity); 
      Serial.print("Signal Intensity: "); 
      Serial.println(analogRead(pinNumber)); 
      delay(200);  
    } 
}

 

코드 내용은 길이에 비해 심플하다. 우선 void setup() 함수는 사용할 pin 번호와 디버깅을 위한 Serial 포트 사용을 선언하는 것 외에 작성한 코드가 없다. loop() 에서는, 처음에는 digitalWrite() 함수의 작동과 신호의 세기를 확인하여 Serial Monitor에 출력하도록 만들고, 이후 analogWrite()함수의 작동과 신호 세기를 확인하도록 코드를 작성했다. 결과는 아래와 같다.

 

 

5. 결과

 

 

코드 작성 시, 의도한대로 발광 다이오드가 한 번 깜빡이고(digitalWrite), 이후에 서서히 밝기가 변화(analogWrite)되는 것을 확인할 수 있었다.

 

digitalWrite와 analogWrite 사이의 차이점도 확인할 수 있었는데, digitalWrite() 함수를 통해 전달되는 신호의 크기는 단순히 0(LOW)과 1(HIGH)로만 나타나며, analogWrite()의 경우 이와 다르게 0부터 255 사이의 수가 나타난다는 것이다. 필자는 코드를 작성하기 전에, analogWrite() 함수의 두 번째 인자의 최대값이 255라고 정의되어 있어서, digitalREAD() 함수의 HIGH 값도 255로 출력될 것이라 예상했는데, 보기좋게 예측이 빗나갔다.

 

* digitalRead() 함수는, digitalWrite() 함수에 정의된 pin에서 발생하는 신호의 유무를 나타내어 주는 함수라고 생각하면 된다. HIGH일 경우 1을, LOW일 경우, 0을 출력한다.

 

analogWrite()의 두 번째 인자값의 범위가 0 ~ 255 라고 위에서 언급했는데, 사실 이보다 더 큰 수나, 음수가 입력되더라도 작동은 된다. 다만 범위를 벗어나는 값이 입력되었을 때, 이 값에서 256을 뺀 값이 Arduino에 인식된다. 즉, 255에서 1이 더해진 값은 0으로, 255 * 2 값인 510이 입력되었을 때는 255가 입력되었다고 인지한다. 음수의 경우도 마찬가지로, 0보다 1이 작은 -1인 경우 255와 동일한 밝기의 빛을 발산하고...

 

 

정리하자면, 단순히 신호의 전달과 차단을 목적으로 한다면, digitalWrite() 함수를, 그렇지 않고 신호의 세기까지 고려를 해야한다면 analogWrite() 함수를 사용해야 한다.

 

 

ps: analogWrite() 함수와 쌍으로 붙어 오는 함수 중에 analogRead() 라는 함수가 있다. 하지만, 이 두 함수의 규칙성을 필자가 아직까지도 찾아내지 못해서 본 포스팅에 관련 내용을 넣지 않았다. 발견하는 대로 추가로 내용을 작성할 예정이다.

 

 

FIN.

반응형

댓글