자바스크립트(JavaScript)로 배우는 피지컬 컴퓨팅(Physical Computing) — (4/8) LED 밝기 조절하기

Minkyu Lee
7 min readMay 14, 2021

--

이번 강좌에서는 디지털이 아닌 아날로그 입출력(Analog I/O)을 사용하여 LED의 밝기를 조절해보도록 하겠다.

강좌 전체 목차

준비물

  • 라즈베리파이 피코 — 1개
  • 브레드보드(Breadboard) — 1개
  • LED (5mm) — 1개
  • 저항 (330Ω(옴) 또는 220Ω) — 1개
  • 포텐셔미터(Potentiometer, 10KΩ) — 1개
  • 점퍼 와이어 — 여러개

아날로그 출력(Analog Output)

디지털 입출력이 LOWHIGH의 값을 읽거나 출력하는 것에 반하여 아날로그 입출력은 0과 1사이의 수많은 값(0.0, 0.23, 0.756, 0.99, 1.0, …)을 가질 수 있다. 먼저 아래와 같이 회로를 구성해보자.

지난번에는 디지털 출력을 이용했기 때문에 digitalWrite() 함수를 사용했다. 이번에는 analogWrite()를 사용해보자. 터미널에 아래 코드를 한줄 한줄 입력하면서 LED의 밝기를 확인해보자.

> analogWrite(15, 1);
> analogWrite(15, 0.7);
> analogWrite(15, 0.5);
> analogWrite(15, 0.1);
> analogWrite(15, 0);

LED의 밝기가 1 에서는 매우 밝았다가 점점 어두워지면서 0을 입력하면 완전히 꺼지는 것을 확인 할 수 있다. 이것은 아날로그의 출력이 1일 때에는 단자로 3.3V 전체의 전압이 출력이 되고, 1보다 작아질때에는 3.3V보다 전압이 점점 낮아지다가 0을 입력하면 완전히 0V가 된다.

PWM (Pulse Width Modulation)

앞서 전압을 조절해서 0~1 사이의 값을 출력한다고 했지만, 엄밀히 말하자면 이것은 틀린말이다. Pico와 같은 디지털 컴퓨터의 경우에는 0~1사이의 값을 만들기 위해서 HIGHLOW를 1초에 수 백번에서 수 만번 매우 빠르게 전환하면서 값을 만들어 낸다. 예를 들면 0.1과 같이 낮은 값은 HIGH로 두는 시간을 매우 짧게 하고 LOW로 두는 시간을 길게한다. 반대로 0.9와 같이 높은 값은 HIGH로 두는 시간을 길게하고 LOW로 두는 시간을 짧게 한다. 이와 같이 HIGH로 두는 시간을 LOW에 대비해서 얼마나 길게 할 것인지를 듀티(duty cycle)라고 부른다. 그리고 HIGHLOW를 얼마나 1초에 몇 번이나 전환할 것인지를 주파수(frequency)라고 한다.

PWM에서의 Duty Cycle (from Wikipedia)

이렇듯 디지털 펄스를 주파수와 듀티로 제어하는 방식을 PWM(Pulse Width Modulation) 이라고 한다. Kaluma에서는 PWM을 직접 다룰 수 있는 모듈을 제공하고 있다. 아래 코드는 위의 analogWrite() 함수를 사용한 것과 동일한 효과를 낸다. 한 줄씩 터미널에 입력하면서 변화를 살펴보자. PWM 클래스는 듀티(duty) 뿐만 아니라 주파수도 조절할 수 있는데 자세한 내용은 레퍼런스를 참고하기 바란다.

> const PWM = require('pwm').PWM;
> const led = new PWM(15, 450, 1); // frequency=450Hz, duty=100%
> led.start(); // 펄스 시작
> led.setDuty(0.7); // duty=70%
> led.setDuty(0.5); // duty=50%
> led.setDuty(0.1); // duty=10%
> led.setDuty(0); // duty=0%
> led.stop(); // 펄스 중단

아날로그 입력 (Analog Input)

이제 아날로그 입력 값을 한번 읽어보자. 아날로그 값을 읽기보기 위해서 우리는 포텐셔미터(Potentiometer, 또는 가변저항)를 사용할 것이다. 포텐셔미터는 손잡이를 돌리는 정도에 따라 저항의 값이 변화하는 부품이다. 보통 오디오 장치에서 볼륨을 조절하는 용도 등으로 많이 보았을것이다.

우리는 포텐셔미터의 가운데 핀을 GPIO26번에 연결하고 왼쪽핀은 3V3, 오른쪽핀은 GND에 연결해두었다. 먼저 포텐셔미터를 시계방향(오른쪽)으로 끝까지 돌리고 아날로그 값을 읽고, 다음으로 반시계방향(왼쪽) 끝까지 돌린 다음 아날로그 값을 읽어보자. 오른쪽 핀에 GND를 연결해두었기 때문에, 시계방향(오른쪽)으로 끝까지 돌리면 0에 가까운 값이 나오고, 반대로 돌리면 1에 가까운 값이 나온다.

> analogRead(26);
0.0029296875
> analogRead(26);
0.999755859375

ADC (Analog to Digital Converter)

아날로그 출력을 실제로는 PWM을 사용하여 펄스를 만들어냈듯이, Pico는 디지털 컴퓨터이기 때문에 아날로그 값을 디지털로 변환하여 주는 장치가 필요한데 그것이 바로 ADC(Analog to Digital Converter)이다. Pico는 내부에 ADC를 내장하고 있어서 바로 사용할 수 있는데, 단지 3개의 핀(GPIO26=ADC0, GPIO27=ADC1, GPIO28=ADC2)에서만 ADC 기능을 사용할 수 있다는 것을 기억하자. 요즘에는 많은 디지털 센서들이 잘 나와있어서 아날로그 부품을 쓸일이 그리 많지는 않지만, 여전히 많이 쓰이는 아날로그 부품들(온도, 거리, 자기장 등)이 있는데 그럴 때 ADC핀에 연결하여 사용하면 된다.

Kaluma에서는 ADC도 별도의 API를 제공하고 있다. 아래 코드와 같이 ADC 클래스의 인스턴스를 만들고 값을 읽을 수 있다. ADC의 자세한 내용은 역시 레퍼런스를 참고하기 바란다.

> var ADC = require('adc').ADC;
> var a = new ADC(26);
> console.log(a.read());

모든 것을 연결해보자

이제 모든 것을 연결해서 포텐셔미터를 돌리는 만큼 LED의 밟기를 조절하는 프로그램을 작성해보자. 아래 코드는 0.1초 마다 포텐셔미터의 값을 읽어서 그 값 만큼으로 LED의 밝기를 설정한다. 물론 포텐셔미터를 LED에 직접 연결해서 밝기를 조절 할 수도 있지만, 여기서는 프로그램으로 다루는 방법을 설명하기 위해서 이런 방법을 사용한다.

포텐셔미터로 LED 밝기 조절하기

이번 강좌까지 디지털 입출력과 아날로그 입출력 모두를 다루어보았다. 다음 강좌에서는 온도와 습도를 측정할 수 있는 좀 더 실용적인 센서를 다루어보도록 하자.

--

--

Minkyu Lee
Minkyu Lee

Written by Minkyu Lee

PhD in Computer Science, JavaScript enthusiast, Amateur Jazz drummer.

No responses yet