BH1750. Сензор за околна светлина с I2C шина.
BH1750 е сензор за околна светлина със сравнително висока разделителна способност и чувствителност. Той се държи при видима светлина по начин, сравним с този на човешкото око и не се влияе от инфрачервеното лъчение, нито зависи от цветната температура на вида осветление, тоест работи добре с естествена светлина и с различни видове изкуствено осветление. Той комуникира цифрово с микроконтролера, с I2C шина, така че е устойчив на смущения, ако се постави на определено разстояние от веригата, която го чете. Времето му за реакция е доста ниско, по-малко от 200 ms при най-неблагоприятни обстоятелства.
От електронна гледна точка изпълнението му е много просто. Просто свържете захранването (между 2,4 V и 3,6 V) и I2C шина. По избор адресът на шината може да бъде променен за свързване на две устройства (с ADDR на ниско ниво е 0B0100011 или 0x23 и с ADDR на високо ниво е 0B1011100 или 0x5C) и VDI линията може да се използва за функцията за нулиране с микроконтролер.
За да свържете BH1750 към Arduino, освен че се захранва от изхода 3,3 V, най-правилно е да се използва и преобразувател на ниво в допълнение към издърпващи резистори за I2C шина. Въпреки че компонентът ще поддържа директна връзка с шината I2C шина Не е препоръчително да оразмерявате верига, без да обмислите преобразуване на нивото.
Поради своята популярност, която се дължи на това, че е много евтин спрямо прецизността си, има няколко модула, като добре познатия GY-30, който може да се види на снимката в началото. За да ги свържете по-удобно при прототипиране с микроконтролер, те обикновено включват преобразуватели на ниво за I2C шина и регулатори на напрежението, за да ги захранват с по-високо напрежение (до 5V) вместо 3,3V изход на Arduino.
BH1750 има два режима на четене, непрекъснат и индивидуален, които съответстват на две състояния, активно и ниска мощност или заспиване. Докато, ако се използва режим на непрекъснато отчитане, BH1750 остава активен след вземане на проби, след извършване на индивидуално измерване той автоматично влиза в режим на заспиване и ниска мощност. Първото отчитане в непрекъснат режим отнема максимум 180 ms, а следващите между 16 ms и 120 ms в зависимост от разделителната способност.
Сензорът може да измерва на интервали (резолюция) от 4 лукса, 1 лукс и 0,5 лукса. BH1750 препоръчва в своя лист с данни да се използва разделителна способност от 1 лукс, което позволява да се разграничат осветености под 10 лукса (което съответства на здрач) и е по-устойчив на шум, който може да повлияе на измерването.
Резолюциите от 1 лукс и 4 лукса използват 16 бита данни, за да представят цялата част, така че може да се постигне максимално измерване от 65535 0,5 лукса (слънчев ден без пряка светлина). Режимът 0,5 лукса използва най-малкия бит за десетичната част (измерва от 0,5 лукса до 15 лукса), така че с останалите 32767 бита е възможно да се представи максимална стойност от XNUMX лукса (външност без пряка светлина)
Обикновено оптичният прозорец, според който се измерва околната светлина, съответства на целия видим спектър и целта е да се постигне разпределение на чувствителността в него, сравнимо с това на хората. Ако оптичният прозорец е намален (светлината се измерва в по-нисък диапазон на дължина на вълната), чувствителността на BH1750 може да се увеличи (до 0,11 лукса) с режим на отмяна на настройката на влиянието на оптичния прозорец чрез увеличаване на отчитането на времето пропорционално. Тъй като в този специален (извънгабаритен) режим се вземат отделни показания, контекстът трябва да позволява това, без особено да променя условията на измерване (например сензорът трябва да остане много стабилен, не трябва да се мести в зона с различни условия на осветеност)
Операционни кодове BH1750
Estado
5>
-
0B00000000
(0x00
) Ниска мощност или режим на неактивност. -
0B00000001
(0x01
) Включен. -
0B00000111
(0x07
) Нулиране. Изчиства регистрационните файлове с данни на BH1750.
резолюция
5>
-
0B00010011
(0x13
) Непрекъснато измерване при разделителна способност 4 лукса (между 16 ms и време за отчитане) -
0B00010000
(0x10
) Непрекъснато измерване при разделителна способност 1 лукс (120 ms време за отчитане) -
0B00010001
(0x11
) Непрекъснато измерване при разделителна способност 0,5 лукс (120 ms време за отчитане) -
0B00100011
(0x23
) Измерване при разделителна способност 4 лукса (16 ms време за отчитане) -
0B00100000
(0x20
) Измерване при разделителна способност 1 лукса (120 ms време за отчитане) -
0B00100001
(0x21
) Измерване при разделителна способност 0,5 лукса (120 ms време за отчитане)
Корекция за промяна на оптичния прозорец
5>
-
0B011MT
[0,1,2,3,4] Нисък бит от регистъра MTREG (Measurement Time REGister). -
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 BH1750. Разделителната способност е 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”);
}
}
}
|
Изтеглете документите за примерите за измерване на околната светлина със сензор BH1750 и Arduino.
Публикувай коментар