BH1750. Senzor zunanje svetlobe z vodilom I2C.
BH1750 je senzor ambientalne osvetlitve z razmeroma visoko ločljivostjo in občutljivostjo. V vidni svetlobi se obnaša podobno kot človeško oko in nanj ne vpliva infrardeče sevanje, niti ni odvisen od barvne temperature vrste osvetlitve, kar pomeni, da dobro deluje z naravno svetlobo in z različne vrste umetne razsvetljave. Digitalno komunicira z mikrokontrolerjem, z I2C vodilo, zato je odporen na motnje, če je nameščen na določeni razdalji od vezja, ki ga bere. Njegov odzivni čas je precej nizek, manj kot 200 ms v najbolj neugodnih okoliščinah.
Z elektronskega vidika je njegova izvedba zelo enostavna. Preprosto priključite napajanje (med 2,4 V in 3,6 V) in I2C vodilo. Po želji je mogoče naslov vodila spremeniti za povezavo dveh naprav (z ADDR na nizki ravni je 0B0100011 ali 0x23 in z ADDR na visoki ravni je 0B1011100 ali 0x5C), linija VDI pa se lahko uporabi za funkcijo ponastavitve z mikrokrmilnik.
Za povezavo BH1750 z Arduino, je poleg napajanja z izhodom 3,3 V najbolj pravilno uporabiti poleg nivojskega pretvornika pull-up upori za I2C vodilo. Čeprav bo komponenta podpirala neposredno povezavo z vodilom I2C vodilo Ni priporočljivo dimenzionirati vezja brez upoštevanja pretvorbe ravni.
Zaradi svoje priljubljenosti, ki je posledica zelo poceni glede na natančnost, obstaja več modulov, kot je znani GY-30, ki ga lahko vidimo na fotografiji na začetku. Za udobnejšo povezavo pri izdelavi prototipov z mikrokrmilnikom običajno vključujejo pretvornike ravni za I2C vodilo in regulatorji napetosti, da jih napajate z višjo napetostjo (do 5 V) namesto 3,3 V izhoda Arduino.
BH1750 ima dva načina branja, neprekinjeno in individualno, ki ustrezata dvema stanjema, aktivno in nizko porabo ali spanje. Če je uporabljen način neprekinjenega odčitavanja, BH1750 ostane aktiven po vzorčenju, po izvedbi posamezne meritve samodejno preide v način mirovanja in nizke porabe. Prvo branje v neprekinjenem načinu traja največ 180 ms, naslednje pa med 16 ms in 120 ms, odvisno od ločljivosti.
Senzor lahko meri v intervalih (ločljivost) 4 lux, 1 lux in 0,5 lux. BH1750 v svojem podatkovnem listu priporoča uporabo ločljivosti 1 luks, ki omogoča razlikovanje osvetlitev pod 10 luksov (kar ustreza mraku) in je bolj odporen na hrup, ki bi lahko vplival na merjenje.
Ločljivosti 1 in 4 luksi uporabljajo 16 bitov podatkov za predstavitev celotnega dela, tako da je mogoče doseči največjo meritev 65535 luksov (sončen dan brez neposredne svetlobe). Način 0,5 luksa uporablja najmanj pomemben bit za decimalni del (meri od 0,5 luksa do 0,5 luksa), tako da je s preostalimi 15 biti mogoče predstaviti največjo vrednost 32767 luksa (zunanjost brez neposredne svetlobe)
Običajno optično okno, po katerem se meri ambientalna svetloba, ustreza celotnemu vidnemu spektru, cilj pa je doseči porazdelitev občutljivosti v njem, primerljivo s človeško. Če se optično okno zmanjša (svetloba se meri v krajšem območju valovnih dolžin), se lahko poveča občutljivost BH1750 (do 0,11 luksa) z načinom preklica prilagajanja vpliva optičnega okna s povečanjem odčitavanja časa. v razmerju. Ker se v tem posebnem (predimenzioniranem) načinu merijo ločeni odčitki, mora kontekst to omogočati brez posebnega spreminjanja merilnih pogojev (senzor mora na primer ostati zelo stabilen, ne sme se premakniti na območje z drugačnimi svetlobnimi pogoji)
Kode delovanja BH1750
Estado
5>
-
0B00000000
(0x00
) Nizka poraba energije ali način mirovanja. -
0B00000001
(0x01
) Prižgan. -
0B00000111
(0x07
) Ponastaviti. Počisti podatkovne dnevnike BH1750.
Resolucija
5>
-
0B00010011
(0x13
) Neprekinjeno merjenje pri ločljivosti 4 luksov (med 16 ms in časom odčitavanja) -
0B00010000
(0x10
) Neprekinjeno merjenje pri ločljivosti 1 luks (čas odčitavanja 120 ms) -
0B00010001
(0x11
) Neprekinjeno merjenje pri ločljivosti 0,5 luks (čas odčitavanja 120 ms) -
0B00100011
(0x23
) Meritev pri ločljivosti 4 luksov (čas odčitavanja 16 ms) -
0B00100000
(0x20
) Meritev pri ločljivosti 1 luksov (čas odčitavanja 120 ms) -
0B00100001
(0x21
) Meritev pri ločljivosti 0,5 luksov (čas odčitavanja 120 ms)
Prilagoditev za spremembo v optičnem oknu
5>
-
0B011MT
[0,1,2,3,4] Nizki bit registra MTREG (Measurement Time REGister). -
0B01000MT
[5,6,7] Visoki bit registra MTREG.
Preberite BH1750 iz Arduina
Za merjenje osvetlitve okolice z BH1750 iz Arduino knjižnica se uporablja Wire ki upravlja komunikacijo z I2C vodilo. Postopek je običajen pri tovrstnih komunikacijah, najprej se aktivirajo (enkrat v programu) z Wire.begin()
, se komunikacija z BH1750 začne z Wire.beginTransmission()
in vaš naslov I2C (0x5C ali 0x23, odvisno od tega, ali je ADDR visok ali nizek), se konfigurira s pošiljanjem ustrezne kode z Wire.write()
in avtobus se sprosti z Wire.endTransmission()
15
|
Wire.begin();
|
17
18
19
|
Wire.beginTransmission(DIRECCION_BH1750_0);
Wire.write(MEDIDA_CONTINUA_UN_LUX_BH1750);
Wire.endTransmission();
|
Če je uporabljen eden od načinov neprekinjenega branja, se za pridobitev podatkov z naslovom uporabi Wire.beginTransmission(). I2C ki ustreza dostopu do BH1750, ste pozvani k vnosu dveh bajtov (ločljivost je 16 bitov) z Wire.requestFrom()
ki se berejo, uporabljajo Wire.read()
in se naložijo v nepredznačeno celo število, pri čemer se prvi bajt zasuka za 8 bitov. Avtobus je naknadno izpuščen z Wire.endTransmission()
. Končni rezultat dobimo tako, da vrnjeno vrednost delimo s faktorjem natančnosti (1,2, če optično okno ni spremenjeno)
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
|
Če je uporabljen način individualnega odčitavanja, preide BH1750 v način mirovanja.Za vrnitev v aktivni način se lahko pošlje konfiguracija (isti način odčitavanja ali nov) ali koda za vklop (0x01). S kodo za zaustavitev (1750x0) lahko BH00 prisilite v način mirovanja.
Pomembno je upoštevati čas odčitavanja senzorja, ki je odvisen od ločljivosti. Če čakanje ni kritično, ga je mogoče poenotiti v vrednost za vse primere, ki je lahko nekoliko večja od pričakovane največje vrednosti, da se zagotovi dokončanje branja.
Za bolj udobno pisanje kode za BH1750 Arduino, so najpomembnejše kode operacij v naslednjem naslovnem dokumentu.
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
|
Naslednji primer kode prikazuje najpogostejši način branja v svetlobnem senzorju I2C BH1750. Ločljivost je 1 luks in način branja je neprekinjen. Primer prikazuje uporabo serijske konzole Arduino, vsak rezultat, dobljen iz izmerjene vrednosti.
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”);
}
}
}
|
Kot sem rekel zgoraj, oba načina ločljivosti 1 luks in 4 luksi uporabljata 16 bitov podatkov za izražanje meritve kot celega števila. Po drugi strani pa v načinu 0,5 luksa zadnji bit predstavlja decimalni del, kar pomeni, da je vrednost, ki prispeva k skupni meritvi, premaknjena za potenco dva v desno. V načinu 1 luks ali 4 luksi zadnji bit (LSB) je vreden 20, predzadnji 21, naslednja 22…v načinu 0,5 luksa zadnji bit (LSB) je vreden 2-1, predzadnji 20, naslednja 21...
Glede na to podatkovno strukturo in glede na to, da je treba opraviti dve odčitki I2C bajta, da dobite 16-bitno vrednost, morate naložiti najpomembnejše bite bajta, prve, ki jih je treba prebrati, in jih zasukati za 8 bitov v levo v načinu ločljivosti 1 luksa in v načinu ločljivosti 4 luksa ter samo 7 bitov pri 0,5 luksa. Za poenotenje načina branja v načinu 0,5 luksa lahko najpomembnejši bajt naložite v nepredznačeno celo število, zavrtite za 8 bitov v levo, naložite najmanj pomemben bajt in celotno nepredznačeno celo število zasukate za 1 bit v levo. desno, ohranite vrednost decimalnega dela, ki označuje LSB (najmanj pomemben bit) da ga uporabite pozneje.
Logično je, da je za načine 1 luks ali 4 luks potrebno uporabiti cela števila brez predznaka (unsigned int
) kaj za Arduino ne rezervirajte MSB (najpomembnejši bit) za znak in lahko neposredno operirate s pravo vrednostjo meritve, ne z negativnim številom. notri Arduino zaradi ni potrebno, ker cela števila uporabljajo 32 bitov, vendar bo isti program deloval tudi, če se uporablja tudi unsigned int
.
Naslednja koda prikazuje, kako bi se uporabil način 0,5 luksa
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”);
}
}
}
|
Prenesite dokumente za primere merjenja ambientalne svetlobe s senzorjem BH1750 in Arduino.
po Komentar