آموزش پروژهمحور اندازهگیری شدت روشنایی
BH1750 یک حسگر دیجیتال نور محیط با خروجی مستقیم لوکس و رابط I2C است. در این راهنما مشخصات تراشه خام و برد آماده، آدرسها، حالتهای اندازهگیری، سیمکشی، کد عملی و روش ساخت یک کنترلکننده روشنایی مطمئن را بررسی میکنیم.
0x23 یا 0x5CBH1750FVI محصول ROHM یک مبدل نور به داده دیجیتال 16 بیتی است. پاسخ طیفی آن تقریباً به چشم انسان نزدیک شده و اثر مادونقرمز در آن کم است. به همین دلیل بهجای یک عدد خام ADC، روشنایی را بر حسب لوکس گزارش میکند.
لوکس شار نوری دریافتشده روی هر مترمربع است. این عدد برای کنترل نور اتاق، تنظیم خودکار نمایشگر، ثبت روشنایی گلخانه و تشخیص روز و شب مناسب است؛ اما رنگ نور، UV یا کیفیت طیف را اندازه نمیگیرد.
| پارامتر | مقدار رسمی | نتیجه عملی |
|---|---|---|
| VCC تراشه خام | 2.4 تا 3.6V | حد مطلق 4.5V مجوز کار عادی با 5V نیست. |
| ولتاژ مرجع I2C | 1.65V تا VCC | سطح منطق باید با طراحی واقعی برد هماهنگ باشد. |
| جریان در اندازهگیری | تیپیک 120µA، بیشینه 190µA | حالت Power Down برای پروژه باتریخور مفید است. |
| High Resolution | 1lx، تیپیک 120ms، بیشینه 180ms | برای شروع و نور کم انتخاب پیشنهادی دیتاشیت است. |
| High Resolution Mode 2 | 0.5lx، تیپیک 120ms | تفکیک بیشتر با همان زمان تیپیک. |
| Low Resolution | 4lx، تیپیک 16ms، بیشینه 24ms | سریعتر است ولی تغییرات کوچک را کمتر نشان میدهد. |
| داده خام | 16 بیت؛ 0 تا 65535 شمارش | عدد خام با لوکس یکسان نیست؛ ضریب تبدیل و حالت سنجش مهماند. |
وقتی ADDR پایین باشد آدرس هفتبیتی 0x23 است و با بالا بردن آن به VCC آدرس 0x5C میشود. این دو آدرس اجازه میدهند دو حسگر را روی یک باس قرار دهید. برد Adafruit برای حالت پیشفرض Pull-down و برای SCL و SDA مقاومت Pull-up ده کیلو اهم دارد.
در حالت Continuous نتیجه با فاصله حالت انتخابی بهروزرسانی میشود. در One Time حسگر پس از تکمیل اندازهگیری خودکار به Power Down میرود. دیتاشیت برای High Resolution انتظار تا 180ms را لازم میداند؛ خواندن فوری ممکن است مقدار قبلی را برگرداند. کتابخانه hp_BH1750 این زمانبندی را با API غیرمسدودکننده مدیریت میکند.
| برد Adafruit BH1750 | Generic ESP32 | Arduino Uno |
|---|---|---|
| VIN | 3V3 | 5V فقط برای برد Adafruit مستند |
| GND | GND | GND |
| SDA | GPIO21 | A4 / SDA |
| SCL | GPIO22 | A5 / SCL |
| ADDR | پایین برای 0x23 | پایین برای 0x23 |
GPIO21 و GPIO22 پیشفرض رایج Generic ESP32 هستند، نه قانون همه بردها. در ESP32-S3، ESP32-C3 و طراحی سفارشی پایههای واقعی برد را جایگزین کنید. سیمها را کوتاه نگه دارید و از Pull-upهای تکراری زیاد روی باس پرحسگر پرهیز کنید.
i2c-scanner.ino را اجرا کنید؛ باید 0x23 یا 0x5C دیده شود.#include <Wire.h>
#include <hp_BH1750.h>
#if defined(ESP32)
constexpr int SDA_PIN = 21;
constexpr int SCL_PIN = 22;
#endif
hp_BH1750 lightSensor;
unsigned long measurementStarted = 0;
void startMeasurement() {
if (!lightSensor.start(BH1750_QUALITY_HIGH, BH1750_MTREG_DEFAULT)) {
Serial.println(F("I2C start failed; check wiring and reset."));
while (true) delay(10);
}
measurementStarted = millis();
}
void setup() {
Serial.begin(115200);
#if defined(ESP32)
if (!Wire.setPins(SDA_PIN, SCL_PIN)) {
Serial.println(F("Invalid I2C pins."));
while (true) delay(10);
}
#endif
if (!lightSensor.begin(BH1750_TO_GROUND)) {
Serial.println(F("BH1750 not found; check wiring and address."));
while (true) delay(10);
}
Wire.setClock(100000);
startMeasurement();
}
void loop() {
if (lightSensor.hasValue()) {
const float lux = lightSensor.getLux();
// hp_BH1750 1.0.2 sets getTime() to 999 on an I2C read error.
if (lightSensor.getTime() == 999) {
Serial.println(F("I2C read failed; check wiring and reset."));
while (true) delay(10);
} else if (lightSensor.saturated()) {
Serial.println(F("Full-scale reading: check bright light and I2C."));
} else {
Serial.print(F("Illuminance: "));
Serial.print(lux, 1);
Serial.println(F(" lx"));
}
startMeasurement();
} else if (millis() - measurementStarted > 2000UL) {
Serial.println(F("Measurement timeout; check wiring and reset."));
while (true) delay(10);
}
delay(1);
}
BH1750_TO_GROUND آدرس 0x23 را انتخاب میکند؛ برای ADDR متصل به VCC از BH1750_TO_VCC استفاده کنید.hasValue() بدون معطلکردن حلقه بررسی میکند که زمان تبدیل تمام شده است.getLux() مقدار تبدیلشده به لوکس را میخواند و start() نمونه بعدی را آغاز میکند.Wire.setPins() پیش از راهاندازی کتابخانه، پایههای ESP32 را تعیین میکند؛ خود begin() کتابخانه Wire را راهاندازی میکند و سپس سرعت باس تنظیم میشود.start(BH1750_QUALITY_HIGH, BH1750_MTREG_DEFAULT) حالت High با MTreg=69 را صریح انتخاب میکند؛ مقدار پیشفرض داخلی کتابخانه High2 است.getTime() را 999 میکند. کد این نشانه را پیش از چاپ لوکس بررسی میکند تا قطع کابل بهاشتباه «تاریکی» نمایش داده نشود؛ این رفتار داخلی را پس از تغییر نسخه کتابخانه دوباره بررسی کنید.یک رله یا MOSFET مناسب را با ایزولاسیون و حفاظت لازم به خروجی وصل کنید. چراغ را فقط زمانی روشن کنید که چند نمونه پیاپی زیر آستانه پایین باشند و فقط پس از عبور چند نمونه از آستانه بالاتر خاموش کنید. فاصله میان دو آستانه همان هیسترزیس است و از قطعووصل سریع نزدیک مرز جلوگیری میکند.
اگر حسگر پشت شیشه، قاب مات یا پوشش محصول قرار بگیرد، بخشی از نور کم میشود. دیتاشیت با تغییر Measurement Time Register امکان جبران اثر پنجره را میدهد، اما ضریب را نمیتوان حدس زد. یک لوکسمتر مرجع، هندسه ثابت، منبع پایدار و چند سطح روشنایی لازم است.
جدول دقت دیتاشیت، در نور LED سفید 1000lx و شرایط مرجع VCC=DVI=3V و 25°C، نسبت «خروجی خام به لوکس واقعی» را 0.96 تا 1.44 با مقدار تیپیک 1.2 میدهد. پس تقسیم بر 1.2 در حالت High و MTreg=69، انحراف اسمی حدود ±20٪ را نشان میدهد؛ این عدد تضمین دقت یکسان در هر نور و محیط نیست. در همین تنظیم، سقف محاسباتی 65535/1.2 حدود 54613lx است و در High2 نصف میشود. کد مقدار تماممقیاس را هشدار میدهد و بهعنوان اندازهگیری معتبر چاپ نمیکند.
| نشانه | علت محتمل | بررسی پیشنهادی |
|---|---|---|
| حسگر پیدا نمیشود | آدرس یا پایه اشتباه، نبود زمین مشترک | اسکنر را اجرا و 0x23/0x5C را بررسی کنید. |
| مقدار ثابت یا قدیمی | خواندن پیش از پایان تبدیل | از hasValue() و شروع نمونه بعدی استفاده کنید. |
| پرش نزدیک آستانه | سایه، نور مستقیم یا منطق تکآستانه | میانه چند نمونه و هیسترزیس اضافه کنید. |
| اختلاف با لوکسمتر | تلرانس حسگر، زاویه یا پوشش اپتیکی | در هندسه ثابت با مرجع معتبر کالیبره کنید. |
| ماژول روی Uno داغ یا خراب میشود | برد فاقد رگولاتور/Level Shifter | شماتیک ماژول را بررسی و با 3.3V و منطق سازگار کار کنید. |
با ADDR پایین، آدرس هفتبیتی 0x23 است؛ اتصال ADDR به VCC آن را به 0x5C تغییر میدهد.
خیر. VCC کاری تراشه خام 2.4 تا 3.6 ولت است. فقط برد آمادهای که صریحاً رگولاتور و Level Shifter دارد ممکن است 5V را بپذیرد.
خیر. خروجی آن روشنایی بر حسب لوکس است و سنجش رنگ یا UV نیازمند حسگر دیگری است.
تبدیل High Resolution میتواند تا 180 میلیثانیه طول بکشد. خواندن غیرمسدودکننده پس از آمادهشدن داده از مقدار قبلی جلوگیری میکند.
خیر. اینها پیشفرض رایج Generic ESP32 هستند؛ پایههای برد واقعی خود، بهویژه S3 و C3، را بررسی کنید.
برای شروع، برد مستند را با ولتاژ سازگار وصل کنید، آدرس را با اسکنر پیدا کنید و اندازهگیری High با MTreg=69 را اجرا کنید. سپس تغییر نور و سایه، پوشش جلوی حسگر، نور شدید و قطع اتصال را روی سختافزار خود آزمایش کنید. این نمونهها برای Uno و Generic ESP32 کامپایل شدهاند؛ کامپایل جای آزمون واقعی حسگر و کالیبراسیون محصول را نمیگیرد.