[아두이노] [강좌] 14. analogRead()/analogWrite() 실습 - 조도 센서 + LED

analogRead() 함수와 analogWrite() 함수에 대해 모두 배웠으니, 이제 두 함수를 동시에 이용하는 예제를 실습해보자. 제목에 나와 있듯이, 조도 센서와 LED를 사용하는 예제.


조도 센서는 빛의 세기를 읽는 센서이고, LED는 빛을 내는 센서(? 뭐지? 센서는 아닌데 뭐라고 해야 할 지 모르겠는 이 느낌적인 느낌은?).


그래서 조도 센서의 값을 읽어서 주변 밝기에 따라 LED의 밝기를 조절하는 예제를 만들어보자. 


센서(하나는 LED지만) 두 개로 실습하는 예제는 처음이라 두근두근. 



조도 센서와 LED는 다음 그림과 같이 아두이노 보드와 연결하자. 조도 센서는 TEMT6000을 사용.


c864663e98a5a1d8ee702e9b82b7ae93.png


아.. 다른 사람이 선 연결 그려놓은거 보면 되게 깔끔하던데...brown_and_cony-31


암튼, "강좌 10. analogRead() 함수"에서 설명했던 조도 센서와 "강좌 13. LED 밝기 조절하기"에서 설명한 LED 연결이 합해진 것 뿐, 새로 나온 건 없으므로 설명은 생략하고 지나간다.



그리고는 예제 소스를 열어보자. 스케치 툴의 "파일→예제→03.Analog→AnalogInOutSerial" 열기.



 AnalogInOutSerial.ino

 

 const int analogInPin = A0;

 const int analogOutPin = 9;


 int sensorValue = 0;

 int outputValue = 0;


 void setup() {

   Serial.begin(9600);

 }


 void loop() {

   sensorValue = analogRead(analogInPin);

   outputValue = map(sensorValue, 0, 1023, 0, 255);

   analogWrite(analogOutPin, outputValue);


   Serial.print("sensor = " );

   Serial.print(sensorValue);

   Serial.print("\t output = ");

   Serial.println(outputValue);


   delay(100);

 }





마지막에 delay() 값을 100밀리초로 수정했다. 아두이노 보드도 힘드니까.



소스 중 대부분은 이미 설명했던 내용들이고, map()이라는 함수가 새로 나왔다. map() 함수는 일정 범위의 값을 비율에 맞춰 지정한 범위의 값으로 바꿔주는 함수이다. 음? 




예를 들어 1~100 사이의 값들 중 50이라는 값을 1~1000 사이의 값들 중 같은 위치의 값으로 바꾸고 싶으면 어떻게 해야 할까? 즉, 1은 1로 그대로 두고, 100을 1000으로 늘렸을 때, 50은 얼마만큼 늘어날까? 수학, 수학!



보자.. 50:100=x:1000 이니까, 100x=1000*50 이고, 그럼 x=1000*50/100 이니까, 계산하면 '500'이군! 이정도 쯤이야. ㅋㅋㅋㅋㅋㅋ



자, 그럼 200~500 사이의 값들 중 300이라는 값을 500~1000 사이의 값들 중 같은 위치의 값으로 바꾸려면?? 음... 음?? 300:500 이긴 한데, 200부터 시작하니까........ 음?????????



brown_and_cony-61 

(수학을 잘 하는 사람은 금방 계산 되겠지만, 난 안돼...)




이 계산을 해주는 함수가 바로 map() 함수이다. map() 함수의 매개 변수와 반환 값은 다음과 같다.




long map(value, fromLow, fromHigh, toLow, toHigh)



 

 매개 변수


 value : 같은 위치로 변환하고 싶은 값


 fromLow : value 값이 위치하는 범위의 가장 낮은 값


 fromHigh : value 값이 위치하는 범위의 가장 높은 값


 toLow : 바꾸고 싶은 범위의 가장 낮은 값


 toHgih : 바꾸고 싶은 범위의 가장 높은 값 


 


 

 반환 값


 long 타입의 정수 : 바꾸고 싶은 범위에서 value 값과 동일한 위치의 값


 



그럼 위에서 예로 든 값을 구해볼까? 200~500 사이의 값들 중 300이라는 값을 500~1000 사이의 값들 중 같은 위치의 값으로 바꾸려면?



 long value = map(300, 200, 500, 500, 1000);

 



