반응형

【 아두이노초급#5포토레지스터 CDS사용 입·출력 실습 

1

 

 CDS(Cadmium Sulfide : 황화카드뮴 소자)또는 포터 레지스터(Photo Resistor)라 불리는 센서를 가지고 아두이노 입출력 실습을 진행합니다.

▶ 주요 내용
- CDS에 대한 개념, 동작원리
- PWM(pulse width modulation) 정의와 아두이노에서 사용 방식
- 아두이노에서의 입력함수, 출력함수에 대한 사용방법 정리
     [ analogRead ( ) , analogWrite ( ) , digitalRead ( ) , digitalWrite ( ) ]
- CDS 신호 처리 하여, LED의 밝기 조절에 대한 아두이노 코딩과 실습

 CDS는 기본적으로 저항의 역할을 합니다.   그래서, 아래 CDS의 기호에 저항의 이미지가 들어가 있죠. 
그리고, 기호에 보면, 외부로부터의 빛을 받아들이는 것을 의미하는 화살표로 구성되어 있듯이, 빛에 따라 저항값이 바뀌는 특성이 있는 소자입니다.

CDS 센서의 기호

주변이 밝아 센서 표면에 유입되는 빛이 많을수록 저항값이 0Ω에 가까워지고(약 1㏀),  주변이 어두울수록 저항값이 급격하게 커지는(약 10MΩ) 특성을 가집니다.
이런 특성을 이용하면 빛의 밝기를 이용해서, 입력되는 전압(전류)의 크기를 제어할 수 있습니다.
아래에 보이는 회로를 참고하여 CDS 및 기타 부품들을 준비하고 회로를 연결해 주세요.  (CDS 종류나 크기에 상관없이 준비된 것으로 연결하면 됩니다.)

동작 원리를 설명드리면, 적당한 빛이 있을 때 CDS는 특정한 저항값을 가지게 되며,  CDS와 함께 직렬로 연결된 10㏀의 저항에 5V의 전압이 분배되어 걸리게 됩니다.

만약, CDS 주변의 밝기가, CDS의 저항값을 10㏀으로 변화시켰다면,  그래서, 직렬로 연결된 10㏀의 저항과 같은 값이 될 경우,  공급되는 5v 전압은 CDS와 저항 각각에 1/2로 분배되어, 2.5v의 전압이 A0로 입력됩니다. (아래 그림)

 

 그런데, CDS 주변을 아주 밝게 하여 CDS의 저항값이 거의 0Ω에 이르렀다면,  5v의 전원이 10㏀에 모두 걸리게(강하) 되고, 그러면 A0에 이 5v의 전압이 입력되게 됩니다. (아래 그림)

 

 

 그리고 만약, 주변을 아주 어둡게 하여 CDS의 저항값이 거의 수십㏁에 이르렀다면,  직렬연결된 10㏀의 저항값은 CDS의 저항값에 비해 무시할 정도로 작게 되고, 5v의 전원 대부분이 CDS에 걸리게(전압강하) 되어, 이 부분의 전위는 0v (GND)에 가깝게 됩니다. (아래)

이런 원리로, CDS 주변의 밝기에 따라 A0 포트로 0v ~ 5v 사이의 전압이 입력됩니다. 
아두이노의 Analog 입력 포트(A0~A5) 쪽에는 입력된 아날로그 전압 값을 디지털 값으로 변환시켜주는 A/D Converter가 내장되어 있습니다.
우노(나노)에 들어 있는 A/D Converter는 10bit의 분해능(해상력)을 가지고 있는데, 10bit는 2의 10승, 즉 1024의 값이며 아날로그 포트(A0~A5)로 입력되는 0v~5v의 전압을 0~1023의 수치로 변환받을 수 있게 됩니다. (아래)

이때, 아날로그 포트로 아날로그 값을 읽어 들이기 때문에, analogRead(pin)라는 함수를 사용합니다.

이렇게 읽어 들인 수치(0~1023)를 가지고 if 비교문 등을 이용해서, 디지털 포트에 연결된 LED를 켜고 끄거나, 밝기(PWM)를 조절할 수 있습니다.

