본문 바로가기
전자공학/아두이노

아두이노 PWM 실습1: analogWrite() 시뮬레이션

by 블랜드 2022. 2. 2.
반응형

Fast PWM(5, 6번 핀) vs Phase Correct PWM(3, 9, 10, 11번 핀)

 

※ x = 비교 값 = Fast PWM에서의 Ton 클럭수 (범위: 0~255)

파형 모드 디지털 핀 PWM 주기 PWM 주파수 Duty Cycle
Fast PWM 5, 6 256 클럭 976.5625Hz x / 256
Phase Correct PWM 3, 9, 10, 11 510 클럭 490.1961Hz x / 510 * 2 = x / 255

 이번에는 아두이노의 PWM 함수인 analogWrite() 함수를 쓸 때 각 파형 모드에 따라 위 표와 같이 Duty Cycle 계산 공식이 들어맞는지를 검증해 보도록 하겠다. 본 글에서는 아두이노 시뮬레이터인 서킷(Circuit)을 이용하여 실험하도록 하겠다. 

 

※서킷이 무엇인지 알고 싶으면 다음 글을 참고하라.

 

아두이노 시뮬레이터 Circuits(서킷) 및 학습 사이트

아두이노 Circuits(서킷)이란?  Circuits(서킷)은 오토데스크(Autodesk)사에서 온라인에서 무료로 제공하는 아두이노 시뮬레이터이다. 즉, 아두이노 및 전자 부품을 이용하여 가상으로 동작하는 전자

recall.tistory.com


시뮬레이션 구성

서킷(Circuit)을 통한 시뮬레이션 실험 구성

  Arduino Uno R3 보드의 PWM 출력이 가능한 5번, 9번 디지털 핀에 각각 계측기(멀티미터)와 오실로스코프를 하나씩 연결하였다. 위 시뮬레이션 구성 그림에서 노란 작은 직사각형이 계측기이고, 노랗고 큰 정사각형 모양이 오실로스코프이다. 계측기는 각 디지털 핀에서 출력되는 평균 전압을 측정하여 Duty Cycle을 검증하기 위해서 연결하였다. 오실로스코프는 analogWrite()의 예외 사항에서 파형이 어떻게 출력되는지 보여주기 위해 연결하였다.


시뮬레이션 실험 코드

 실험에 쓰인 코드는 아래와 같다. analogWrite(pin, 아날로그 값(0~255)) 함수에서의 두 번째 매개변수인 아날로그 값을 0~255까지 값 중 임의로 변화시켜가며 실험하는 코드이다. 아래 코드는 analogWrite(5, 0), analogWrite(9, 0)으로 되어 있는데 여기서 두 번째 매개변수에 설정된 0을 0~255까지 임의로 바꿔가며 평균전압을 측정해 볼 것이다. 

void setup()
{
  Serial.begin(9600);
  analogWrite(9, 0); // 9번 핀에 설정된 아날로그 값에 따른 PWM 출력
  analogWrite(5, 0); // 5번 핀에 설정된 아날로그 값에 따른 PWM 출력
}

void loop()
{
  Serial.print(OCR1A); // 9번 핀: 16비트 타이머 비교값(PC PWM)
  Serial.print("\t");
  Serial.print(OCR1AH); // 9번 핀: 8비트 타이머 상위 비교값(PC PWM)
  Serial.print("\t"); 
  Serial.print(OCR1AL); // 9번 핀: 8비트 타이머 하위 비교값(PC PWM)
  Serial.print("\t");
  Serial.println(OCR0B); // 5번 핀: 8비트 타이머(Fast PWM)
}

 위 코드에서 loop문 안에 있는 Serial.print()문들은 analogWrite()에 설정된 0~255까지의 아날로그 값에 따라 어떤 비교값을 출력해내는지 알아보기 위한 함수이다. analogWrite(pin, 아날로그 값(0~255))에서 아날로그 값은 해당 핀에 연결된 타이머의 비교 값을 의미한다.

 

※타이머와 analogWrite()에 대해 알아야 이해가 수월하다. 아래 글을 참고하라.

 

아두이노 PWM 이론2: analogWrite() 함수 분석

 <선수지식>  (1) 아두이노 analogWrite() 함수에 대해 알아보기 전에 원활한 이해를 이해 먼저 아래 글을 읽어오면 본문을 이해하기 수월하다.  아두이노는 디지털 장치이므로 아날로그 신호를 바

recall.tistory.com


<실험 결과>

analogWrite(0)

