BH1750 คืออะไร?
BH1750 คือ โมดูลเซนเซอร์วัดความเข้มแสง (Light Sensor) แบบดิจิทัลที่สื่อสารผ่าน I2C ใช้ชิป BH1750FVI ของ ROHM สามารถอ่านค่าแสงออกมาเป็นหน่วย Lux (lx) ได้โดยตรง โดยไม่ต้องแปลงค่าแรงดันหรือทำสมการเหมือน LDR เหมาะกับงานที่ต้องการ ความแม่นยำ และ ความสะดวกในการเขียนโค้ด เช่น ระบบไฟส่องสว่างอัตโนมัติ, Smart Farm, ระบบควบคุมแสงในตู้ปลา หรือเครื่องวัดแสงพกพา
หลักการทำงาน (Illuminance: Lux)
- BH1750 ใช้ Photodiode ตรวจจับแสง → แปลงเป็นกระแสไฟฟ้า → วงจรภายในคำนวณเป็นค่า Illuminance (Lux)
- Lux หมายถึง ปริมาณแสงที่ตกกระทบต่อพื้นที่ 1 ตารางเมตร
- ยิ่ง Lux สูง แสดงว่าพื้นที่นั้นสว่างมาก เช่น
- ห้องนั่งเล่นในบ้าน: 50–200 Lux
- แสงกลางวันทั่วไป: 10,000–25,000 Lux
- แสงแดดจัด: 100,000 Lux+
BH1750 สามารถวัดได้ตั้งแต่ 1 – 65,535 Lux ซึ่งครอบคลุมการใช้งานทั่วไปแทบทุกแบบ

โหมดวัดค่า (H-Resolution, H-Resolution2, L-Resolution)
BH1750 มีโหมดหลัก 3 แบบที่เลือกใช้ได้ตามสถานการณ์:
- H-Resolution Mode
- ความละเอียดสูง (1 lx/step)
- ใช้เวลาวัด ~120 ms
- เหมาะกับงานที่ต้องการค่าละเอียด เช่น วัดแสงใน Smart Farm
- H-Resolution2 Mode
- ความละเอียดสูงขึ้นอีก (0.5 lx/step)
- ใช้เวลาวัด ~120 ms
- เหมาะกับงานในสภาพแสงน้อยมาก เช่น ห้องมืดหรือตู้เพาะเลี้ยง
- L-Resolution Mode
- ความละเอียด 4 lx/step
- ใช้เวลาวัดสั้นลง ~16 ms
- เหมาะกับงานที่ต้องการ ความเร็วในการตอบสนอง มากกว่าความแม่นยำ
ข้อดี/ข้อจำกัดเมื่อเทียบกับ LDR, TSL2561, MAX44009
เมื่อเทียบกับ LDR (Light Dependent Resistor):
✅ ให้ค่าออกมาเป็น Lux ตรง ๆ ไม่ต้องทำสมการแปลง
✅ มีความเสถียรมากกว่า ไม่สวิงง่าย
❌ ราคาสูงกว่า LDR
❌ ซับซ้อนกว่านิดหน่อย (ต้องใช้ I2C)
เมื่อเทียบกับ TSL2561 (Light-to-Digital):
✅ ใช้งานง่ายกว่า (TSL2561 มีหลาย channel เช่น IR + Visible ต้องประมวลผลเพิ่ม)
✅ BH1750 โค้ดสั้นกว่า ตรงไปตรงมา
❌ TSL2561 แม่นกว่าในงานวิจัยที่ต้องแยกแสง IR/Visible
เมื่อเทียบกับ MAX44009 (Ultra-Low Power):
✅ BH1750 หาง่าย ราคาถูกกว่า
✅ รองรับการวัดแสงสูงถึง ~65k Lux (MAX44009 จะเน้นงาน Low-Light)
❌ MAX44009 ประหยัดพลังงานกว่ามาก เหมาะกับ IoT ที่ใช้ Battery

อุปกรณ์และเครื่องมือที่ใช้
รายการอุปกรณ์
- ESP32 DevKit (เช่น DevKit v1) → ไมโครคอนโทรลเลอร์หลัก ใช้รันโค้ดและอ่านค่าจากเซนเซอร์
- โมดูล BH1750 → เซนเซอร์วัดความเข้มแสงแบบ I2C
- สาย Dupont (Male–Female / Male–Male) → สำหรับต่อขาระหว่าง ESP32 กับโมดูล BH1750
- บอร์ดทดลอง (Breadboard) → ช่วยให้ต่อวงจรได้สะดวกโดยไม่ต้องบัดกรี
รายละเอียดพื้นฐานของ บอร์ด ESP32 คืออะไร พร้อมจุดเด่นและวิธีเริ่มต้นใช้งาน


