Как подключить датчик освещённости bh1750 к arduino

Содержание

How to use the BH1750 library

The BH1750 library is used very similar to the BME280 library (or BMP180). At the beginning of the program, the library is called and the lightMeter object is initialized by indicating the address of the BH1750 on the I2C bus. By default the BH1750 is located at address 0x23. If you have a conflict with another component, you can assign the address 0x5C by feeding the addr pin to 3.3V.

The library supports the 6 modes of operation of the sensor. The sensor can measure continuous brightness

  • BH1750_CONTINUOUS_LOW_RES_MODE: Fast measurement (16ms) at low resolution (4 lux of precision)
  • BH1750_CONTINUOUS_HIGH_RES_MODE (default mode): High resolution (1 lux accuracy). The measurement time is 120ms
  • BH1750_CONTINUOUS_HIGH_RES_MODE_2: Very high resolution (0.5 lux accuracy). Measurement time 120ms

These three other modes allow to realize a single measurement (One_Time) and then to put the sensor in energy saving. Accuracy and measurement time are identical.

  • BH1750_ONE_TIME_LOW_RES_MODE
  • BH1750_ONE_TIME_HIGH_RES_MODE
  • BH1750_ONE_TIME_HIGH_RES_MODE_2

In the setup, the lightMeter object is started by using the function begin (uint8_t mode) by passing it as parameter the measurement mode. The configure (uint8_t mode) function is (called by begin) is also exposed.

The readLightLevel method reads the light intensity measured by the BH1750 at any time. The function returns the measurement directly to Lux.

А можно ли измерить освещенность фотоаппаратом?

Можно! Все современные фотоаппараты и многие антикварные имеют встроенный фотоэкспонометр. Антиквариат обычно работает по принципам внешних экспонометров. А с цифрой вообще все просто – большинство камер моментально отображает на встроенном экране подобранные для съемки значения.

Нужно лишь выставить ISO на 100, отключить вспышку, навести камеру на объект и дать ей сфокусироваться (даже птичке вылетать не требуется). Как вариант можно подобрать выдержку и диафрагму вручную, убедившись, что ползунок EV установился на отметке 0. Полученные значения сличаем по диаграмме выше.

Если же ваш фотоаппарат не позволяет менять ISO или вообще не отображает параметров съемки, то просто сделайте снимок и посмотрите EXIF данные: правой кнопкой в проводнике -> свойства -> вкладка «подробно». Перед вами предстанет список EXIF данных, среди которых должны найтись параметры съемки.

У смартфонов значения могут быть весьма нестандартные… поэтому без расчетов обойтись скорей всего не получится (можно воспользоваться выложенным выше файлом).

Вот так, подручными средствами, можно довольно точно и быстро измерить освещенность в люксах. Может не у всех в чулане завалялись экспонометры, но фотоаппарат уж точно у каждого найдется.

Overview

The BH1750 has six different measurement modes which are divided in two groups;
continuous and one-time measurements. In continuous mode the sensor
continuously measures lightness value. In one-time mode, the sensor makes only
one measurement and then goes into Power Down mode.

Each mode has three different precisions:

  • Low Resolution Mode — (4 lx precision, 16ms measurement time)
  • High Resolution Mode — (1 lx precision, 120ms measurement time)
  • High Resolution Mode 2 — (0.5 lx precision, 120ms measurement time)

By default, this library uses Continuous High Resolution Mode, but you can
change this to a different mode by passing the mode argument to
BH1750.begin().

When the One-Time mode is used your sensor will go into Power Down mode when
it completes the measurement and you’ve read it. When the sensor is powered up
again it returns to the default mode which means it needs to be reconfigured
back into One-Time mode. This library has been implemented to automatically
reconfigure the sensor when you next attempt a measurement so you should not
have to worry about such low level details.

Usually you will get an integer value which represent the lux equivalent.

  • Low Resolution Mode — (generic range: 0.0 up to 54612.5 lux)
  • High Resolution Mode — (generic range: 0.0 up to 54612.5 lux)
  • High Resolution Mode 2 — (generic range: 0.0 up to 27306.25 lux)

The sensor itself returns a 16 bit unsigned integer. Therefore the maximum value is limited in general.
The standard conversion between the so called ‘counts’ to lux is 1/1.2, that means you get a smaller value.
As we use float, if an error occurs you will get a negative value.

  • -1 no valid data was transmitted from the sensor
  • -2 device is not configured
    Otherwise the measured counts are converted to lux and returned. If no advanced parameters are changed the maximum lux value is 54612.5 lx.