analogWrite(0)에 대한 시뮬레이션 결과

 5번, 9번 디지털 핀 모두 계측기에 측정된 평균전압이 0V로 나왔다. 이는 Duty Cycle을 통해 도출된 평균전압 Vavg 값과 같다. 즉, 비교 값이 0이므로 PWM 주기에서 ON 되어 있는 시간인 Ton이 0이 되므로(Ton = 0) 평균전압은 아래와 같이 계산된다.

 5번 핀: Vavg = 0 / 256 x 5V = 0V 

 9번 핀: Vavg = 0 / 255 x 5V = 0V

analogWrite(255)

analogWrite(255) 시뮬레이션 결과: 5번 핀, 9번 핀

 5번, 9번 디지털 핀 모두 계측기에 측정된 평균 전압이 5V로 나왔다. 이는 다음과 같이 5번 핀은 Duty Cycle을 통해 도출된 평균전압 Vavg 값과 다르다. 

 5번 핀: Vavg = 255 / 256 x 5V= 4.98V

 9번 핀: Vavg = 255 / 255 x 5V= 5.00V

 왜 이런 식으로 계산됐는지는 아래 그림을 보면 알 수 있다.

Fast PWM 5번, 6번 핀 PWM 출력

 5번 핀에 해당하는 Fast PWM에서는  255를 비교값으로 설정하게 되면 클럭이 255가 됐을 때 출력이 OFF가 된다. 그래서 PWM 주기 Tpwm=256 클럭 중에 ON되어 있는 시간이 Ton  = 255 클럭이 되어 Duty Cycle = 255/256이된다. Duty Cycle에 5V를 곱하면 평균전압이 나온다. 따라서 원래라면 평균전압 Vavg = Duty Cylce x 5V = 255/265 x 5V = 4.98V이 5번 핀에서 계측되어야 한다.

Phase Correct PWM 3, 9, 10, 11번 핀 PWM 출력

 9번 핀에 해당하는 Phase Correct PWM에서는 255를 비교값으로 설정하게 되면, 업카운트할 때 클럭이 255가 되면 출력이 OFF가 된다. 그런데 바로 그 순간 255가 클럭 최대값이므로 클럭을 더 이상 증가시키며 셀 수가 없어서 다운카운트가 시작된다. 다운카운트 때 255와 비교 일치가 일어나므로 출력은 ON이 된다. 업카운트 비교 일치 때의 OFF는 없던 일이 되는 것이다. 따라서 위 그림과 같이 PWM 주기 동안 모두 ON되어 있다.

 그래서 PWM 주기 Tpwm=510 클럭 중에 ON되어 있는 시간이 Ton=255+255=510 클럭이 되어 Duty Cycle = 255/510x2 = 255/255 = 1이된다. Duty Cycle에 5V를 곱하면 평균전압이 나온다. 따라서 원래라면 평균전압 Vavg = Duty Cylce x 5V = 1 x 5V = 5V가 5번 핀에서 계측되어야 한다. 9번 핀의 경우는 5번 핀과 달리 이 계산 결과대로 5V로 똑같이 나왔다.

 

 5번 핀은 4.98V가 나와야 하는데 정작 analogWrite(255) 결과에서는 5V가 나왔다. analogWrite(255)에서는 왜 이런 결과가 나온 것일까? 그 이유는 다음과 같다.

 

 왜냐하면 analogWrite(0), analogWrite(255)의 정의가 아래 코드와 같이 analogWrite(pin, val)가 짜여져 있기 때문이다. 두 번째 매개변수인 val 값이 0이면 digitalWrite()로 LOW(0V)를 내보내고,  val 값이 0이면 digitalWrite()로 HIGH(5V)를 내보낸다. 즉, analogWrite(0) = digitalWrite(LOW)이고 analogWrite(255) = digitalWrite(HIGH)로 정의되어 있다.

	if (val == 0)
	{
		digitalWrite(pin, LOW);
	}
	else if (val == 255)
	{
		digitalWrite(pin, HIGH);
	}

analogWrite(255) = digitalWrite(HIGH)로 정의한 이유

 analogWrite(255)를 digitalWrite(HIGH)로 지정해 단순히 5V 디지털 신호만 내보내도록 설정한 이유가 무엇일까? 그 답은 타이머 비교값의 한계 때문이라고 볼 수 있다. analogWrite() 함수에서 사용하는 타이머는 8비트로 제한하고 있는데, 이는 '클럭'과 '비교값'의 최대값이 8비트가 나타낼 수 있는 최댓값으로 제한된다. 즉, 2^8 - 1 = 255까지로 제한된다. 클럭을 255까지 세줄 수 있고, 비교값 설정도 255까지가 최대인 것이다.