ดาวน์โหลด Arduino IDE และติดตั้งได้ง่าย ๆ ที่ Arduino IDE Download & Install
ติดตั้งไลบรารี “BH1750” ผ่าน Library Manager
- ไปที่เมนู Sketch > Include Library > Manage Libraries…
- ค้นหาคำว่า BH1750
- เลือก BH1750 by Christopher Laws (หรือเวอร์ชันยอดนิยมอื่นที่รองรับ)
- กด Install
- ตรวจสอบว่าใน Examples มีตัวอย่าง BH1750test แสดงว่าติดตั้งเรียบร้อย
ทดสอบ I2C Scanner (ตรวจสอบ address ก่อน)
ก่อนเขียนโค้ดจริง ควรใช้ I2C Scanner เพื่อตรวจสอบว่าโมดูล BH1750 ต่อถูกหรือไม่ และใช้ Address อะไร
- เปิด File > Examples > Wire > i2c_scanner (หรือใช้โค้ดตัวอย่างนี้):
#include <Wire.h>
void setup() {
Serial.begin(115200);
Wire.begin();
Serial.println(“\nI2C Scanner”);
}void loop() {
byte error, address;
int nDevices = 0;for (address = 1; address < 127; address++) {
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0) {
Serial.print(“I2C device found at 0x”);
if (address < 16) Serial.print(“0”);
Serial.print(address, HEX);
Serial.println(” !”);
nDevices++;
}
}
if (nDevices == 0) Serial.println(“No I2C devices found\n”);
else Serial.println(“done\n”);delay(2000);
} - อัปโหลดโค้ดไปที่ ESP32 → เปิด Serial Monitor (115200 baud)
- ถ้าโมดูล BH1750 ต่อถูกต้อง จะเห็นข้อความประมาณ:
I2C device found at 0x23 !หรือบางรุ่นอาจเป็น0x5C
โค้ดอ่านค่าแสงพื้นฐาน (ESP32 + BH1750)
// ใช้ไลบรารี BH1750 by Christopher Laws
#include <Wire.h>
#include <BH1750.h>
// ถ้า I2C Scanner เจอ 0x23 ให้ใช้ตามนี้ (ส่วนใหญ่จะเป็น 0x23)
// ถ้าเจอ 0x5C ให้เปลี่ยนเป็น BH1750 lightMeter(0x5C);
BH1750 lightMeter(0x23);
void setup() {
Serial.begin(115200);
// ค่า Default ของ ESP32: SDA = 21, SCL = 22
// ระบุให้ชัดเจนกันพลาด
Wire.begin(21, 22);
// เริ่มต้นใช้งาน BH1750 และกำหนดโหมดวัดค่า
// CONTINUOUS_HIGH_RES_MODE ≈ 1 lx/step, ใช้เวลาวัด ~120 ms
if (!lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE)) {
Serial.println("BH1750 not found. Check wiring/address!");
while (true) delay(1000);
}
Serial.println("BH1750 ready. Reading lux...");
}
void loop() {
// อ่านค่า Lux (float)
float lux = lightMeter.readLightLevel();
// ป้องกันค่าผิดปกติ
if (lux < 0) {
Serial.println("Error reading BH1750");
} else {
Serial.print("Lux: ");
Serial.println(lux, 1); // แสดงทศนิยม 1 ตำแหน่ง
}
// เว้นช่วงให้เซนเซอร์มีเวลาวัด (ตามโหมด ~120ms)
delay(200);
}
กรุณา เข้าสู่ระบบ เพื่อดาวน์โหลด
อธิบายทีละส่วน
begin(…)
- ใช้สำหรับเริ่มต้นสื่อสารกับเซนเซอร์และตั้งโหมดครั้งแรก
- ตัวอย่างที่ใช้:
lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE); - ถ้า begin() คืนค่า false แปลว่าไม่พบอุปกรณ์ → เช็กสายไฟ SDA/SCL, VCC/GND และที่อยู่ I2C (0x23/0x5C)
setMode(…)
- ใช้เปลี่ยนโหมดการวัดภายหลัง begin() (ไม่จำเป็นต้องเรียกซ้ำถ้าโหมดเดิมเหมาะแล้ว)
- ตัวอย่าง:
lightMeter.setMode(BH1750::CONTINUOUS_HIGH_RES_MODE_2); // ≈ 0.5 lx/step
// หรือ
lightMeter.setMode(BH1750::CONTINUOUS_LOW_RES_MODE); // ≈ 4 lx/step ~16ms - แนวทางเลือกโหมด:
- HIGH_RES: ละเอียด 1 lx (เอนกประสงค์/Smart Farm)
- HIGH_RES_2: ละเอียดขึ้น 0.5 lx (แสงน้อย)
- LOW_RES: เร็ว ~16 ms (แลกความละเอียด)
readLightLevel()
- อ่านค่า Illuminance (Lux) แบบ float
- ในโหมด CONTINUOUS_* คำสั่งนี้จะคืนค่าล่าสุดที่แปลงเสร็จแล้ว
- ควรมี delay ให้ยาวพอสำหรับเวลาวัดของแต่ละโหมด (เช่น 200 ms สำหรับ High-Res)
การปรับเทียบและตีความค่า
สภาพแวดล้อมที่มีผล (มุมตกกระทบ, เงา, ระยะ)
การอ่านค่า Lux ไม่ได้ขึ้นกับเซนเซอร์อย่างเดียว แต่ยังขึ้นกับ สภาพแวดล้อม รอบ ๆ ด้วย
- มุมตกกระทบของแสง → ถ้าแสงเข้าด้านตรง ๆ ค่าจะสูงกว่ามุมเอียง ๆ
- เงา → ถ้ามีเงาบัง (เช่น มือ, กรอบตู้, ใบไม้) ค่า Lux จะลดลงทันที
- ระยะห่างจากแหล่งกำเนิดแสง → ยิ่งห่าง ค่า Lux ยิ่งลดลงแบบกำลังสอง (Inverse Square Law)
💡 ดังนั้นควรติดตั้ง BH1750 ใน ตำแหน่งเดียวกับพื้นที่ที่ต้องการควบคุมแสงจริง เช่น ระดับยอดผัก หรือบริเวณโต๊ะทำงาน ไม่ใช่วางไว้ไกลเกินไป
Smooth/Average ค่า (Moving Average/Median)
ค่าแสงที่อ่านมามักจะ “สวิง” เพราะสิ่งแวดล้อมเปลี่ยนตลอดเวลา (คนเดินผ่าน, แสงกระพริบ, ไฟ LED dimming)
วิธีแก้คือใช้ การเฉลี่ยค่า (Filtering) เช่น:
- Moving Average → เก็บค่าล่าสุด 5–10 ค่าแล้วหารเฉลี่ย
const int N = 5;
float buffer[N];
int idx = 0;
float readLuxAverage(BH1750 &sensor) {
buffer[idx] = sensor.readLightLevel();
idx = (idx + 1) % N;
float sum = 0;
for (int i = 0; i < N; i++) sum += buffer[i];
return sum / N;
}
- Median Filter → เรียงค่าที่อ่านได้แล้วเลือกค่ากลาง จะกันสัญญาณรบกวน spike ได้ดี
เทคนิคนี้ทำให้ค่า Lux ที่แสดงใน Serial Monitor หรือนำไปคุมรีเลย์ “นิ่ง” และน่าเชื่อถือขึ้นมาก
ตั้ง Threshold ให้เหมาะกับงาน (เช่น แสงในบ้าน/ในตู้ปลูกผัก)
การกำหนดค่า Threshold (ค่าตัดสินใจ) ต้องเลือกให้ตรงกับการใช้งานจริง เช่น
- ห้องนั่งเล่น / ห้องทำงาน:
- 100–300 Lux → พอสำหรับอ่านหนังสือ, ทำงานคอม
- ถ้าต่ำกว่า 100 Lux → เปิดไฟเสริม
- Smart Farm / ตู้ปลูกผัก:
- ผักกินใบต้องการ ~2,000–5,000 Lux
- ถ้าค่าน้อยกว่านี้ → เปิดไฟปลูก
- ถ้าเกิน → ปิดไฟเพื่อลดค่าไฟและป้องกันร้อนเกินไป
- งานตรวจสอบกลางแจ้ง:
- แสงแดดเช้า ~10,000 Lux
- แสงแดดจ้า >100,000 Lux
💡 ทริกสำคัญ: ใช้ Hysteresis เพื่อลดการกระพริบของไฟ เช่น:
- เปิดไฟเมื่อค่า Lux < 200
- ปิดไฟเมื่อค่า Lux > 300
ดีบักและแก้ปัญหายอดฮิต
ค่าขึ้น -1 หรือ NaN / ไม่อ่านค่า
- อาการ: ค่าใน Serial Monitor ขึ้น -1, NaN หรือไม่แสดงอะไรเลย
- สาเหตุที่เจอบ่อย:
- โมดูลไม่ได้ต่อไฟเลี้ยง (VCC/GND)
- สาย SDA/SCL ไม่ได้ต่อ หรือขาสลับกัน
- ยังไม่ได้เรียก begin() หรือ setMode() ในโค้ด
- วิธีแก้:
- เช็กสาย VCC → 3.3V, GND → GND
- เช็ก SDA=GPIO21, SCL=GPIO22 (ค่า default ของ ESP32)
- ใช้ I2C Scanner ตรวจสอบว่ามีอุปกรณ์โผล่หรือไม่
Address ไม่ตรง (0x23/0x5C) / I2C สลับสาย SDA/SCL
- BH1750 มี Address 2 ค่า:
- 0x23 (ค่า default ถ้า ADDR=GND)
- 0x5C (ถ้า ADDR=VCC)
- อาการ: I2C Scanner ไม่เจอ หรือโค้ดอ่านค่าไม่ได้
- วิธีแก้:
- ใช้ I2C Scanner เช็ก address ก่อนทุกครั้ง
- ถ้าโค้ดเขียนว่า BH1750 lightMeter(0x23); แต่เจอจริง ๆ เป็น 0x5C → ต้องเปลี่ยนเป็น BH1750 lightMeter(0x5C);
- สาย SDA/SCL ต่อผิดขาจะมองไม่เห็นอุปกรณ์ → ตรวจอีกทีว่าต่อ SDA → GPIO21, SCL → GPIO22
Q1: BH1750 ต่างจาก LDR ยังไง?
A: BH1750 อ่านค่าออกมาเป็น Lux ได้โดยตรง มีความแม่นยำและเสถียรกว่า ส่วน LDR ต้องใช้วงจรแบ่งแรงดันและเขียนสมการแปลงเอง
Q2: จะรู้ได้ไงว่าค่า Lux ที่อ่านเพียงพอสำหรับต้นไม้?
A: ขึ้นอยู่กับชนิดพืช เช่น ผักกินใบทั่วไปต้องการ 2,000–5,000 Lux ถ้าอ่านได้ต่ำกว่านี้ควรเปิดไฟเสริม
Q3: โมดูล BH1750 ใช้ไฟกี่โวลต์?
A: ส่วนใหญ่รองรับทั้ง 3.3V และ 5V แต่แนะนำใช้ 3.3V ตรงกับ ESP32 เพื่อความปลอดภัย
Q4: ถ้า I2C Scanner ไม่เจออุปกรณ์ ต้องทำยังไง?
A: เช็กสาย SDA/SCL ต่อถูกหรือไม่ (ESP32 ใช้ค่า default SDA=21, SCL=22) และเช็กว่า Address เป็น 0x23 หรือ 0x5C
Q5: ค่า Lux ขึ้น -1 หรือ NaN แก้ยังไง?
A: ตรวจการต่อวงจร, เรียก begin() ให้ถูกโหมด และเช็กว่าโมดูลทำงานหรือไม่
Q6: ถ้าอยากแสดงผลบนจอ ต้องทำยังไง?
A: ใช้จอ OLED SSD1306 หรือ LCD1602 I2C แล้วเพิ่มไลบรารี U8g2 หรือ LiquidCrystal_I2C เพื่อแสดงผลค่า Lux
Q7: BH1750 วัดกลางแจ้งแดดแรง ๆ ได้ไหม?
A: ได้ แต่สูงสุดประมาณ 65,535 Lux ถ้าแดดจัดเกินกว่านี้จะ Saturate (อ่านได้ไม่เกินค่านี้)
Q8: ใช้ BH1750 กับ Arduino UNO แทน ESP32 ได้หรือไม่?
A: ได้ 100% เพราะเป็น I2C มาตรฐาน ใช้โค้ดเกือบเหมือนกัน เพียงแค่เปลี่ยนขา SDA/SCL ให้ตรงกับบอร์ด
Q9: ทำไมค่า Lux สวิงไปมาเวลาอ่าน?
A: เพราะแสงในสิ่งแวดล้อมเปลี่ยนตลอดเวลา แนะนำให้ทำ Moving Average หรือใช้ Hysteresis เวลาควบคุมรีเลย์
Q10: BH1750 ใช้ร่วมกับเซนเซอร์อื่นบน I2C ได้ไหม?
A: ได้ เช่น DHT22, SSD1306, BMP280 เพราะ I2C ต่อร่วมกันได้หลายอุปกรณ์ แค่ Address ไม่ชนกัน