이라고 하면 되겠지. 아, 편리한 함수구먼.



다시 예제로 돌아가자. 소스를 잠깐 설명하자면, 


 const int analogInPin = A0;

 const int analogOutPin = 9;


아날로그 입력 기능으로 사용하기 위한 핀 번호를 'analogInPin'이라는 변수에 저장하고(A0), 아날로그 출력(PWM) 기능으로 사용하기 위한 핀 번호를 'analogOutPin'이라는 변수에 저장하고 있다(9). 여기서 'const'가 앞에 붙은 건, 이 변수들의 값이 프로그램 도중에 변하지 않는 '상수' 값이라는 것을 의미. 핀 번호가 프로그램이 실행되는 중에 바뀔 일은 없으니 붙여준 듯. 


음.. 'const'에 대한 설명은 또 줄줄이 사탕이 될 것 같으니 패스.


 int sensorValue = 0;

 int outputValue = 0;


그리고 또다른 변수 'sensorValue'와 'outputValue'를 선언한 후 0으로 초기화해주고.


 void setup() {

   Serial.begin(9600);

 }

 


setup() 함수에서는 시리얼 모니터 출력을 위해 Serial.begin() 함수를 호출한다. 보레이트는 9600.


시리얼 출력에 대한 내용이 예제에 자주 등장하는 것은, 센서들의 값이나 핀으로 입력되는 값들 등을 직접 눈으로 확인할 수 있는 가장 간단한 방법이기 때문인데, 다음 강좌에서 "Serial"에 대한 내용을 다루도록 하겠다. 그 동안 그냥 시리얼 모니터 출력을 위한 함수라고만 하고 넘어가서 계속 찜찜해쪄.



...




 sensorValue = analogRead(analogInPin);

 outputValue = map(sensorValue, 0, 1023, 0, 255);

 analogWrite(analogOutPin, outputValue);

 


loop() 함수의 내용이다. analogRead() 함수를 이용해서 조도 센서(조도 센서 실습인 거 잊어먹을 뻔..)의 값을 sensorValue 변수에 저장한다. 그리고는 조금 전에 배운 map() 함수. 


기억하고 있을지 모르겠지만, analogRead() 함수에서 반환되는 값은 0~1023 사이의 값이다. 0V에서 5V의 구간을 1024개로 나눈다고 했으니까. 


그리고 analogWrite() 함수에 듀티비를 나타내는 값으로 들어갈 수 있는 값은 0~255 사이의 값이었다. 0을 주면 0%의 듀티비를 가진 PWM 출력, 255를 주면 100% 듀티비를 가진 PWM 출력.


 그래서, 조도 센서에서 읽은 값이 0이면 LED 밝기로 0을 주고, 조도 센서 값이 1023이면 LED 밝기로 255를 주고, 조도 센서 값이 그 중간 어딘가라면 그 중간 어딘가에 위치하는 밝기 값을 LED에 주기 위해서 map() 함수를 사용. 즉, 0~1023 사이의 값 중 sensorValue 값을 0~255 사이의 값으로 바꿈.


그리고 그 값을 'outputValue' 변수에 저장해서 analogWrite() 함수로 LED의 밝기를 조절한다.



 Serial.print("sensor = ");

 Serial.print(sensorValue);

 Serial.print("\t output = ");

 Serial.println(outputValue);

 


시리얼 모니터로도 그 값을 확인하기 위해 Serial.print() 함수와 Serial.println() 함수를 이용하여 출력. 매개 변수에 ""로 묶은 부분은 그 문자열 그대로 출력되고, 매개 변수에 변수가 들어가면 그 변수 값이 출력됨. 




자, 업로드 해보자. 시리얼 모니터도 실행하고.


조도 센서를 손으로 가렸다가, 빛을 비췄다가 하면서 값을 바꿔보고, 그 값이 변하는 것에 따라 LED의 밝기가 변하는지도 확인하자. 



오. 변한다.



조도 센서의 값이 커지면 LED도 밝아지고, 조도 센서의 값이 작아지면 LED도 어두워진다. 




근데, 뭔가 이상하네. 내가 원한건 이 동작이 아닌 듯. 난 주위가 밝으면 LED가 어두워지고, 주위가 어두워지면 LED가 밝아졌으면 좋겠는데. 이건 반대로 동작하네.