As the sensor counts impact of light in a specific time frame you could change this time frame.
This is needed if you use an overlay window or compensate for environmental influence like darkness.
This time frame is defined by a register which is called MTreg. Therefore you could choose a value between 32 and 254.
The default value is 69; keep in mind that the measurement time is changed accordingly.

begin()

Description

The method takes, sanitizes, and stores sensor parameters to a class instance object and initiates two-wire bus.

  • The method sets parameters specific to the sensor itself.
  • All the method parameters can be changed dynamically with corresponding later in a sketch.
  • The method enables to set the sensor’s address according to the ADDR pin, if it is wired to a microcontroller’s pin.

Parameters

  • address: One of two possible 7 bit addresses of the sensor or state of the ADDR pin.
    • Valid values: , , , or pin state HIGH or LOW.
    • Default value:
      • The default values is set to address corresponding to not wired (floating) ADDR pin, which is equivalent to the connection to the ground.
      • If input value is none of expected ones, the method fallbacks it to default address.
      • In fact, the ADDR pin is not aimed to utilize dynamic changing the device address, but to enable using two sensors on one two-wire bus.
  • mode: Measurement mode from possible listed ones.
    • Valid values: ~
    • Default value:

Example

The method has all arguments defaulted and calling without any parameters is equivalent to the calling with all arguments set by corresponding constant with default value:

gbj_bh1750 Sensor = gbj_bh1750();
setup()
{
    Sensor.begin();  // It is equivalent to
    Sensor.begin(gbj_bh1750::ADDRESS_GND, gbj_bh1750::MODE_CONTINUOUS_HIGH);
}

If some argument after some defaulted arguments should have a specific value, use corresponding constants in place of those defaulted arguments, e.g.,

Sensor.begin(gbj_bh1750::ADDRESS_VCC, gbj_bh1750::MODE_ONETIME_LOW);      // Specific measurement mode

Typical usage is just with default values without any arguments.
Specific values of arguments can be set by corresponding .

Example

An example using the BH1750 library in conjunction with the GY-30 board
(which contains the BH1750 component) is presented below. The example
code uses the BH1750 library in the default continuous high precision
mode when making light measurements.

Wiring

Connections:

  • VCC -> 3V3 or 5V
  • GND -> GND
  • SCL -> SCL (A5 on Arduino Nano, Uno, Leonardo, etc or 21 on Mega and Due, on esp8266 free selectable)
  • SDA -> SDA (A4 on Arduino Nano, Uno, Leonardo, etc or 20 on Mega and Due, on esp8266 free selectable)
  • ADD -> NC/GND or VCC (see below)

The ADD pin is used to set the sensor I2C address. By default (if ADD voltage
less than 0.7 * VCC) the sensor address will be 0x23. If it has voltage
greater or equal to 0.7VCC voltage (e.g. you’ve connected it to VCC) the
sensor address will be 0x5C.

Wiring up the GY-30 sensor board to an Arduino is shown in the diagram below.

.

Code

Upload the BH1750 test code to your Arduino.

#include <Wire.h>
#include <BH1750.h>

BH1750 lightMeter;

void setup(){

  Serial.begin(9600);

  // Initialize the I2C bus (BH1750 library doesn't do this automatically)
  // On esp8266 devices you can select SCL and SDA pins using Wire.begin(D4, D3);
  Wire.begin();

  lightMeter.begin();
  Serial.println(F("BH1750 Test"));

}

void loop() {

  float lux = lightMeter.readLightLevel();
  Serial.print("Light: ");
  Serial.print(lux);
  Serial.println(" lx");
  delay(1000);

}

More Examples

The directory contains more advanced use cases such as using different modes, I2C addresses and multiple Wire instances.

Купить Датчик освещенности GY-30 BH1750FVI в Хабаровске Robstore.ru

В наличии: 2 шт.

• 100.00 р. •

Цифровой датчик овещённости GY-30. Модуль выполнен на базе BH1750FVI.

  • Чип: BH1750FVI
  • Питание: 3-5Вольт
  • Протокол связи: стандартный IIC (он же I2C, он же TWI) 
  • Диапазон измерений: 0 – 65535 Люкс

Для первого подключения нам понадобятся Arduino Uno и провода Папа-Мама. Также нужно скачать библиотеку BH1750 и подключить её к проекту в Arduino IDE.

Модуль подключаем по схеме:

GY-30 BH1750FVIArduino Uno

VCC
+5V

GND
GND

SCL
A5

SDA
A6

Для подключения используем провода Папа-Мама.

После установки библиотеки создаём и загружаем в Arduino скетч:

