آموزش BH1750 با ESP32؛ اندازهگیری نور بر حسب لوکس
راهنمای پروژهمحور BH1750 با ESP32 و Arduino؛ دیتاشیت، آدرس I2C، سیمکشی، حالتهای اندازهگیری، کد لوکس، کالیبراسیون و عیبیابی.
آموزش پروژهمحور اندازهگیری شدت روشنایی
راهاندازی BH1750 با ESP32 و Arduino؛ اندازهگیری نور بر حسب لوکس
BH1750 یک حسگر دیجیتال نور محیط با خروجی مستقیم لوکس و رابط I2C است. در این راهنما مشخصات تراشه خام و برد آماده، آدرسها، حالتهای اندازهگیری، سیمکشی، کد عملی و روش ساخت یک کنترلکننده روشنایی مطمئن را بررسی میکنیم.
0x23 یا 0x5CBH1750 چیست و لوکس چه معنایی دارد؟
BH1750FVI محصول ROHM یک مبدل نور به داده دیجیتال 16 بیتی است. پاسخ طیفی آن تقریباً به چشم انسان نزدیک شده و اثر مادونقرمز در آن کم است. به همین دلیل بهجای یک عدد خام ADC، روشنایی را بر حسب لوکس گزارش میکند.
لوکس شار نوری دریافتشده روی هر مترمربع است. این عدد برای کنترل نور اتاق، تنظیم خودکار نمایشگر، ثبت روشنایی گلخانه و تشخیص روز و شب مناسب است؛ اما رنگ نور، UV یا کیفیت طیف را اندازه نمیگیرد.
اعداد مهم دیتاشیت BH1750FVI
| پارامتر | مقدار رسمی | نتیجه عملی |
|---|---|---|
| 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 شمارش | عدد خام با لوکس یکسان نیست؛ ضریب تبدیل و حالت سنجش مهماند. |
آدرس I2C و حالتهای اندازهگیری
وقتی ADDR پایین باشد آدرس هفتبیتی 0x23 است و با بالا بردن آن به VCC آدرس 0x5C میشود. این دو آدرس اجازه میدهند دو حسگر را روی یک باس قرار دهید. برد Adafruit برای حالت پیشفرض Pull-down و برای SCL و SDA مقاومت Pull-up ده کیلو اهم دارد.
در حالت Continuous نتیجه با فاصله حالت انتخابی بهروزرسانی میشود. در One Time حسگر پس از تکمیل اندازهگیری خودکار به Power Down میرود. دیتاشیت برای High Resolution انتظار تا 180ms را لازم میداند؛ خواندن فوری ممکن است مقدار قبلی را برگرداند. کتابخانه hp_BH1750 این زمانبندی را با API غیرمسدودکننده مدیریت میکند.
سیمکشی BH1750 با ESP32 و Arduino Uno
| برد 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های تکراری زیاد روی باس پرحسگر پرهیز کنید.
راهاندازی گامبهگام در Arduino IDE
- در Library Manager عبارت hp BH1750 را جستوجو و کتابخانه Stefan Armborst را نصب کنید.
- برد را بدون تغذیه سیمکشی کنید و سطح ولتاژ ماژول را بررسی کنید.
- کد
i2c-scanner.inoرا اجرا کنید؛ باید 0x23 یا 0x5C دیده شود. - کد اصلی را آپلود و Serial Monitor را روی 115200 baud باز کنید.
- برای تصمیم کنترلی چند نمونه بگیرید و از آستانه رفت و برگشت جدا استفاده کنید.
کد BH1750 برای ESP32 و Arduino
#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 است.- خطای شروع اندازهگیری، داده تماممقیاس و انتظار بیش از دو ثانیه پیام تشخیصی دارند. دو ثانیه حد نگهبان نرمافزاری این مثال است، نه زمان تبدیل دیتاشیت.
- در پیادهسازی نسخه 1.0.2، خطای دریافت I2C مقدار
getTime()را 999 میکند. کد این نشانه را پیش از چاپ لوکس بررسی میکند تا قطع کابل بهاشتباه «تاریکی» نمایش داده نشود؛ این رفتار داخلی را پس از تغییر نسخه کتابخانه دوباره بررسی کنید. - سرعت 100kHz برای بردبورد محافظهکارانه است، هرچند تراشه طبق دیتاشیت تا 400kHz را پشتیبانی میکند.
پروژه: کنترل چراغ با هیسترزیس
یک رله یا 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 و منطق سازگار کار کنید. |
پرسشهای متداول BH1750
آدرس پیشفرض BH1750 چیست؟
با ADDR پایین، آدرس هفتبیتی 0x23 است؛ اتصال ADDR به VCC آن را به 0x5C تغییر میدهد.
آیا میتوان BH1750 خام را به 5V وصل کرد؟
خیر. VCC کاری تراشه خام 2.4 تا 3.6 ولت است. فقط برد آمادهای که صریحاً رگولاتور و Level Shifter دارد ممکن است 5V را بپذیرد.
BH1750 رنگ نور یا UV را اندازه میگیرد؟
خیر. خروجی آن روشنایی بر حسب لوکس است و سنجش رنگ یا UV نیازمند حسگر دیگری است.
چرا مقدار بلافاصله بعد از شروع تغییر نمیکند؟
تبدیل High Resolution میتواند تا 180 میلیثانیه طول بکشد. خواندن غیرمسدودکننده پس از آمادهشدن داده از مقدار قبلی جلوگیری میکند.
GPIO21 و GPIO22 برای همه ESP32ها درست است؟
خیر. اینها پیشفرض رایج Generic ESP32 هستند؛ پایههای برد واقعی خود، بهویژه S3 و C3، را بررسی کنید.
منابع و مسیر ادامه یادگیری
- آموزش سنسور نور LDR
- آموزش VL53L0X با ESP32 و Arduino
- آموزش BMP280 با ESP32 و Arduino
- دوره رایگان سنسورها در ۷ قدم
- دسته آموزش سنسورهای نور
- مرکز آموزش سنسورها در LCENJ
- دیتاشیت ROHM BH1750FVI، نسخه Rev.D، نوامبر 2011، صفحات 1 و 2 برای تغذیه و مشخصات، صفحات 5 و 7 برای حالتها و تبدیل داده؛ نسخه سازنده میزبانیشده در Mouser.
- راهنمای رسمی پایههای برد Adafruit BH1750 برای VIN، Level Shifter و آدرس.
- راهنمای رسمی Arduino برای BH1750 و نصب کتابخانه.
- کد و مثالهای کتابخانه hp_BH1750 نسخه 1.0.2، نوشته Stefan Armborst با مجوز MIT.
- مستند رسمی I2C در Arduino-ESP32 برای پایهها و API.
جمعبندی و آزمون روی میز کار
برای شروع، برد مستند را با ولتاژ سازگار وصل کنید، آدرس را با اسکنر پیدا کنید و اندازهگیری High با MTreg=69 را اجرا کنید. سپس تغییر نور و سایه، پوشش جلوی حسگر، نور شدید و قطع اتصال را روی سختافزار خود آزمایش کنید. این نمونهها برای Uno و Generic ESP32 کامپایل شدهاند؛ کامپایل جای آزمون واقعی حسگر و کالیبراسیون محصول را نمیگیرد.
پرسش و پاسخ مقاله
سوال فنی خود را مطرح کنید
پرسشها و پاسخها پس از بررسی مدیر منتشر میشوند. نویسنده، پیشنویس در انتظار بررسی را میبیند.
هنوز پرسش تاییدشدهای برای این مقاله ثبت نشده است.