아두이노의 입출력 함수에 대해 한 번 정리해 드릴게요.
아날로그 포트는 0~5v의 전압을 입력만 받을 수 있는 포트입니다. 따라서 하드웨어적으로 아날로그 포트로 출력은 할 수 없습니다.  아날로그 포트로 데이터(전압)를 입력받을 때는 ‘analogRead ( )’함수를 사용합니다. 



아두이노 디지털 포트로는 입력과 출력이 가능하며,  디지털 포트를 통해 데이터(전압)를 입력 받을 때는‘digitalRead( )’함수를 사용하고,  출력할 때는,‘digitalWrite( )’함수를 사용합니다. 
또한, PWM 방식을 통해 아날로그적인 값(전압)을 디지털 포트로 출력하고자 할 때는 ‘analogWrite( )’함수를 사용합니다.  ( 단, ~기호가 붙은 11, 10, 9, 6, 5, 3번 핀들만 가능합니다 )   (아래)

 

High 신호일 때는 5v 출력을 하고,  Low 신호일 때, 0v 로만 출력시킬 수 있습니다. 
그래서 0v~5v 사잇값 출력이 안 되어 LED 밝기 조절이 안 되고, On/Off 만 하게 됩니다. 
그런데, PWM(pulse width modulation)이라는 방식을 이용하면 마치 아날로그처럼 0v~5v 사잇값을 출력시킬 수 있습니다. 
PWM 방식은 펄스 형태로 High와 Low 신호의 비율(듀티비)을 조절하여 출력하는 방식이며 High 신호의 비율이 높을수록 평균 전압이 5v에 가까워지고, 낮을수록 0v에 가까워집니다.  
그래서, 듀티비를 조절하여 아날로그처럼, 0v~5v 사잇값도 출력할 수 있게 됩니다. 
이런 방법으로 LED의 밝기를 조절할 수 있게 됩니다.

듀티비(Duty)가 높을수록 높은 전압이 출력되고, 낮을수록 낮은 전압이 출력됩니다.
(듀티비 100% : 5v ,  듀티비 50% : 2.5v ,  듀티비 0% : 0v)

당연히 전압이 높을 때, LED가 밝고,  낮은 전압일 때, LED가 어둡게 켜집니다.

아두이노에는 이런 PWM 출력을 할 수 있는 포트가 정해져 있는데요, 포트 번호 옆에 ~ 물결무늬 표시가 있는 포트만 PWM 출력이 가능합니다.  일반적인 디지털 포트 출력은 digitalWrite( pin , value ) 명령어를 사용합니다.

Value가 HIGH 일 때는 5v의 전압이 출력되고, LOW 일때는 0v로 출력되어,    LED가 최대로 밝거나 혹은, LED가 꺼져있는 두 가지 형태만 가능합니다. 


그런데, ~PWM 포트에는 digitalWrite(  ) 명령어뿐 아니라, analogWrite(pin, value)라는 명령어를 사용할 수 있습니다. 
pwm 디지털 포트의 출력은 8bit로 이루어지기 때문에, 최대 2의 8승 값인 256, 즉, 0 ~ 255 사잇값을 value 값으로 출력해 줄 수 있고, 0이면 LED가 제일 어두우며(꺼짐), 127은 중간값, 255 일 때 최대 밝기가 됩니다. 
이렇게 해서 디지털 포트로 밝기 조절과 같은 아날로그 적인 출력 표현이 가능합니다. (아래)

아두이노 코드는 아래를 참고하거나 직접 다운로드하여 보세요.

int LED=9;    //우노에서는 디지털 포트는 숫자만 입력함
int LIGHT=A0; //아날로그 포트는 A0, A1,...형태로 입력함
int val=0;
int fix=0;
void setup() {
 pinMode(LED,OUTPUT);
 Serial.begin(9600);
}
void loop() {
 val=analogRead(LIGHT); 
 int val2 = map(val,0,340,255,0); 
 int val3 = constrain(val2,0,255);
 Serial.println(val3); 
 analogWrite(LED,val3);    
// delay(100);
}

 아두이노 파일입니다.  다운로드한 후 압축을 풀어서 사용하세요.