#include #include BH1750 lightMeter; void setup(){ Serial.begin(9600); // Initialize the I2C bus (BH1750 library doesn’t do this automatically) Wire.begin(); // On esp8266 you can select SCL and SDA pins using Wire.begin(D4, D3); lightMeter.begin(); Serial.println(F(“BH1750 Test”)); } void loop() { uint16_t lux = lightMeter.readLightLevel(); Serial.print(“Light: “); Serial.print(lux); Serial.println(” lx”); delay(1000); }

В этом примере каждую секунду в COM порт выводится ищмеренный показатель освещённости. Для просмотра поступающих данных необходимо использовать “Монитор порта”.

  • Datasheet на BH1750
  • Библиотека BH1750 для Arduino IDE

Датчик освещённости GY-30 BH1750FVI х1

Датчик освещенности GY-30 BH1750FVI

Модель:
GY-30

Производитель:

Датчик освещенности GY-302 BH1750

ОПИСАНИЕ Цифровой датчик освещенности с большим интервалом измерений. Модуль выполнен на базе BH1750.   ПАРАМЕТРЫ Чип: BH1750 Питание: 3-5 Вольт Протокол связи: стандартный IIC (он же I2C, он же TWI) Диапазон измерений: 1 – 65535 Люкс   ..

Датчик освещенности GY-2561 TSL2561

ОПИСАНИЕ Цифровой датчик освещенности с большим интервалом измерений. Модуль выполнен на базе TSL2651.   ПАРАМЕТРЫ Чип: TSL2651 Питание: 3.3-5 Вольт Протокол связи: стандартный IIC (он же I2C, он же TWI) Диапазон измерений: 1 – 65535 Люкс Габариты: 1..

Датчик освещенности GY-49 MAX44009

ОПИСАНИЕ Цифровой датчик освещенности с большим интервалом измерений. Модуль выполнен на базе MAX44009.   ПАРАМЕТРЫ Чип: MAX44009 Питание: 3 … 5 Вольт Протокол связи: стандартный IIC (он же I2C, он же TWI) Диапазон измерений: 0,045 … 188000 Люкс ..

Подключение BH1750 к Arduino

Модуль модуль GY-302 оборудован пяти-пиновым разъемом стандарта 2.54мм:

  • VCC: Питание «+»
  • GND: Земля «-«
  • SCL: Линия тактирования (Serial CLock)
  • SDA: Линия данных (Serial Data)
  • ADDR: Выбор адреса

Выводы отвечающие за интерфейс I2C на платах Arduino на базе различных контроллеров разнятся:

Arduino Mega Arduino Uno/Nano/Pro Mini BH1750 модуль Цвет проводов на фото
GND GND GND Черный
5V 5V VCC Красный
20 (SDA) A4 SDA Синий
21 (SCL) A5 SCL Зелёный
3.3V 3.3V ADDR Жёлтый

Схема подключения BH1750 к Arduino по I2C

На следующем рисунке показана схема подключения датчика внешней освещенности BH1750 к Arduino UNO. Вывод ADD можно оставить «висящим»:

но вы можете подключить его к 3.3 В. Это переведет вывод ADD в высокий логический уровень, и адрес ведомого I2C датчика внешней освещенности BH1750 станет 0x5C

Это важно в программировании. Если вывод ADD переведен в низкое логическое состояние путем подключения к земле, адрес ведомого устройства I2C датчика внешней освещенности BH1750 будет 0x23

Таким образом, два датчика внешней освещенности BH1750 могут быть подключены к одной шине I2C, где один вывод ADD имеет низкое логическое состояние, а другой вывод ADD высокое.

Пример скетча

В скетче мы каждые 1000 мсек считываем с датчика BH1750 показания освещённости в люксах и выводим эти данные в последовательный порт.

/*
Подключяем библиотеку Wire (для I2C)
*/
#include <Wire.h>
/*
Подключяем библиотеку для bh1750
*/
#include <BH1750.h>
/*
Объявляем объект lightMeter
*/
BH1750 lightMeter;

void setup() {
/*
Запускаем последовательный порт
*/
Serial.begin(9600);
/*
Инициализируем шину I2C (библиотека BH1750 не делает это автоматически)
На esp8266 вы можете выбрать выводы SCL и SDA, используя Wire.begin (D4, D3);
*/
Wire.begin();
/*
Инициализируем и запускаем BH1750
*/
lightMeter.begin();

Serial.println(F(«BH1750 тест»));
}

