ВН1750. Датчик внешней освещенности с шиной I2C.
BH1750 — это датчик внешней освещенности с достаточно высоким разрешением и чувствительностью. Он ведет себя в видимом свете так же, как человеческий глаз, не подвержен влиянию инфракрасного излучения и не зависит от цветовой температуры типа освещения, то есть хорошо работает как с естественным светом, так и с различные виды искусственного освещения. Он осуществляет цифровую связь с микроконтроллером, с Шина I2C, поэтому он устойчив к помехам, если находится на определенном расстоянии от схемы, которая его считывает. Время его отклика довольно низкое, менее 200 мс в самых неблагоприятных обстоятельствах.
С электронной точки зрения его реализация очень проста. Просто подключите питание (между 2,4 В и 3,6 В) и Шина I2C. При желании адрес шины можно изменить для соединения двух устройств (при ADDR на низком уровне это 0B0100011 или 0x23, а при ADDR на высоком уровне это 0B1011100 или 0x5C), а линию VDI можно использовать для функции сброса с помощью микроконтроллер.
Чтобы подключить BH1750 к Arduino, помимо питания от выхода 3,3 В, правильнее всего в дополнение к преобразователю уровня использовать преобразователь уровней. подтягивающие резисторы для Шина I2C. Хотя компонент будет поддерживать прямое подключение к шине Шина I2C Не рекомендуется определять размер схемы без учета преобразования уровня.
Из-за его популярности, которая обусловлена его очень низкой стоимостью по сравнению с его точностью, существует несколько модулей, таких как известный GY-30, который можно увидеть на фотографии в начале. Чтобы их было удобнее подключать при прототипировании с микроконтроллером, в них обычно включают преобразователи уровней для Шина I2C и стабилизаторы напряжения для питания их более высоким напряжением (до 5 В) вместо выхода 3,3 В, как у Arduino.
BH1750 имеет два режима считывания: непрерывный и индивидуальный, которые соответствуют двум состояниям: активному и малому энергопотреблению или спящему режиму. Если используется режим непрерывного считывания, BH1750 остается активным после отбора проб, но после выполнения отдельного измерения он автоматически переходит в спящий режим и режим пониженного энергопотребления. Первое считывание в непрерывном режиме занимает максимум 180 мс, а последующие — от 16 до 120 мс в зависимости от разрешения.
Датчик способен измерять с интервалом (разрешением) 4 люкс, 1 люкс и 0,5 люкс. В технических характеристиках BH1750 рекомендуется использовать разрешение 1 люкс, которое позволяет различать освещенность ниже 10 люкс (что соответствует сумеркам) и более невосприимчиво к шуму, который может повлиять на измерения.
При разрешении 1 люкс и 4 люкс используются 16 бит данных для представления целой части, поэтому может быть достигнуто максимальное измерение 65535 0,5 люкс (солнечный день без прямого освещения). В режиме 0,5 люкс используется младший бит десятичной части (измеряется от 0,5 люкс до 15 люкс), поэтому с помощью оставшихся 32767 бит можно представить максимальное значение XNUMX люкс (снаружи без прямого освещения).
Обычно оптическое окно, в соответствии с которым измеряется окружающий свет, соответствует всему видимому спектру, и цель состоит в том, чтобы добиться в нем распределения чувствительности, сравнимого с человеческим. При уменьшении оптического окна (свет измеряется в меньшем диапазоне длин волн) чувствительность BH1750 можно увеличить (до 0,11 люкс) с режимом отмены регулировки влияния оптического окна за счет увеличения времени отсчета. в пропорции. Поскольку в этом специальном (увеличенном) режиме снимаются отдельные показания, контекст должен позволять это делать без особого изменения условий измерения (например, датчик должен оставаться очень стабильным, он не должен перемещаться в область с разными условиями освещения)
Коды операций BH1750
состояние
5>
-
0B00000000
(0x00
) Режим пониженного энергопотребления или режима ожидания. -
0B00000001
(0x01
) Включен. -
0B00000111
(0x07
) Перезагрузить. Очищает журналы данных BH1750.
Разрешение
5>
-
0B00010011
(0x13
) Непрерывное измерение с разрешением 4 люкс (от 16 мс до времени считывания) -
0B00010000
(0x10
) Непрерывное измерение с разрешением 1 люкс (время считывания 120 мс) -
0B00010001
(0x11
) Непрерывное измерение с разрешением 0,5 люкс (время считывания 120 мс) -
0B00100011
(0x23
) Измерение при разрешении 4 люкс (время считывания 16 мс) -
0B00100000
(0x20
) Измерение при разрешении 1 люкс (время считывания 120 мс) -
0B00100001
(0x21
) Измерение при разрешении 0,5 люкс (время считывания 120 мс)
Регулировка изменения оптического окна
5>
-
0B011MT
[0,1,2,3,4] Младший бит регистра MTREG (РЕГИСТР времени измерения). -
0B01000MT
[5,6,7] Старший бит регистра MTREG.
Прочтите BH1750 от Arduino.
Для измерения окружающего освещения с помощью BH1750 от Arduino библиотека используется Провод который управляет связью с Шина I2C. Процесс обычный для такого типа коммуникаций, сначала они активируются (один раз в программе) с помощью Wire.begin()
, связь с BH1750 начинается с Wire.beginTransmission()
и ваш адрес I2C (0x5C или 0x23 в зависимости от того, высокий или низкий уровень ADDR соответственно), он настраивается путем отправки соответствующего кода с помощью Wire.write()
и автобус выпускается с Wire.endTransmission()
15
|
Wire.begin();
|
17
18
19
|
Wire.beginTransmission(DIRECCION_BH1750_0);
Wire.write(MEDIDA_CONTINUA_UN_LUX_BH1750);
Wire.endTransmission();
|
Если используется один из режимов непрерывного чтения, Wire.beginTransmission() используется для получения данных по адресу I2C что соответствует доступу к BH1750, вам будет предложено ввести два байта (разрешение 16 бит) с Wire.requestFrom()
которые читаются с помощью Wire.read()
, и загружаются в беззнаковое целое число, поворачивая первый байт на 8 бит. Впоследствии автобус был выпущен с Wire.endTransmission()
. Конечный результат получается путем деления возвращаемого значения на коэффициент точности (1,2, если оптическое окно не изменяется).
28
29
|
Wire.beginTransmission(DIRECCION_BH1750_0);
Wire.requestFrom(DIRECCION_BH1750_0,2);
|
37
38
|
lectura_BH1750=Wire.read()<<8; // Leer el primer byte y rotarlo 8 bits
lectura_BH1750|=Wire.read(); // Leer el segundo byte y «juntarlo» con el anterior on OR
|
40
|
iluminacion=long(100.0*(float)lectura_BH1750/DIVISOR_PRECISION)/100; // Resultado corregido y sin decimales
|
Если используется режим индивидуальных показаний, BH1750 переходит в спящий режим.Для возврата в активный режим можно отправить конфигурацию (тот же режим чтения или новый) или код включения (0x01). Код выключения (1750x0) можно использовать для перевода BH00 в спящий режим.
Важно соблюдать время считывания датчика, которое зависит от разрешения. Если ожидание не критично, его можно объединить в значение для всех случаев, которое может быть немного больше ожидаемого максимума, чтобы гарантировать завершение чтения.
Чтобы сделать написание кода для BH1750 более удобным в Arduino, наиболее подходящие коды операций находятся в следующем заголовочном документе.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
#define REPOSAR_BH1750 0x00 // Modo de reposo o bajo consumo
#define ENCENDER_BH1750 0x01
#define RESETEAR_BH1750 0x07
#define MEDIDA_CONTINUA_CUATRO_LUX_BH1750 0x13
#define MEDIDA_CONTINUA_UN_LUX_BH1750 0x10
#define MEDIDA_CONTINUA_MEDIO_LUX_BH1750 0x11
#define MEDIDA_SIMPLE_CUATRO_LUX_BH1750 0x23
#define MEDIDA_SIMPLE_UN_LUX_BH1750 0x20
#define MEDIDA_SIMPLE_MEDIO_LUX_BH1750 0x21
#define ESPERA_BH1750_0 250 // 250 milisegundos de espera de lectura del BH1750 (mayor que la máxima)
#define TIMEOUT_I2C 10 // 10 milisegundos de espera antes de renunciar a leer el bus I2C
#define DIVISOR_PRECISION 1.2 // valor por el que dividir la lectura para calcular la luminosidad 1.2 si no hay cambios en la ventana óptica
#define DIRECCION_BH1750_0 0x23
#define DIRECCION_BH1750_1 0x5C
|
В следующем примере кода показан наиболее распространенный режим считывания датчика освещенности. I2C ВН1750. Разрешение составляет 1 люкс, режим чтения непрерывный. В примере показано использование последовательной консоли Arduino, каждый результат получен на основе измеренного значения.
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
|
#include “BH1750.h” // Cargar los códigos de operación del BH1750
#include <Wire.h>
unsigned int lectura_BH1750;
unsigned int iluminacion;
//float iluminacion; // Mostrar el valor con decimales
long cronometro_lecturas=0;
long tiempo_transcurrido;
long cronometro_timeout_i2c;
void setup()
{
Serial.begin(9600);
Wire.begin();
delay(ESPERA_BH1750_0); // Espera inicial para estabilizar el BH1750
Wire.beginTransmission(DIRECCION_BH1750_0);
Wire.write(MEDIDA_CONTINUA_UN_LUX_BH1750);
Wire.endTransmission();
}
void loop()
{
tiempo_transcurrido=millis()–cronometro_lecturas;
if(tiempo_transcurrido>ESPERA_BH1750_0)
{
cronometro_lecturas=millis();
Wire.beginTransmission(DIRECCION_BH1750_0);
Wire.requestFrom(DIRECCION_BH1750_0,2);
do
{
tiempo_transcurrido=millis()–cronometro_timeout_i2c;
}
while(Wire.available()<2&&tiempo_transcurrido<TIMEOUT_I2C);
if(Wire.available()>1)
{
lectura_BH1750=Wire.read()<<8; // Leer el primer byte y rotarlo 8 bits
lectura_BH1750|=Wire.read(); // Leer el segundo byte y «juntarlo» con el anterior on OR
//iluminacion=lectura_BH1750/DIVISOR_PRECISION; // Resultado corregido y con decimales (mínimamente más preciso pero menos legible)
iluminacion=long(100.0*(float)lectura_BH1750/DIVISOR_PRECISION)/100; // Resultado corregido y sin decimales
Serial.print(“La iluminación es de “);
Serial.print(iluminacion);
Serial.println(” lux”);
}
}
}
|
Как я уже говорил выше, режимы разрешения 1 люкс и 4 люкс используют 16 бит данных для выражения измерения в виде целого числа. С другой стороны, в режиме 0,5 люкс последний бит представляет собой десятичную часть, то есть значение, которое вносит вклад в общее измерение, сдвигается на степень двойки вправо. В режиме 1 люкс или 4 люкс последний бит (LSB) стоит 20, предпоследний 21, следующие 22…в режиме 0,5 люкс последний бит (LSB) стоит 2-1, предпоследний 20, следующие 21...
В соответствии с этой структурой данных и учитывая, что необходимо выполнить два чтения I2C байта, чтобы получить 16-битное значение, вам необходимо загрузить старшие биты байта, которые будут читаться первыми, и повернуть их на 8 бит влево в режиме разрешения 1 люкс и в режиме разрешения 4 люкс и всего 7 бит при 0,5 люкс. Чтобы унифицировать способ чтения в режиме 0,5 люкс, вы можете загрузить старший байт в беззнаковое целое число, повернуть на 8 бит влево, загрузить младший байт и повернуть все целое беззнаковое число на 1 бит влево. значение десятичной части, обозначающее LSB (младший значащий бит) чтобы применить его позже.
Логично, что для режимов 1 люкс или 4 люкс необходимо использовать целые числа без знака (unsigned int
) зачем Arduino не резервируйте MSB (самый старший бит) за знак и иметь возможность оперировать непосредственно с истинным значением измерения, а не с отрицательным числом. В Ардуино из-за в этом нет необходимости, поскольку целые числа используют 32 бита, но та же программа также будет работать, если ее использовать. unsigned int
.
Следующий код показывает, как будет использоваться режим 0,5 люкс.
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
|
#include “BH1750.h” // Cargar los códigos de operación del BH1750
#include <Wire.h>
unsigned int lectura_BH1750;
//unsigned int iluminacion;
float iluminacion; // Mostrar el valor con decimales
long cronometro_lecturas=0;
long tiempo_transcurrido;
long cronometro_timeout_i2c;
bool parte_decimal;
void setup()
{
Serial.begin(9600);
Wire.begin();
delay(ESPERA_BH1750_0); // Espera inicial para estabilizar el BH1750
Wire.beginTransmission(DIRECCION_BH1750_0);
Wire.write(MEDIDA_CONTINUA_MEDIO_LUX_BH1750);
Wire.endTransmission();
}
void loop()
{
tiempo_transcurrido=millis()–cronometro_lecturas;
if(tiempo_transcurrido>ESPERA_BH1750_0)
{
cronometro_lecturas=millis();
Wire.beginTransmission(DIRECCION_BH1750_0);
Wire.requestFrom(DIRECCION_BH1750_0,2);
do
{
tiempo_transcurrido=millis()–cronometro_timeout_i2c;
}
while(Wire.available()<2&&tiempo_transcurrido<TIMEOUT_I2C);
if(Wire.available()>1)
{
lectura_BH1750=Wire.read()<<8; // Leer el primer byte y rotarlo 8 bits
lectura_BH1750|=Wire.read(); // Leer el segundo byte y «juntarlo» con el anterior on OR
parte_decimal=(lectura_BH1750<<15)>0;
lectura_BH1750>>=1;
iluminacion=((float)lectura_BH1750+(parte_decimal?0.5:0.0))/DIVISOR_PRECISION;
Serial.print(“La iluminación es de “);
Serial.print(iluminacion);
Serial.println(” lux”);
}
}
}
|
Оставить комментарий