CDS.zip
0.00MB

CDS는 크기별 종류가 있으며, 5pi(5mm), 7pi, 10pi, 20pi ... 

이미지 참조 : www.societyofrobots.com


제조사별 및 품번 별로도 약간의 다른 특성을 지니고 있는데요,
빛에 따라 반응하는 저항값의 범위가 조금 다르고, 허용 최대 전압이 조금 다를 뿐이어서 이런 실험에서는 크기나 종류에 크게 영향이 없으니 어떤 것이든 실습에 사용하면 됩니다.

그럼, CDS를 연결해 주고, 코드를 빌드&업로드해 주세요. 
시리얼 모니터를 열어보면, 현재 주변의 밝기에 따른 입력값이 나오는 것을 볼 수 있습니다. 
그리고 손으로 가려보면, 수치가 작아지고, 오픈하면 수치가 올라갑니다. 
빛에 노출되는 정도에 따라, 수치가 변하는 것을 볼 수 있는데요,  수치는 CDS의 종류에 따라 달라지기도 하지만, 현재 놓인 장소의 밝기에 따라 달라지게 됩니다. 



그럼, 다른 종류의 CDS도 있으면 바꾸어 실험해 보세요.  
CDS의 종류에 따라서도 입력되는 값의 범위가 다름을 알 수 있습니다. 
따라서, 제공해드리는 코드를 그대로 사용하지 말고, 한 가지 변경해 주어야 하는데요,
밝기의 최소·최대 값 범위를 확인해서, LED의 출력 값 범위와(0~255)와 매핑(매칭)을 시켜야 합니다.  
이렇게 하여야, 현재 주변의 밝기에 따라 LED의 밝기 조절을 최대로(0~255) 할 수 있게 됩니다. 
이를 위해 화면에 보이는 매핑 함수를 사용합니다. 

'값'에는, CDS로부터 값이 입력되는 변수를 써주고,  fromLow, fromHigh 두 자리에는 CDS를 어둡게 했을 때의 최솟값과 밝게 했을 때의 최댓값을 적으세요. 
그리고, toLow, toHigh 두 자리에는 LED의 최대 범위 0과 255를 각각 적습니다. 
그리고, 매핑된 값을 시리얼 모니터로 확인해 보기 위해, val2로 바꾸어 주세요. 
코드는 순차적으로 컴파일되기 때문에, Serial.println(val2)는 val2 변수 선언 이후로 내려 주세요. 
그럼, 컴파일&업로드해서 확인해 보세요. 
약간의 오차가 있겠지만 0~255 범위를 크게 벗어나지 않을 거예요. 
그리고, 좀 더 나아가서 아예 0보다 작고 255보다 큰 값들은 제거해 버리도록 constrain( ) 함수를 써서 처리할 수 있어요.
constrain( ) 처리한 값은 val3에 저장하고,  마찬가지로 serial.println(val3) 문장을 val3선언 이후로 내려주면 됩니다. 
다시 업로드해서 값을 확인해 보세요. 


constrain( val3, 0, 255 ) 처리를 하면, 해당 값 이하(0)와 이상(255)은 잘라버리기 때문에,  해당 값 이외의 숫자가 나오면 안 되는 경우에 활용하면 좋습니다.   
이렇게 하면, LED 밝기를 최대 범위(0~255 : 0v~5v)로 컨트롤할 수 있습니다. 

 만약, CDS가 바뀌거나 실험 장소가 바뀌면 다시 A0로 입력되는 값을 실측해서 적용해 주어야 합니다.
첨부해드린 코드에는 , CDS주변이 어두우면 LED가 점점 어두워지고, 주변이 밝으면 LED가 밝게 작동하는데요,
이 작동을 반대로 하려면,“map( val, 최솟값, 최댓값, 255, 0 )”으로 LED값을 반대로 해주면 됩니다. 

이상으로 포터레지스터 소자인 CDS에 대한 아두이노 입출력 실습을 진행했습니다.
감사합니다.

【 실습과정 영상으로 보기 】

 

반응형