Fast PWM 5번, 6번 핀 PWM 출력

 타이머를 이용한 PWM의 원리를 기억하는가? Fast PWM의 경우, 현재까지 세어 온 클럭수와 비교값이 일치하는 순간 출력은 OFF가 된다. 이 때문에 비교값을 최대로 설정해도 PWM으로 완전한 HIGH 값을 만들 수가 없기 때문에 digitalWrite() 함수로 대체한 것이다. 아까 보여준 위 그림을 보면 비교값=255과 클럭=255이 서로 일치하는 부분에서 OFF가 일어나 PWM에서 모두 ON이 안 된 것을 볼 수 있다.

 이 때문에 analogWrite(255)일 때 digitalWrite(HIGH)로 대체한 것이지만 이로 인해 문제가 하나 더 발생한다. 그것은 원래 비교값 = 255이면 Duty Cycle = 255 / 256이 되어야 하는데, 이를 주기 전체에서 HIGH(ON) 시켰으므로 Ton=256이 되어 Duty Cycle = 256 / 256 = 1이 되어 버린다. 즉, Duty Cycle = 255 / 256 값이 사라진다. 이는 Duty Cycle = 254 / 256와 Duty Cycle = 255 / 256 = 1 사이의 값을 나타내는 Duty Cycle = 255 / 256 값이 없어짐을 나타낸다. 출력전압이 5V일 때 PWM으로 평균전압 Vavg = 255 / 256 x 5V= 4.98V을 못 나타내게 되는 문제점이 생긴다. 256가지의 아날로그 표현 중 255가지밖에 못 나타내게 되는 것이다.

 

 이때 analogWrite(255) 말고 진짜 비교값이 255일 때의 출력을 보고 싶으면 어떻게 하면 될까? 그것은 아래와 같이 analogWrite(511)로 하면 된다. 


analogWrite(511)

analogWrite(511)일 때의 평균전압

 비교값은 8비트로 제한되어 있기 때문에 255 값을 넘어가서 256이 되면 오버플로우가 일어나 0이 되어 버린다. 그래서 비교값이 255일 때의 진짜 출력을 알고 싶으면 256(0)+255 = 511을 analogWrite() 함수에 대입하면 알 수 있다. 위 그림은 analogWrite(511)일 때를 시뮬레이션하여 평균전압을 측정한 그림이다. 아래 평균전압 공식으로 도출한 결과와 같게 나옴을 볼 수 있다.

 5번 핀: Vavg = 255 / 256 x 5V= 4.98V

 9번 핀: Vavg = 255 / 255 x 5V= 5.00V

 4.98V로 측정되는 5번 핀에 연결된 오실로스코프를 한 번 보자. 9번 핀의 오실로스코프는 5V는 일정한 전압 파형을 보여주는 반면, 5번 핀의 오실로스코프는 1클럭 동안 LOW가 되어 있는 것을 볼 수 있다. 어떻게 LOW인 간격이 1클럭인지 아는 것인가? 그 이유는 오실로스코프의 한 눈금을 5번 핀에 해당하는 Fast PWM의 한 클럭 주기인 4μs로 설정해 놓았기 때문이다. Fast PWM의 한 클럭의 주파수는  fclock = 클럭 주파수 / 분주비인데, 이때 '클럭 주파수=16MHz'이고, 분주비=64로 설정되어 있다. 따라서 주기는 주파수의 역수이므로 '한 클럭의 주기 = 1 / fclock =분주비 / 클럭 주파수 = 64/16000000*(10^6) = 4μs'이다. 이를 통해 5번 핀의 오실로스코프에서 한 눈금 동안 LOW 되어 있는 것을 보고 한 클럭이 OFF 되어 있음을 확인할 수 있다.

 

 5핀 PWM 파형의 한 주기에 해당하는 256클럭 중에 255클럭이 HIGH(ON)이고, 나머지 1클럭이 LOW(OFF)인 것이다. 이로부터 Fast PWM에서는 '비교값=ON되는 클럭 개수'임을 알 수 있다. 비교값이 125이면 ON되는 클럭 개수는 125개이다. 비교값이 1이면 ON되는 클럭 개수는 1개이다.


analogWrite(250)

 

analogWrite(250)일 때의 평균전압

 5번 핀: Vavg = 250 / 256 x 5V= 4.88V

 9번 핀: Vavg = 250 / 255 x 5V= 4.90V

 시뮬레이션 결과가 Duty Cycle 공식을 이용한 평균전압과 똑같이 나오는 것을 확인할 수 있다. 이로부터 본문 맨 위 표에 정리해 놓은 Duty Cycle 공식이 올바른 식이라는 것을 검증하였다.