즉, 조도 값이 낮으면 LED로 내보내는 PWM의 듀티비가 커야 한다는 말. 어떻게 바꿀까?



쉽다. 한 줄만 바꾸면 된다. 



 AnalogInOutSerial2.ino

  

 const int analogInPin = A0;

 const int analogOutPin = 9;


 int sensorValue = 0;

 int outputValue = 0;


 void setup() {

   Serial.begin(9600);

 }


 void loop() {

   sensorValue = analogRead(analogInPin);

   outputValue = map(sensorValue, 0, 1023, 255, 0);

   analogWrite(analogOutPin, outputValue);


   Serial.print("sensor = " );

   Serial.print(sensorValue);

   Serial.print("\t output = ");

   Serial.println(outputValue);


   delay(100);

 }


 



map() 함수로 sensorValue 값을 바꿀 때 toLow 값과 toHigh 값을 바꾸면 반대 위치의 값이 나온다는 말. 0일 때 255로, 1023일 때 0으로. 


업로드 한 후 확인해보자. 손으로 조도 센서를 가려 어둡게 만들면 LED가 밝아지고, 빛을 비춰 밝게 만들면 LED가 어두워지는 것이 보이는가? 




moon_and_james-2 




지금 우리는 "자동 밝기 조절 전등"을 만든 셈이다. 완전 대다나다!


이러다 우주선 만드는거 아님? ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 아두이노로 3D 프린터도 만드는데, 우주선이라고 못만들까. ㅋㅋㅋㅋㅋㅋ




자, 그 날을 꿈꾸며. 이번 시간은 여기서 안녕~

0
0
이 글을 페이스북으로 퍼가기 이 글을 트위터로 퍼가기 이 글을 카카오스토리로 퍼가기 이 글을 밴드로 퍼가기

임베디드 보드

번호 제목 글쓴이 날짜 조회수
118 아두이노 ESP32 Analog Inputs (ADC) +4 icon 양재동메이커 02-12 16,810
117 아두이노 TIP : Serial의 Port가 Open 시점 확인 icon 양재동메이커 01-21 13,544
116 아두이노 ESP32 Boot Mode icon 양재동메이커 12-28 13,421
115 아두이노 아두이노 에러 리스트(Arduino Error list) icon 양재동메이커 11-24 18,509
114 아두이노 ESP32 main.cpp +1 icon 양재동메이커 11-19 13,761
113 아두이노 ESP32 EEPROM 와 IR Remote icon 양재동메이커 08-06 13,624
112 아두이노 Learn ESP32 icon 양재동메이커 06-25 13,179
111 라즈베리 파이 라즈베리 파이 (Raspberry Pi) 기초 icon 양재동메이커 06-19 14,790
110 라즈베리 파이 (동영상 강의) 라즈베리 파이 강좌 Link icon 양재동메이커 06-17 13,769
109 STM32 / MBED [MED] Switch debouncing icon HellMaker 12-30 15,887
108 기타 [타이젠] 아두이노의 16x2 LCD Display라이브러리 LiquidCrystal_I2C의 타이젠 포팅 icon 양재동메이커 09-15 15,532
107 기타 [타이젠] GPIO의 디지탈 출력과 입력 인터럽트의 C++ Class 제작 icon 양재동메이커 09-12 14,863
106 마이크로비트 서보 모터 icon HellMaker 09-03 14,639
105 마이크로비트 아날로그 온도센서 (마이크로 비트 센서 활용) icon HellMaker 09-01 15,215
104 마이크로비트 터치센서 (마이크로 비트 센서 활용) icon HellMaker 09-01 14,261
103 마이크로비트 디지털 홀 센서 (마이크로 비트 센서 활용) icon HellMaker 08-29 13,482
102 마이크로비트 리니어 홀 센서 (마이크로 비트 센서 활용) icon HellMaker 08-29 12,926
101 마이크로비트 불꽃 감지 센서 (마이크로 비트 센서 활용) icon HellMaker 08-26 13,306
100 마이크로비트 로터리 엔코더 (마이크로 비트 센서 활용) icon HellMaker 08-25 13,449
99 마이크로비트 2컬러 LED(3mm) (센서 활용) icon HellMaker 08-22 13,416