void loop() {
/*
Считываем показания с BH1750
*/
float lux = lightMeter.readLightLevel();
/*
Отправляем значение освещенности в последовательный порт
*/
Serial.print(«Light: «);
Serial.print(lux);
Serial.println(» lx»);
/*
раз в секунду
*/
delay(1000);
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

/*
   Подключяем библиотеку Wire (для I2C)
*/
#include <Wire.h>
/*
   Подключяем библиотеку для bh1750
*/
#include <BH1750.h>
/*
   Объявляем объект lightMeter
*/

BH1750lightMeter;

voidsetup(){

/*

     Запускаем последовательный порт
  */

Serial.begin(9600);

/*

    Инициализируем шину I2C (библиотека BH1750 не делает это автоматически)
    На esp8266 вы можете выбрать выводы SCL и SDA, используя Wire.begin (D4, D3);
  */

Wire.begin();

/*

    Инициализируем и запускаем BH1750
  */

lightMeter.begin();

Serial.println(F(«BH1750 тест»));

}
 

voidloop(){

/*

    Считываем показания с BH1750
  */

floatlux=lightMeter.readLightLevel();

/*

    Отправляем значение освещенности в последовательный порт
  */

Serial.print(«Light: «);

Serial.print(lux);

Serial.println(» lx»);

/*

     раз в секунду
  */

delay(1000);

}

Результат

Открыть монитор последовательного порта можно сочетанием клавиш Ctrl+Shift+M или через меню Инструменты. В мониторе последовательного порта побегут значения освещённости с нашего датчика BH1750.

Обзор

BH1750 имеет шесть различных режимов измерения, которые разделены на две группы:

  • непрерывные,
  • одноразовые измерения.

В непрерывном режиме датчик постоянно измеряет значение освещенности. В одноразовом режиме датчик выполняет только одно измерение и затем переходит в режим выключения питания.

Каждый режим имеет три разные точности:

  • Режим низкого разрешения — (точность 4 лк, время измерения 16 мс)
  • Режим высокого разрешения — (точность 1 лк, время измерения 120 мс)
  • Режим высокого разрешения 2 — (точность 0,5 лк, время измерения 120 мс)

По умолчанию в этой библиотеке используется непрерывный режим высокого разрешения, но вы можете изменить его на другой режим, передав аргумент mode в BH1750.begin().

Когда используется одноразовый режим, ваш датчик перейдет в режим выключения питания, когда он завершит измерение, и вы прочитаете его. Когда датчик снова включается, он возвращается в режим по умолчанию, что означает, что его необходимо перенастроить обратно в одноразовый режим. Эта библиотека была реализована для автоматической перенастройки датчика при следующей попытке измерения, поэтому вам не придется беспокоиться о таких деталях низкого уровня.

Обычно вы получите целочисленное значение, которое представляет эквивалент в люксах.

  • Режим низкого разрешения — (общий диапазон: от 0,0 до 54612,5 люкс)
  • Режим высокого разрешения — (общий диапазон: от 0,0 до 54612,5 люкс)
  • Режим высокого разрешения 2 — (общий диапазон: от 0,0 до 27306,25 люкс)

Сам датчик возвращает 16-битное целое число без знака. Поэтому максимальное значение ограничено в целом. Стандартное преобразование между так называемыми «отсчетами» в люкс составляет 1 / 1,2, что означает, что вы получаете меньшее значение. Поскольку используется float, в случае ошибки вы получите отрицательное значение.

  • -1 с датчика не поступило достоверных данных
  • -2 устройство не настроено. В противном случае измеренные значения преобразуются в люкс и возвращаются. Если никакие дополнительные параметры не изменены, максимальное значение люкс составляет 54612,5 лк.

Поскольку датчик учитывает воздействие света в определенный период времени, вы можете изменить этот период времени. Это необходимо, если вы используете накладываемые окна или компенсируете влияние окружающей среды, например, темнота. Этот период времени определяется регистром, который называется MTreg. Поэтому вы можете выбрать значение от 32 до 254. Значение по умолчанию — 69. Имейте в виду, что время измерения изменяется соответственно.

Техническое описание чипа BH1750 можно скачать здесь.

setResolutionVal()

Description

The method writes provided value to the measurement time register of the sensor.

  • The measurement resolution in conjunction with sensor’s current measurement accuracy (typical, maximal) and current measurement mode determines measurement time and measurement sensitivity in .
  • The method limits minimal measurement time to the typical one for current measurement mode.
  • The method forces typical value of the measurement time register at low measurement modes.

Parameters

  • mtreg: Desired value of measurement time register.
    • Valid values: 31 ~ 254, typical 69
    • Default value

      If current measurement mode is for low resolution, the value is always typical one.

      : none

Пример

Пример использования библиотеки BH1750 в сочетании с платой GY-30 (которая содержит компонент BH1750) представлен ниже. Пример кода использует библиотеку BH1750 в режиме непрерывной высокой точности по умолчанию при выполнении измерений освещенности.

Схема

Соединения:

  • VCC -> 3V3 или 5V
  • GND -> GND
  • SCL -> SCL (A5 на Arduino Nano, Uno, Leonardo и т.п., или 21 на Mega и Due, на esp8266 любой)
  • SDA -> SDA (A4 на Arduino Nano, Uno, Leonardo, и т.п. или 20 на Mega и Due, на esp8266 любой)
  • ADD -> NC/GND или VCC (см. ниже)

Вывод ADD используется для установки адреса I2C датчика. По умолчанию (если напряжение ADD меньше 0,7 * VCC), адрес датчика будет 0x23. Если его напряжение больше или равно напряжению 0,7 В (например, вы подключили его к VCC), адрес датчика будет 0x5C.

Подключение платы датчика GY-30 к Arduino показано на схеме выше.

Код

Загрузите код для BH1750 ниже на свою плату Arduino.

#include <Wire.h>
#include <BH1750.h>

BH1750 lightMeter;

void setup(){

  Serial.begin(9600);

  // Initialize the I2C bus (BH1750 library doesn't do this automatically)
  // On esp8266 devices you can select SCL and SDA pins using Wire.begin(D4, D3);
  Wire.begin();

  lightMeter.begin();
  Serial.println(F("BH1750 Test"));

}

void loop() {

  float lux = lightMeter.readLightLevel();
  Serial.print("Light: ");
  Serial.print(lux);
  Serial.println(" lx");
  delay(1000);

}

Вывод значений

Перемещение датчика к большему количеству света приводит к увеличению измерений в люксах.

BH1750 Test
Light: 70.0 lx
Light: 70.0 lx
Light: 59.0 lx
Light: 328.0 lx
Light: 333.0 lx
Light: 335.0 lx
Light: 332.0 lx

Что такое экспонометр?

В этом уроке я покажу вам, как сделать экспонометр, используя Arduino UNO, SSD1306 SPI OLED-дисплей, сенсорный модуль BH1750.

Если вы снимаете фотографии с помощью пленочных камер, вы можете использовать это руководство для создания собственного экспонометра, который можно носить с собой. Измеритель также может пригодиться для портретной фотографии, так как вам всегда нужен хороший свет для наилучшего захвата объекта.

Типичный экспонометр

Результаты датчика BH1750 могут быть неточными на 100%, но оно того стоит. В аналоговой фотографии люди все время использовали экспонометры для измерения света, соответствующего ISO их пленки.

В настоящее время для цифровых зеркальных камер всё цифровое и встроенное. Экспонометр — это в основном инструмент для измерения количества света, падающего на объект или отражающегося от объекта. Устройство собирает данные и преобразует результаты измерений в полезную информацию, которая затем сообщает скорость затвора и размер диафрагмы, необходимые для получения хороших фотографий.

Hardware

Connection Arduino UNO board — BH1750

Pins board — BH1750 VCC GND SDA SCL
Arduino UNO (ATMega328 boards) 5V GND A4 A5
Arduino Mega2560 5V GND D20 D21
Arduino Leonardo 5V GND D2 D3
Arduino DUE (ATSAM3X8E) 3V3 GND 20 21
ESP8266 3V3 GND GPIO4 (D2) GPIO5 (D1)
ESP32 3V3 GND GPIO21 GPIO22

Note: Tested ESP8266 / ESP32 boards:

  • ESP8266 boards: ESP12E / WeMos D1 & R2 / Node MCU v2 / v3
  • ESP32 boards: WeMos LOLIN32 / LOLIN D32

Other unlisted MCU’s may work, but are not tested.

WeMos LOLIN32 with OLED display

Change the following Wire initialization to:

// WeMos LOLIN32 with OLED support
Wire.begin(5, 4);

Note: pin may be floating (open) which is the same as LOW.

Программирование люксметра

Теперь можно подключить к разъемам ардуины преобразователь USB/SERIAL и начинать программировать

Для работы с дисплеем 5110 по любым 5-ти дискретным выводам использую библиотеку Adafruit-PCD8544-Nokia-5110-LCD-library и графическую библиотеку Adafruit-GFX-Library

Остальное из стандартного набора Arduino IDE

Микроконтроллер постоянно находится в режиме SLEEP_POWER_DOWN И включается/выключается длительным (более 2 сек) нажатием на кнопку питания. Ток в отключенном режиме порядка 100 мкА. Это достигнуто тем, что с платы демонтирован светодиод питания, аккумулятор заведен на контроллер минуя стабилизатор напряжения, включение всей периферии производится микроконтроллером через транзисторы. Все выходы при выключении переводятся в режим выхода в низкое состояние (LOW).

В рабочем режиме с периодичностью 1 сек выводятся показания датчика освещенности и напряжение аккумулятора.

Напряжение питания сравнивается с внутренним опорным напряжением 1.1В по методике описанной в этой статье

Скетч люксметра для ардуино

Конструктив

Изготовление корпуса

Размечаю окно под дисплей и дырки под кнопки


Делаю отверстия и ровняю из гравером

Примеряю плату с деталями

Подгоняю, проверяю отверстия

Батарейный отсек

Изготавливаю из старой заглушки от системного блока. Размягчаю феном, подгоняю под аккумулятор и вставляю две пружинки — контакты аккумулятора

Припаиваю провода к контактам и креплю батарейный отсек в корпусе на «холодную сварку»

После высыхания этого «чудо пластилина» получаю вполне надежное крепление аккумулятора в корпусе с возможностью его быстрого извлечения для зарядки

Размещаю все компоненты на макетной плате

И распаиваю согласно схемы любимыми тефлоновыми проводами

Сенсор освещенности

Под рукой оказалась прозрачная коробочка от SD-карточки. Поместил модуль освещенности пока туда, хотя выглядит достаточно неказисто. На отрезке гибкого 4-х жильного телефонного провода обжал разъемчики в стиле Ардуино

Собираю все вместе

Верхняя крышка

Рисую в графическом пакете макет надписей на верхнюю крышку и печатаю в зеркальном виде на прозрачную пленку, а затем приклеиваю ее к крышке

И вот готовый вид прибора

Circuit

The GY-302 module communicates via the I2C bus with the Arduino or ESP8266. The wiring is very simple.

Pin Description
GND Ground
ADDR Select I2C adresse. 0x23 by default. 0x5C if connected to 3V3
SDA I2C SDA
SCL I2C SCL
VCC 3.3V

For your Fritzing schemas, the component is available on GitHub here

On an Arduino, connect the SDA pin to pin A4 and SCL on pin A5. On the ESP8266 Wemos d1 mini, SDA is in D2 and SCL in D1. For other ESP8266 boards, read this article.

It is possible to manually assign the I2C bus pins using the Wire.h library. At the beginning of the program, the library is declared

Then in the setup ()

Here, all I2C devices are diverted to the new pins.

4Взаимодействие с сенсором BH1750 в деталях

Для управления датчиком мы должны по его I2C адресу записать код команды. Под управлением понимается изменение режима работы, изменение чувствительности, сброс и т.д. Команды можно передавать только по одной. Для чтения мы должны запросить из датчика 2 байта. Датчик хранит всегда значение в виде 16-битного числа, но его интерпретация зависит от текущей чувствительности.

Последовательность обмена с датчиком BH1750

На следующем рисунке представлен список команд, необходимых для работы с датчиком BH1750:

Команды управления датчиком BH1750

Как мы знаем, управление и обмен данными с датчиком BH1750 происходит по протоколу I2C. Мне нравится использовать для быстрых тестов общения с устройствами I2C и SPI отладочную плату с микросхемой FT2232H. Подключим SCL датчика к SCL микросхемы FT2232H, SDA датчика – к SDA и SDO микросхемы. Питание 5В возьмём с Arduino Nano, а все земли объединим.

Модуль с датчиком BH1750 управляется микросхемой FTDI

Теперь запустим программу SPI via FTDI и попробуем прочитать значения, хранящиеся в регистрах сенсора.

Чтение единичного показания датчика BH1750 с помощью FT2232HНепрерывное считывание показаний датчика BH1750 с помощью FT2232H

Developers

The following information is for developers of this library.

Code Format

The code in this project is formatted using tool.

Once the tool has been install you can then run the
convenience script () to check or apply the code
formatting. The script should be run from the repo’s top level directory.

$ ./ci/code-format.bash

This script is also run as part of the project’s continuous integration
checks.

If you make changes to code files then the code format can be applied
by simply passing apply as an argument to the script.

$ ./ci/code-format.bash apply

Code Linting

To run the linter over the project use the command below.

$ arduino-lint --library-manager update --compliance strict

The same command is run as part of the project’s continuous integration
checks.

If errors or warnings are reported then fix them and re-run the script
until they are resolved.

Build Locally

The code in this project can be built locally using the tool.
The tool can be installed using the instructions . Once you have the tool installed you can compile the
examples scripts using the convenience script ().

$ ./ci/compile-examples.bash

This script performs the same actions as the project’s continuous integration
compile checks.

Release Process

  • Update and version strings.
  • Create a new project release and use the new version number as tag. Click Publish.
  • Now wait about an hour for it to appear in the Arduino library manager.

Сравнение BH1750 и TSL2561

Спектр видимого света колеблется от 380 нм (фиолетовый) до 780 нм (красный) (в вакууме). Короче говоря, BH1750 просто измеряет это. TSL2561, помимо видимого спектра, также измеряет инфракрасное излучение. Он имеет два диода, один для видимого, а второй для инфракрасного. На мой взгляд, BH1750 соответствует большинству требований, тогда как TSL2561 предлагает более широкий спектр, большую чувствительность и большую точность.

Для сравнения, оба датчика были размещены параллельно в макете, один рядом с другим. Таким образом, можно получить практически одинаковое излучение на оба датчика.

Более подробно о том, как работать с TSL2561 в Ардуино, можете найти в отдельной статье Подключение цифрового датчика освещенности TSL2561 к Arduino.

На следующем рисунке показана схема подключения датчиков внешней освещенности TSL2561 и BH1750 к Arduino UNO.

Пример скетча

#include <Wire.h>
#include <BH1750.h>
#include <Adafruit_TSL2561_U.h>

BH1750 bh1750;
Adafruit_TSL2561_Unified tsl2561 = Adafruit_TSL2561_Unified(TSL2561_ADDR_FLOAT, 12345);

void setup() {
Serial.begin(9600);
Wire.begin();

/*
TSL2561
*/
if (!tsl2561.begin()) {
Serial.print(F(«При обнаружении TSL2561 возникла проблема … проверьте подключение!»));
while (1);
}

tsl2561.setGain(TSL2561_GAIN_1X);
tsl2561.setIntegrationTime(TSL2561_INTEGRATIONTIME_402MS);

/*
BH1750
*/
bh1750.begin(BH1750::ONE_TIME_HIGH_RES_MODE);

Serial.println(F(«BH1750 vs TSL2561»));
}

void loop() {
/*
Считываем показания с TSL2561
*/
sensors_event_t event;
tsl2561.getEvent(&event);
/*
Считываем показания с BH1750
*/
float lux = bh1750.readLightLevel();
/*
Отправляем значение освещенности в последовательный порт
*/
if (event.light) {
Serial.print(F(«TSL2561: «));
Serial.print(event.light);
Serial.println(F(» lx»));
} else {
/*
Если event.light = 0 люкса датчик, вероятно, насыщенные
и достоверные данные не может быть сгенерированы!
*/
Serial.println(F(«Насыщенные TSL2561»));
}
Serial.print(F(«BH1750 : «));
Serial.print(lux);
Serial.println(F(» lx»));

delay(1000);
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

#include <Wire.h>
#include <BH1750.h>
#include <Adafruit_TSL2561_U.h>
 

BH1750bh1750;

Adafruit_TSL2561_Unifiedtsl2561=Adafruit_TSL2561_Unified(TSL2561_ADDR_FLOAT,12345);

voidsetup(){

Serial.begin(9600);

Wire.begin();

/*

     TSL2561
  */

if(!tsl2561.begin()){

Serial.print(F(«При обнаружении TSL2561 возникла проблема … проверьте подключение!»));

while(1);

}

tsl2561.setGain(TSL2561_GAIN_1X);

tsl2561.setIntegrationTime(TSL2561_INTEGRATIONTIME_402MS);

/*

    BH1750
  */

bh1750.begin(BH1750::ONE_TIME_HIGH_RES_MODE);

Serial.println(F(«BH1750 vs TSL2561»));

}
 

voidloop(){

/*

    Считываем показания с TSL2561
  */

sensors_event_tevent;

tsl2561.getEvent(&event);

/*

    Считываем показания с BH1750
  */

floatlux=bh1750.readLightLevel();

/*

    Отправляем значение освещенности в последовательный порт
  */

if(event.light){

Serial.print(F(«TSL2561: «));

Serial.print(event.light);

Serial.println(F(» lx»));

}else{

/*

      Если event.light = 0 люкса датчик, вероятно, насыщенные
      и достоверные данные не может быть сгенерированы!
    */

Serial.println(F(«Насыщенные TSL2561»));

}

Serial.print(F(«BH1750 : «));

Serial.print(lux);

Serial.println(F(» lx»));

delay(1000);

}

Результат

По результатам TSL2561 и BH1750 дают практически идентичные показатели в одинаковых условиях. Это говорит о том, что сами датчики идут откалиброванными с завода.

Испытание люксметра

Для проверки показаний взят простой прибор DT-1300

Разница показаний примерно 2-4%, что вполне укладывается в точность DT-1300 5%

Там где освещение не равномерное разница увеличивается из за отличий в форме датчиков приборов

Прошелся по комнатам с различными светильниками

  • Люстра с эффектом бесконечности дает освещенность 100-110 лк в центре комнаты, уменьшаясь до 75-80 лк по углам. Включение направленной подсветки — 400 лк на поверхности стола
  • Встраиваемые светильники в корпусе GX-70 — 125-135 лк
  • COB-матрица в ванной комнате — 120-130 лк
  • Настольная лампа на COB 20 Вт — 500-1000 лк в зависимости от зоны стола и направленности светильника

Исходный код программы (скетча)

Arduino

#include<Wire.h>
#include<LiquidCrystal.h>

int BH1750address = 0x23;
byte buff;
LiquidCrystal lcd (7,6,5,4,3,2); //RS, E, D4, D5, D6, D7
void setup()
{
Wire.begin();
//Serial.begin(9600);
lcd.begin(16,2);
lcd.print(» BH1750 Light «);
lcd.setCursor(0,1);
lcd.print(«Intensity Sensor»);
delay(2000);
}

void loop()
{
int i;
uint16_t value=0;
BH1750_Init(BH1750address);
delay(200);

if(2==BH1750_Read(BH1750address))
{
value=((buff<<8)|buff)/1.2;
lcd.clear();
lcd.print(«Intensity in LUX»);
lcd.setCursor(6,1);
lcd.print(value);

//Serial.print(val);
//Serial.println(«»);
}
delay(150);
}

int BH1750_Read(int address)
{
int i=0;
Wire.beginTransmission(address);
Wire.requestFrom(address, 2);
while(Wire.available())
{
buff = Wire.read();
i++;
}
Wire.endTransmission();
return i;
}

void BH1750_Init(int address)
{
Wire.beginTransmission(address);
Wire.write(0x10);
Wire.endTransmission();
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

#include<Wire.h>
#include<LiquidCrystal.h>

intBH1750address=0x23;

bytebuff2;

LiquidCrystallcd(7,6,5,4,3,2);//RS, E, D4, D5, D6, D7

voidsetup()

{

Wire.begin();

//Serial.begin(9600);

lcd.begin(16,2);

lcd.print(»  BH1750 Light  «);

lcd.setCursor(,1);

lcd.print(«Intensity Sensor»);

delay(2000);

}

voidloop()

{

inti;

uint16_tvalue=;

BH1750_Init(BH1750address);

delay(200);

if(2==BH1750_Read(BH1750address))

{

value=((buff<<8)|buff1)1.2;

lcd.clear();

lcd.print(«Intensity in LUX»);

lcd.setCursor(6,1);

lcd.print(value);

//Serial.print(val);    

//Serial.println(«»);

}

delay(150);

}

intBH1750_Read(intaddress)

{

inti=;

Wire.beginTransmission(address);

Wire.requestFrom(address,2);

while(Wire.available())

{

buffi=Wire.read();

i++;

}

Wire.endTransmission();

returni;

}

voidBH1750_Init(intaddress)

{

Wire.beginTransmission(address);

Wire.write(0x10);

Wire.endTransmission();

}

Example continues conversion high resolution

#include <Wire.h>
#include <ErriezBH1750.h>

// ADDR line LOW/open:  I2C address 0x23 (0x46 including R/W bit) 
// ADDR line HIGH:      I2C address 0x5C (0xB8 including R/W bit)
BH1750 sensor(LOW);

void setup()
{
  Serial.begin(115200);
  Serial.println(F("BH1750 continues measurement high resolution example"));

  // Initialize I2C bus
  Wire.begin();

  // Initialize sensor in continues mode, high 0.5 lx resolution
  sensor.begin(ModeContinuous, ResolutionHigh);

  // Start conversion
  sensor.startConversion();
}

void loop()
{
  uint16_t lux;

  // Wait for completion (blocking busy-wait delay)
  if (sensor.isConversionCompleted()) {
    // Read light
    lux = sensor.read();

    // Print light
    Serial.print(F("Light: "));
    Serial.print(lux / 2);
    Serial.print(F("."));
    Serial.print(lux % 10);
    Serial.println(F(" LUX"));
  }
}

Output

BH1750 continues measurement high resolution example
Light: 15.0 LUX
Light: 31.2 LUX
Light: 385.0 LUX
Light: 575.1 LUX
Light: 667.5 LUX