커뮤니티
- 제 목 [ 기초 ] 아두이노 실습 - 어두워지면 점점 밝아지는 가로등 만들기
- 작성자 주피터 조회 : 9,675 좋아요 : 0 댓글 : 0
- 작성일 2019-10-28 오전 9:40:52
-
날이 저물어 어두워지려고 할 때 하나 둘씩 가로등이 켜지는 것을 본 적이 있을 겁니다.
주변에 아무도 없는 것 같은데 누가 스위치를 눌러 켜주는 것도 아닌데 가로등이 어떻게 자동으로 켜지는 걸까요?
그것은 가로등이 주변이 밝기를 인식하고 자동으로 불을 켜기 때문입니다.
가로등을 같이 만들어 보면서 가로등이 어떻게 자동으로 켜지고 점점 밝아지는지 알아보도록 하겠습니다.
광센서는 빛의 양을 측정해 전기 신호로 바꿔 출력하는 전자부품이에요.
광센서는 저항처럼 +, -에 대한 극성이 없는 무극성 소자이므로 회로를 구성할 때 방향을 고려할 필요가 없습니다. 그리고 내부적으로 저항 한 개와 결합한 간단한 회로 구조를 가지고 있는데 빛의 밝기가 커지면, 내부 저항값이 작아지고 어두워지면 내부 저항값이 커지는 구조입니다. 그래서 내부 저항값의 변화에 따라 다른 전압을 출력하게 됩니다.
ⓞ 광센서 회로 구성
광센서 회로를 구성하는 방법을 보면 그림과 같이 되는데 아날로그 단자를 사용해 출력하는 전압을 읽고 10K옴 정도의 큰 저항을 연결해 회로를 구성해 줍니다.
광센서 한쪽 다리는 5v 에 연결하고 다른 하나는 아날로그 입력 단자에 연결하고 10k옴 저항을 아날로그 입력 단자와 그라운드 사이에 하나 연결해 줍니다.
A0 단자에서 측정되는 전압은 빛의 밝기에 따라 달라지는데, 식으로 표현하면 그림과 같고, 광센서 내부 저항 크기가 외부 빛의 양에 따라 달라지면, 위의 식 저항 비율에 따라 A0 전압이 달라집니다.
10K옴 정도의 그렇게 큰 저항을 사용하는 이유는 뭘까요 ? 그것은 빛이 너무 밝아 광센서의 저항이 0이 되어도 과도한 전류가 흐르지 않도록 하고 A0의 전압이 0 ~ 5V까지 선형적으로 변화할 수 있도록 하기 위한 목적입니다.
ⓞ 광센서에서 출력하는 전압값을 아날로그 입력으로 받는 부분
아두이오가 광센서 신호를 인식하려면 아날로그 입력 단자에 연결합니다. 아두이노는 A0 ~ A6까지 6개의 아날로그 입력 단자가 있는데 그 중에 하나를 사용하면 됩니다.
광센서 회로는 아날로그 단자에 연결 한다고 했는데 아날로그는 컴퓨터는 0과 1, 두 값만 인식할 수 있는데 이것을 디지털이라고 합니다. 하지만, 우리가 살고 있는 세상에는 0과 1 두 값만으로는 표현할 수 없는 것이 무수히 많습니다.예를 들어, 빛의 밝기는 밝다. 어둡다. 두 가지 값만 가지는 것이 아니지요. 밝다. 조금 밝다. 매우 밝다. 어둡다. 매우 어둡다. 등의 아주 다양한 값을 가지기 때문에 이렇게 다양한 값으로 표현하는 것을 아날로그라고 합니다. 그래서 빛의 밝기는 디지털이 아닌 아날로그값으로 처리해야 하기 때문에 아날로그 단자에 연결합니다.
ⓞ analogRead() 함수로 아날로그 입력값 읽기
스케치에서 아날로그 입력값은 읽으려면 스케치 프로그래밍을 할 때는 analogRead() 함수를 사용해서 읽습니다. 그림에서 보는 것처럼, 광센서에서 0V ~ 5V의 전압값을 출력한다고 하면 analogRead() 함수는 광센서에서 내보내는 0V ~ 5V의 전압값을 입력받아 0 ~ 1023 사이의 값으로 변환해 줍니다.
그래서 analogRead() 함수는 단자번호를 인자로 받아서 그 단자의 전압값을 읽어 0 ~ 1023 사이의 값으로 변환해 반환하는 것입니다. 그래서 1024가지의 다양한 값으로 반환해 주는 것입니다.
ⓞ LED 밝기 조절을 위한 진폭변조
가로등이 점점 밝아지게 하려면 밝다. 어둡다 두가지 상태만 있는 것이 아니라 점점 어두워지고 점점 밝아지는 다양한 상태가 있기 때문에 디지털이 아닌 아날로그값을 사용해야 합니다. 그래서 아날로그 출력 단자를 사용합니다. 진폭변조 단자라고 하는데 아두이노 보드에 보면 디지털 핀 밑에 PWM이라고 써져 있는 3,5,6,9,10,11번 핀에발광 다이오드를 연결하면 됩니다.
ⓞ 진폭변조
진폭 변조는 디지털적인 방법으로 아날로그와 같은 효과를 얻기 위한 방법입니다.
값은 디지털의 ON(1), OFF(0)값만을 사용하지만 지속시간을 변경하는 방법으로 빛의 밝기를 조절할 수 있습니다.
예를 들어, 출력값이 0이면 5v의 지속시간이 0%를 뜻하므로 0v만 계속 흐르게 되어 꺼져 있는 상태가 됩니다. 출력값을 127로 지정하면 255범위 중 50%가 되어 5V 지속시간이 50%이므로 중간 정도의 밝기를 갖게 됩니다. 255로 지정하면 100% 상태가 되어 가장 밝은 상태가 되겠지요. 이렇게 출력값에 따라 0,과 1의 지속 시간을 조절하여 아날로그적인 효과를 내는 것을 진폭변조라고 합니다.
ⓞ analogWrite() 이용한 LED 출력
아두이노가 발광 다이오드에 불을 켜려면 analogWrite()함수를 사용하면 되는데 인자를 출력단자번호와 출력값을 넘겨주면 되는데 여기서 출력값은 0 ~ 255 사이의 값입니다. 광센서에서 입력받은 빛의 밝기는 0 ~ 1023범위의 값이므로 범위를 조정해 주는 작업이 필요합니다.
이때 사용하는 함수가 map() 함수입니다.현재 범위값과 조정하고자 하는 범위값을 같이 map()함수에 넣어주면 조정된 범위에 맞는 값을 반환해 줍니다 그래서 map() 함수를 먼저 사용해 값의 범위를 조정하고 거기서 반환된 값을 analogWrite()의 출력값으로 사용하면 됩니다.
ⓞ 스케치 순서도
그림과 같이 순서도를 먼저 살펴 보면 먼저 발광다이오드 출력용 핀 하나를 설정합니다.
이 부분은 실제로 동작을 하기 위한 준비과정입니다. 그런 다음, 0 ~ 1023 사이의 값인 전압값을 입력받은 다음 0 ~ 255 사이의 값으로 범위를 조정합니다.
그리고 그 값의 반대값을 구합니다.
가로등은 주변이 어두우면 밝게 밝으면 어둡게 켜야 하기 때문에 주변 밝기 값의 반대값을 발광다이오드가 연결된 단자에 전송해 발광 다이오드를 켭니다.
우리가 원하지 않는 가짜신호를 제거하기 위해 잠깐 대기하고 위의 과정을 무한 반복합니다.
정수형 변수 lightPin과 ledPin을 선언해서 0과 3을 대입했습니다.
0번 단자와 3번 단자를 사용하겠다는 뜻입니다. setup() 함수에서는 pinMode함수를 호출하여 ledPin핀을 모두 출력으로 설정하였습니다. 그 다음 loop()함수가 시작됩니다. loop()함수 내부에 있는 문장들은 무한히 반복됩니다.
먼저, 광센서에서 현재 주변 빛의 밝기를 읽어야 하므로 analogRead()함수를 호출하여 lightPin의 전압값을 읽어 변수 lightValue에 대입합니다.
그 다음, map()함수를 호출하여 0 ~ 255 범위 내의 값으로 조정하여 lightValue에 다시 대입합니다. 이제analogWrite() 함수를 호출하여 255에서 lightValue를 뺀 값을 인자로 넘겨줍니다. 그 이유는 주변밝기가 어두울 때 밝게 밝으면 어둡게 설정해야 하기 때문입니다.
그리고 delay(100)함수를 호출하여 100밀리초간 대기 명령을 줍니다.
광센서를 가리고 발광 다이오드에 불이 켜지는지 확인해 보세요. 그리고 빛에 노출시켜보고 발광다이오드가 꺼지는지도 확인해 봅시다. 플래시가 있다면 비춰보는 것도 좋습니다. 광센서로 인식한 주변 빛의 밝기에 따라 다양한 빛의 밝기로 발광 다이오드가 켜집니다.
int lightPin = 0; int ledPin = 3; void setup() { pinMode(ledPin, OUTPUT); } void loop() { int lightLevel = analogRead(lightPin); lightLevel = map(lightLevel, 0, 1023, 0, 255); analogWrite(ledPin, 255 - lightLevel); delay(100); }