ماژول مقاومت وابسته به نور
(LDR)
Analog LDR Module
LDR Light Dependent Resistor
[table id=38 /]
ماژول مقاومت وابسته به نور (LDR) یک سنسور نوری مقاومتی که مقدار مقاومت آن با شدت نور محیط معکوس تغییر میکند. این ماژول با مدار مقایسهگر و ADC، امکان خواندن آنالوگ و تشخیص دیجیتال سطح نور را فراهم میکند.
☀️ ویژگیهای اصلی
🔹 سنسور LDR با کیفیت – پاسخ سریع به تغییرات نور
🔹 خروجی دوگانه – آنالوگ (ADC) + دیجیتال (مقایسهگر)
🔹 مقایسهگر قابل تنظیم – با پتانسیومتر برای آستانه دلخواه
🔹 LED نشانگر – فعال بودن خروجی دیجیتال
🔹 ولتاژ کاری گسترده – 3.3V تا 5V
🔹 نصب آسان – پایههای استاندارد 2.54mm
📊 مشخصات فنی دقیق
سنسور LDR:
-
نوع: Cadmium Sulfide (CdS) Photoresistor
-
مقاومت در تاریکی: 1MΩ – 10MΩ (تایپیکال: 2MΩ)
-
مقاومت در نور (10 لوکس): 5KΩ – 20KΩ (تایپیکال: 10KΩ)
-
مقاومت در نور کامل (100 لوکس): 500Ω – 2KΩ
-
زمان پاسخ: 15ms – 50ms
-
دامنه طیفی: 400nm – 700nm (حساس به نور مرئی)
-
توان نامی: 100mW
-
دمای کاری: -30°C تا +70°C
مشخصات الکتریکی ماژول:
-
ولتاژ کاری: 3.3V – 5V DC
-
جریان مصرف: 1mA – 5mA
-
خروجی آنالوگ: 0V تا Vcc (مستقیماً از تقسیم ولتاژ)
-
خروجی دیجیتال: HIGH/LOW (از مقایسهگر LM393)
-
پتانسیومتر تنظیم: 10KΩ چند دور
-
مقاومت سری LDR: 10KΩ دقیق ±1%
-
مقایسهگر: LM393 Dual Comparator
-
LED نشانگر: قرمز (فعال بودن خروجی دیجیتال)
پیکربندی پایهها:
پین 1: VCC (3.3V - 5V)
پین 2: GND
پین 3: DO (Digital Output) - خروجی دیجیتال
پین 4: AO (Analog Output) - خروجی آنالوگ
*DO زمانی HIGH میشود که نور از آستانه تنظیم شده کمتر باشد
مدار داخلی:
VCC → LDR → AO → میکروکنترلر (آنالوگ)
↓
مقاومت 10KΩ → GND
AO همچنین به مقایسهگر LM393 وارد میشود
پتانسیومتر آستانه ←→ LM393 ←→ DO
ابعاد فیزیکی:
-
ابعاد PCB: 32mm × 14mm × 8mm
-
فاصله پایه: 2.54mm استاندارد
-
سوراخ نصب: 3mm
-
وزن: 3 گرم
-
رنگ: آبی با ماسک
-
نوع LDR: گلوبی شکل با لنز پخشکننده
🔌 نحوه اتصال و راهاندازی
اتصال به آردوینو:
#define LDR_ANALOG_PIN A0
#define LDR_DIGITAL_PIN 2
void setup() {
Serial.begin(9600);
pinMode(LDR_DIGITAL_PIN, INPUT);
Serial.println("ماژول LDR راهاندازی شد");
Serial.println("========================");
}
void loop() {
int analogValue = analogRead(LDR_ANALOG_PIN);
bool digitalState = digitalRead(LDR_DIGITAL_PIN);
float voltage = analogValue * (5.0 / 1023.0);
float ldrResistance = 10000.0 * (5.0 / voltage - 1.0);
Serial.print("آنالوگ: ");
Serial.print(analogValue);
Serial.print(" | ولتاژ: ");
Serial.print(voltage, 2);
Serial.print("V | مقاومت LDR: ");
Serial.print(ldrResistance / 1000.0, 1);
Serial.print("KΩ | دیجیتال: ");
Serial.println(digitalState ? "HIGH (تاریک)" : "LOW (روشن)");
delay(1000);
}
تنظیم پتانسیومتر آستانه:
روش تنظیم:
1. نور محیط را در سطح مورد نظر تنظیم کنید
2. پتانسیومتر را بچرخانید تا LED نشانگر روشن/خاموش شود
3. در این نقطه، آستانه روی همان سطح نور تنظیم شده است
4. وقتی نور از این آستانه کمتر شود، خروجی دیجیتال HIGH میشود
کلاس مدیریت پیشرفته LDR:
class LDRSensor {
private:
int analogPin;
int digitalPin;
int referenceResistor;
float vcc;
float darkResistance;
float lightResistance;
public:
LDRSensor(int aPin, int dPin, int refR = 10000, float voltage = 5.0) {
analogPin = aPin;
digitalPin = dPin;
referenceResistor = refR;
vcc = voltage;
pinMode(digitalPin, INPUT);
darkResistance = 2000000.0;
lightResistance = 10000.0;
}
int readRaw() {
return analogRead(analogPin);
}
float readVoltage() {
int raw = readRaw();
return raw * (vcc / 1023.0);
}
float calculateResistance() {
float voltage = readVoltage();
if(voltage <= 0) return -1;
float ldrResistance = referenceResistor * ((vcc / voltage) - 1.0);
return ldrResistance;
}
float estimateLux() {
float resistance = calculateResistance();
if(resistance <= 0) return 0;
float logResistance = log10(resistance);
float logDark = log10(darkResistance);
float logLight = log10(lightResistance);
float lux = pow(10,
((logResistance - logDark) / (logLight - logDark)) * 3 + (-1)
);
return lux;
}
bool isDark() {
return digitalRead(digitalPin) == HIGH;
}
bool isBright() {
return !isDark();
}
void calibrateDark() {
Serial.println("کالیبراسیون تاریکی: سنسور را در تاریکی کامل قرار دهید");
delay(5000);
darkResistance = calculateResistance();
Serial.print("مقاومت تاریکی ثبت شد: ");
Serial.print(darkResistance / 1000.0);
Serial.println("KΩ");
}
void calibrateLight() {
Serial.println("کالیبراسیون نور: سنسور را در نور مناسب قرار دهید");
delay(5000);
lightResistance = calculateResistance();
Serial.print("مقاومت نور ثبت شد: ");
Serial.print(lightResistance / 1000.0);
Serial.println("KΩ");
}
void printInfo() {
int raw = readRaw();
float voltage = readVoltage();
float resistance = calculateResistance();
float lux = estimateLux();
Serial.println("=== اطلاعات سنسور LDR ===");
Serial.print("مقدار خام ADC: ");
Serial.println(raw);
Serial.print("ولتاژ: ");
Serial.print(voltage, 3);
Serial.println(" V");
Serial.print("مقاومت LDR: ");
if(resistance >= 1000000) {
Serial.print(resistance / 1000000.0, 2);
Serial.println(" MΩ");
} else if(resistance >= 1000) {
Serial.print(resistance / 1000.0, 1);
Serial.println(" KΩ");
} else {
Serial.print(resistance, 0);
Serial.println(" Ω");
}
Serial.print("شدت نور تخمینی: ");
Serial.print(lux, 1);
Serial.println(" لوکس");
Serial.print("وضعیت دیجیتال: ");
Serial.println(isDark() ? "تاریک (HIGH)" : "روشن (LOW)");
Serial.println("========================");
}
};
LDRSensor ldr(A0, 2);
void setup() {
Serial.begin(9600);
Serial.println("سنسور LDR با کلاس مدیریت راهاندازی شد");
}
void loop() {
ldr.printInfo();
if(ldr.isDark()) {
Serial.println("هشدار: محیط تاریک است!");
}
float lux = ldr.estimateLux();
if(lux > 500) {
Serial.println("نور بسیار زیاد! ممکن است به سنسور آسیب برسد");
}
delay(2000);
}
سیستم کنترل نور اتوماتیک:
class AutomaticLightControl {
private:
LDRSensor* ldr;
int lightPin;
float onThreshold;
float offThreshold;
bool hysteresisEnabled;
public:
AutomaticLightControl(LDRSensor* sensor, int pin,
float onLux = 50, float offLux = 100) {
ldr = sensor;
lightPin = pin;
onThreshold = onLux;
offThreshold = offLux;
hysteresisEnabled = true;
pinMode(lightPin, OUTPUT);
digitalWrite(lightPin, LOW);
}
void update() {
float currentLux = ldr->estimateLux();
bool lightState = digitalRead(lightPin);
if(hysteresisEnabled) {
if(!lightState && currentLux <= onThreshold) {
turnOnLight();
} else if(lightState && currentLux >= offThreshold) {
turnOffLight();
}
} else {
if(currentLux <= onThreshold) {
turnOnLight();
} else {
turnOffLight();
}
}
}
void turnOnLight() {
digitalWrite(lightPin, HIGH);
Serial.println("چراغ روشن شد (نور کم)");
}
void turnOffLight() {
digitalWrite(lightPin, LOW);
Serial.println("چراغ خاموش شد (نور کافی)");
}
void setThresholds(float onLux, float offLux) {
onThreshold = onLux;
offThreshold = offLux;
Serial.print("آستانهها تنظیم شد: روشن = ");
Serial.print(onLux);
Serial.print(" لوکس، خاموش = ");
Serial.print(offLux);
Serial.println(" لوکس");
}
void enableHysteresis(bool enable) {
hysteresisEnabled = enable;
Serial.print("هیسترزیس ");
Serial.println(enable ? "فعال شد" : "غیرفعال شد");
}
};
LDRSensor myLDR(A0, 2);
AutomaticLightControl lightControl(&myLDR, 8, 50, 100);
void setup() {
Serial.begin(9600);
Serial.println("سیستم کنترل نور اتوماتیک راهاندازی شد");
}
void loop() {
lightControl.update();
static unsigned long lastPrint = 0;
if(millis() - lastPrint > 5000) {
lastPrint = millis();
myLDR.printInfo();
}
delay(100);
}
سیستم جمعآوری دادههای نوری:
#include <SD.h>
#include <SPI.h>
class LightDataLogger {
private:
LDRSensor* ldr;
File dataFile;
unsigned long logInterval;
unsigned long lastLogTime;
bool loggingEnabled;
public:
LightDataLogger(LDRSensor* sensor, unsigned long interval = 60000) {
ldr = sensor;
logInterval = interval;
lastLogTime = 0;
loggingEnabled = false;
}
bool begin() {
if(!SD.begin(4)) {
Serial.println("خطا در راهاندازی کارت SD!");
return false;
}
dataFile = SD.open("light_log.csv", FILE_WRITE);
if(!dataFile) {
Serial.println("خطا در ایجاد فایل!");
return false;
}
dataFile.println("Time(ms),RawADC,Voltage(V),Resistance(Ohm),Lux,Digital");
dataFile.close();
loggingEnabled = true;
Serial.println("دیتالاگر نور راهاندازی شد");
return true;
}
void update() {
if(!loggingEnabled) return;
unsigned long currentTime = millis();
if(currentTime - lastLogTime >= logInterval) {
lastLogTime = currentTime;
logData();
}
}
void logData() {
dataFile = SD.open("light_log.csv", FILE_WRITE);
if(dataFile) {
int raw = ldr->readRaw();
float voltage = ldr->readVoltage();
float resistance = ldr->calculateResistance();
float lux = ldr->estimateLux();
bool digital = ldr->isDark();
dataFile.print(millis());
dataFile.print(",");
dataFile.print(raw);
dataFile.print(",");
dataFile.print(voltage, 3);
dataFile.print(",");
dataFile.print(resistance, 0);
dataFile.print(",");
dataFile.print(lux, 2);
dataFile.print(",");
dataFile.println(digital ? "DARK" : "LIGHT");
dataFile.close();
Serial.print("داده ثبت شد: ");
Serial.print(lux, 1);
Serial.println(" لوکس");
}
}
void setLogInterval(unsigned long interval) {
logInterval = interval;
Serial.print("فاصله ثبت داده به ");
Serial.print(interval / 1000);
Serial.println(" ثانیه تنظیم شد");
}
void stop() {
loggingEnabled = false;
Serial.println("ثبت داده متوقف شد");
}
};
LDRSensor ldrSensor(A0, 2);
LightDataLogger dataLogger(&ldrSensor, 30000);
void setup() {
Serial.begin(9600);
if(dataLogger.begin()) {
Serial.println("دیتالاگر آماده است");
}
}
void loop() {
dataLogger.update();
delay(1000);
}
🎯 کاربردهای عملی
1. سیستمهای روشنایی اتوماتیک:
2. کشاورزی و گلخانه:
-
کنترل نور گلخانهها
-
مانیتورینگ نور گیاهان
-
سیستمهای آبیاری هوشمند
-
کنترل پردههای گلخانه
3. سیستمهای امنیتی:
-
تشخیص قطع نور (دستکاری)
-
آلارم نفوذ به پنجره
-
سیستمهای نظارتی
-
تشخیص حرکت با تغییر نور
4. دستگاههای مصرفی:
5. پروژههای تحقیقاتی:
-
مطالعات آب و هوایی
-
تحقیقات نوری
-
آزمایشهای فیزیک نور
-
پروژههای دانشآموزی
⚠️ نکات مهم و محاسبات
فرمولهای محاسباتی:
1. مقاومت LDR از ولتاژ:
R_ldr = R_series * (Vcc / V_out - 1)
2. ولتاژ خروجی:
V_out = Vcc * (R_series / (R_ldr + R_series))
3. تخمین لوکس (رابطه تجربی):
لوکس ≈ 10^((log(R_ldr) - log(R_dark)) / (log(R_light) - log(R_dark)) * 3 - 1)
نکات کالیبراسیون:
-
کالیبراسیون تاریکی: سنسور را در تاریکی کامل قرار دهید
-
کالیبراسیون نور: از منبع نور استاندارد استفاده کنید
-
مقاومت سری: از مقاومت دقیق 10KΩ ±1% استفاده کنید
-
دمای محیط: LDR به دما هم حساس است (دمای ثابت نگه دارید)
محدودیتهای LDR:
-
پاسخ طیفی: فقط به نور مرئی حساس است
-
پاسخ زمانی: کندتر از فوتودیودها
-
حساسیت دمایی: مقاومت با دما تغییر میکند
-
خطی نبودن: رابطه مقاومت-نور خطی نیست
عیبیابی:
🔧 پروژههای نمونه پیشرفته
پروژه 1: ردیاب خورشید ساده:
class SunTracker {
private:
int ldrPins[4];
int servoPin;
public:
SunTracker(int pins[4], int servo) {
for(int i=0; i<4; i++) {
ldrPins[i] = pins[i];
}
servoPin = servo;
}
int calculateSunPosition() {
int values[4];
for(int i=0; i<4; i++) {
values[i] = analogRead(ldrPins[i]);
}
int maxIndex = 0;
int maxValue = values[0];
for(int i=1; i<4; i++) {
if(values[i] > maxValue) {
maxValue = values[i];
maxIndex = i;
}
}
return maxIndex;
}
};
پروژه 2: سیستم هشدار قطع نور:
class LightBreakDetector {
private:
LDRSensor* ldr;
float baselineLux;
float thresholdPercent;
bool alarmActive;
public:
LightBreakDetector(LDRSensor* sensor, float threshold = 30.0) {
ldr = sensor;
thresholdPercent = threshold;
alarmActive = false;
delay(1000);
baselineLux = ldr->estimateLux();
Serial.print("نور پایه ثبت شد: ");
Serial.print(baselineLux, 1);
Serial.println(" لوکس");
}
void check() {
float currentLux = ldr->estimateLux();
float changePercent = abs(currentLux - baselineLux) / baselineLux * 100;
if(changePercent > thresholdPercent) {
if(!alarmActive) {
triggerAlarm();
alarmActive = true;
}
} else {
alarmActive = false;
}
}
void triggerAlarm() {
Serial.println("هشدار: تغییر ناگهانی نور تشخیص داده شد!");
}
};
📊 جدول مقایسه با سنسورهای نوری دیگر
⭐ مزایای رقابتی
نسبت به LDR خام:
-
مدار کامل با مقایسهگر و تنظیم آستانه
-
خروجی دوگانه آنالوگ و دیجیتال
-
نشانگر وضعیت LED
-
محافظت در برابر اتصال کوتاه
نسبت به سنسورهای دیجیتال:
ویژگیهای منحصر به فرد:
-
پتانسیومتر تنظیم آستانه برای کاربردهای مختلف
-
خروجی آنالوگ مستقیم برای اندازهگیری دقیق
-
ساختار مقاوم با پوشش ضدگردوغبار
-
نصب بسیار آسان با پایههای استاندارد
💡 نکات حرفهای
برای دقت بیشتر:
-
میانگینگیری: از 10-20 نمونه برای هر خوانش استفاده کنید
-
فیلتر نویز: خازن 100nF بین VCC و GND نزدیک ماژول
-
کالیبراسیون دورهای: هر 6 ماه کالیبره کنید
-
دمای ثابت: در دمای اتاق کار کنید
برای کاربردهای صنعتی:
-
از ماژول با پوشش IP67 استفاده کنید
-
سیگنال را با کابل شیلددار انتقال دهید
-
از منبع تغذیه رگوله شده استفاده کنید
-
پاسخ فرکانسی را برای نورهای مصنوعی در نظر بگیرید
برای کاهش مصرف برق:
void lowPowerMeasurement() {
digitalWrite(LDR_POWER_PIN, HIGH);
delay(10);
int value = analogRead(LDR_PIN);
digitalWrite(LDR_POWER_PIN, LOW);
return value;
}
☀️ مناسب برای:
-
توسعهدهندگان خانه هوشمند
-
مهندسین کشاورزی و گلخانه
-
پژوهشگران علوم محیطی
-
دانشجویان الکترونیک و رباتیک
-
سازندگان سیستمهای امنیتی
⚠️ هشدار: LDRها به نور UV حساس نیستند و برای کاربردهای تشخیص شعله یا UV مناسب نمیباشند.
نقد و بررسیها
پاکسازی فیلترهنوز بررسیای ثبت نشده است.