analogWrite(254)

 5번 핀: Vavg = 254 / 256 x 5V= 4.96V

 9번 핀: Vavg = 254 / 255 x 5V= 4.98V

 이 또한 계산값과 시뮬레이션 결과가 동일하게 나옴을 확인할 수 있다.

 이때 5번 핀에 연결된 오실로스코프를 보면 2개의 클럭 동안 OFF되어 있음을 볼 수 있다. 이는 Fast PWM에서는 '비교값=ON되는 클럭 개수' 공식을 떠올리면 쉽게 알 수 있다. 5핀은 Fast PWM 출력에 해당하는데, 비교값을 254로 설정하였으므로 PWM 파형의 한 주기에 해당하는 256개의 클럭 중 254개의 클럭이 ON이 되고 나머지 2클럭이 OFF가 된 것이다.

 더불어 9번 핀에 연결된 오실로스코프를 보면 여기도 마찬가지로 2개의 클럭이 OFF 되어 있다. 뭔가 이상하지 않은가? 9번 핀의 Duty Cycle 계산 공식을 보면 254 / 255로 되어 있으므로 전체 주기는 255클럭이 아닌가? 그렇다면 255클럭 중에 비교값이 254이므로 한 주기에 PWM 파형의 한 주기에 해당하는 255개의 클럭 중 254개의 클럭이 ON이 되고 나머지 1클럭이 OFF가 되야 하는 것이 아닌가? 왜 그런 것인가?

 

 그 이유는 9번 핀의 출력은 Fast PWM이 아니라 Phase Correct PWM이기 때문이다. Phase Correct PWM의 한 파형의 전체주기는 510클럭이고 'ON이 되는 클럭 개수 = 2 x 비교값'이기 때문이다. 

비교값이 254일 때의 Phase Correct PWM

 왜 Phase Correct PWM에서는  'ON이 되는 클럭 개수 = 2 x 비교값'인지 궁금한가? 그건 위 그림을 다시 보면 알 수 있다. 주황색 점선을 기준으로 파형을 양쪽으로 이등분한다고 생각하면 된다. 왼쪽 파형은 0~255클럭까지 진행되므로 주기는 255클럭이고, 오른쪽 파형은 255~0까지 진행되므로 주기 또한 255클럭이다. 즉, 왼쪽 및 오른쪽 파형 모두 주기가 255클럭이다. 이때 왼쪽 및 오른쪽 파형 둘 다 Fast PWM 같은 모양을 가지므로 비교값이 설정되면 각 파형에서 'ON이 되는 클럭 개수 = 비교값'이 된다. 그런데 Phase Correct PWM은 두 파형을 모두 합친 파형이므로 총 주기는 255 + 255  = 510 주기가 되고, 두 파형에서 ON이 되는 클럭 개수도 합치게 되므로 'ON이 되는 클럭 개수 = 비교값 x 2'가 된다. 따라서 x를 비교값이라고 할  때 Phase Correct PWM의 Duty Cycle 공식이  (2*x) / 510 = x / 255가 되는 것이다.

 

 analogWrite(254)에서는 비교값을 254로 설정했으므로 ON이 되는 클럭 개수 = 2 x 254 = 508'이다. 따라서 PWM 파형의 한 주기에 해당하는 510개의 클럭 중 508개의 클럭이 ON이 되고 나머지 2클럭이 OFF가 된 것이다. 


analogWrite(1)

 5번 핀: Vavg = 1 / 256 x 5V= 0.0195V = 19.5mV

 9번 핀: Vavg = 1 / 255 x 5V= 0.0196V = 19.6mV

 analogWrite(1)의 계산결과와 실제 시뮬레이션 결과가 비슷하게 나오는 것을 볼 수 있다. 그런데 문제가 있다. 아까와는 달리 위 그림을 보면 5번, 9번 핀에서 측정되는 전압들이 수시로 변한다. 왜 그런 것일까? 그 이유는 PWM은 디지털 신호를 ON, OFF를 번갈아 가며 출력하여 평균전압을 만들어내는 것이기 때문이다. 시간의 흐름에 따라 평균전압으로 인식하는 한 주기 내에서 ON, OFF가 차지하는 비율이 수시로 변하기 때문에 나타나는 현상인 것이다. 이 현상은 비교값이 커서 ON이 되는 클럭의 개수가 많을수록 잘 안 나타난다. ON이 되는 클럭의 개수가 많아지면 OFF가 되는 클럭의 개수가 적어져 OFF 클럭이 평균전압에 영향을 덜 미치기 때문이다. 그래서 아까 위에서 analogWrite(250)과 같이 비교값을 크게 하면 위 그림과는 달리 측정되는 전안 값이 변하지 않는다.

 

 시뮬레이션이 아닌 실제로 아두이노에 계측기(멀티미터)를 연결하여 PWM 실험을 해 봐도 0.1V 단위의 전압 변화가 나타남을 확인할 수 있다. 물론 시뮬레이션이 너무 심하게 계측기로 측정되는 전압 값이 요동치는 것일뿐, 실제 실험에서는 PWM 출력을 측정해 보면 거의 고정된 전압 값으로 측정된다. 이는 다음 글에서 보일 것이다.

반응형

댓글