[아두이노] 조도센서(LDR)과 풀다운(Pull-Down), 그리고 캘리버레이션(Calibration)
조도센서에 풀다운 저항을 사용하는 이유와 캘리버레이션(Calibration) 기법
이번 실험의 주제는 조도센서의 캘리버레이션 기법입니다. 캘리버레이션(Calibration)은 아날로그 입력값의 하한과 상한을 검출하는 것을 의미합니다. 조도센서의 캘리버레이션을 위해 아두이노 보드 구동후 5초 동안 하한과 상한 검출을 수행하고, 캘리버레이션 결과값을 기준으로 조도센서의 입력을 LED 밝기 조정에 매핑(mapping) 시켜 보겠습니다.
우선 회로는 아래와 같이 구성됩니다.
코드를 리뷰하기 전에 조도센서에 풀다운 저항을 연결하는 이유에 대해 고찰할 필요가 있습니다. 아래 회로를 보겠습니다.
전류 Isensor 는 LDR의 저항과 R2, Rin에 의해 결정됩니다. Rin은 아두이노 입력핀쪽에 위치한 MCU에는 내부 저항이 있는데 이것을 임피던스라고 부르기도 합니다. 대락 10MΩ 정도의 큰 저항입니다. LDR의 저항이 주변 빛의 양에 따라 가변적이므로 전압 또한 가변적입니다.
R2와 Rin이 병렬로 연결되어 있지만 Rin값이 매우 크기 때문에 LDR 아래쪽의 저항은 아래와 같이 기존 R2와 별 차이 없이 10kΩ 정도가 됩니다.
조도센서의 저항이 최대 10kΩ인 경우 Isensor에 인가되는 전압은 아래와 같습니다.
정리하자면, 10kΩ 풀다운 저항을 사용하면, 조도센서의 상태에 따라 2.5V에서 5V 사이의 전압편차를 보인다는 것입니다. 만약에 풀다운 저항을 사용하지 않으면 어떻게 될까요?
풀다운 저항이 사용되었던 상황과 마찬가지로, 조도센서의 저항이 최대 10kΩ인 경우 Isensor 에 인가되는 전압은 아래와 같이 구할 수 있습니다.
위 계산에서 알 수 있듯이 Isensor에는 거의 5V가 인가됩니다. 즉, 조도센서의 저항값이 변해도 전압의 변화폭의 거의 없다는 의미입니다. 전압의 편차가 거의 없으면 빛의 변화 또한 인지하지 못하게 되는 것입니다.
const int ledPin = 9; // LED가 연결된 핀번호
결론적으로 조도센서에 사용되는 풀다운 저항은 조도센서의 저항값 변화에 따른 적절한 전압 편차를 만들기 위해 사용됩니다.
테스트용 코드는 아래와 같습니다.
const int sensorPin = A0; // 조도센서가 연결된 핀번호const int ledPin = 9; // LED가 연결된 핀번호
int sensorValue = 0; // 조도센서 아날로그값
int sensorMin = 1023; // 조도센서 아날로그 최소값 저장
int sensorMax = 0; // 조도센서 아날로그 최대값 저장
void setup() {
// 캘리브레이션 동작중에 13번핀 내부 LED ON
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
int sensorMin = 1023; // 조도센서 아날로그 최소값 저장
int sensorMax = 0; // 조도센서 아날로그 최대값 저장
void setup() {
// 캘리브레이션 동작중에 13번핀 내부 LED ON
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
// 5초 동안 캘리브레이션 수행
while (millis() < 5000) {
sensorValue = analogRead(sensorPin);
while (millis() < 5000) {
sensorValue = analogRead(sensorPin);
// 최대값 검출
if (sensorValue > sensorMax) {
sensorMax = sensorValue;
}
// 최소값 검출
if (sensorValue < sensorMin) {
sensorMin = sensorValue;
}
}
// 내부 LED OFF
digitalWrite(13, LOW);
}
void loop() {
// 조도센서 아날로그값 읽기
sensorValue = analogRead(sensorPin);
// 조도센서 아날로그값을 LED 아날로그값으로 매핑
sensorValue = map(sensorValue, sensorMin, sensorMax, 0, 255);
if (sensorValue > sensorMax) {
sensorMax = sensorValue;
}
// 최소값 검출
if (sensorValue < sensorMin) {
sensorMin = sensorValue;
}
}
// 내부 LED OFF
digitalWrite(13, LOW);
}
void loop() {
// 조도센서 아날로그값 읽기
sensorValue = analogRead(sensorPin);
// 조도센서 아날로그값을 LED 아날로그값으로 매핑
sensorValue = map(sensorValue, sensorMin, sensorMax, 0, 255);
댓글
댓글 쓰기