4.3 Senzor svetla DLIGHT HAT
M5Stack DLIGHT HAT
Moduly od spoločnosti M5Stack s označením HAT sú určené výhradne pre M5Stick, pripájajú sa do jeho vrchnej časti. Modul DLIGHT HAT meria intenzitu svetla. Je vybavený senzorom BH1750FVI, pripojeným ku zbernici I²C na GPIO 26 (SCL) a 0 (SDA), má adresu 0x23.
Senzor svetla BH1750FVI
Senzor BH1750FVI je integrovaným obvodom s A/D prevodníkom, ktorý intenzitu svetla prevedie do 16-bitového čísla, typicky rozsahu 0 až 54613 lx. Každý kus senzoru má však inú presnosť, podľa špecifikácií je potrebné nameranú hodnotu deliť koeficientom od 0,96 po 1,44, pričom typickou hodnotou je 1,2 - práve táto typická hodnota je použitá v odkazovanej MicroPython knižnici (ovládači).
Senzor vie merať v dvoch režimoch, líšia sa rozlíšením a dobou merania:
- režim vysokej presnosti (predvolený v knižnici): odchýlka ±1 lx, 180 ms;
- rýchly režim nízkej presnosti: odchýlka ±4 lx, 24 ms.
Ukážkový program
Samotná knižnica (ovládač) je veľmi jednoduchá, ide len o funkciu sample(), ktorej povinným parametrom je inštancia zbernice.
Priebežný výpis aktuálnej intenzity svetla, kým nestlačíme tlačidlo:
from machine import I2C, Pin, Signal
i2c = I2C(0, scl = Pin(26), sda = Pin(0))
zariadenia = i2c.scan()
print(i2c, zariadenia)
if 0x23 in zariadenia:
import bh1750fvi
from time import sleep
tlačidlo = Signal(37, Pin.IN, invert = True)
while not tlačidlo():
try:
svetlo = bh1750fvi.sample(i2c)
except:
print("Nastala chyba pri meraní! ")
sleep(1)
else:
print("intenzita svetla:", svetlo, end = " lx \r")
else:
print("Nie je pripojený správny senzor!")
Automatické svetlo
Druhým ukážkovým programom je implementácia automatického svetla, ktoré sa rozsvieti vždy, keď sa zotmie:
from machine import I2C, Pin, Signal
from M5Stick import pmu, lcd
from time import sleep
def Svetlo(stav):
global lcd, pmu
lcd.sleep_mode(not stav)
if stav: pmu.lcd_on()
else: pmu.lcd_off()
return stav
lcd.fill(65535) # biela farba
svieti = Svetlo(False)
i2c = I2C(0, scl = Pin(26), sda = Pin(0))
zariadenia = i2c.scan()
print(i2c, zariadenia)
if 0x23 in zariadenia:
import bh1750fvi
tlačidlo = Signal(37, Pin.IN, invert = True)
while not tlačidlo():
try:
intenzita = bh1750fvi.sample(i2c)
except:
print("Nastala chyba pri meraní! ")
sleep(1)
else:
print("intenzita svetla:", intenzita, end = " lx \r")
if not svieti and intenzita < 40:
svieti = Svetlo(True)
elif svieti and intenzita > 60:
svieti = Svetlo(False)
else:
print("Nie je pripojený správny senzor!")
Svetlo(False)
Všimnite si v programe zopár dôležitých bodov:
- najskôr zisťujeme, či je senzor pripojený, až potom začneme merať;
- meranie je obalené v try-except, aby v prípade poruchy senzoru program neskončil s chybou;
- v slučke zdanlivo nie je žiadna pauza, no v skutočnosti je - každé meranie trvá 180 ms a ak nastane chyba, čaká sa sekundu;
- stav svetla prepíname len vtedy, keď sa zmenil (teda nezapíname už zapnuté svetlo a nevypíname vypnuté);
- výpis intenzity svetla je stále v jednom riadku - používa sa znak
"\r", ktorý vráti kurzor na začiatok riadku.
Hysterézna slučka
Dôležité je tiež ošetrenie hysteréznej slučky: svetlo zapíname pri intenzite svetla pod 40 lx a vypíname nad 60 lx. Pri intenzite od 40 do 60 lx nechávame pôvodný stav.
Prečo nemôžeme použiť jednoduchú podmienku, napríklad či je svetlo nad alebo pod 50 lx?
Povedzme, že sa zotmelo na 49 lx. Svetlo sa zapne, čím osvetlí svoje okolie a senzor zachytí napríklad 60 lx. Keďže je to nad 50, tak svetlo vypne. Po vypnutí svetla sa zotmie zase na 49 lx, takže zapneme svetlo… A sme v (nekonečnej) slučke! Svetlo by blikalo v približne 200 ms intervaloch.
