Měření světla s Arduinem: senzor VEML7700

Senzorů pro Arduino existuje spousta. Některé měří teplotu, jiné vlhkost, tlak, proud, napětí nebo třeba vzdálenost. Tentokrát se podíváme na senzor VEML7700, který slouží k měření intenzity okolního světla.

Na první pohled je to malý a nenápadný modul, ale pro různé pokusy je docela zajímavý. Na rozdíl od obyčejného fotorezistoru nevrací jen neurčitou hodnotu typu „víc světla / míň světla“, ale umí pracovat přímo s hodnotou v luxech. Díky tomu se dají naměřené hodnoty mnohem lépe porovnávat.

V článku si ukážeme, co VEML7700 vlastně měří, jak ho připojit k Arduinu, jak nainstalovat knihovnu a jak z něj dostat první hodnoty. Přidám i několik jednoduchých praktických příkladů, které se dají snadno upravit pro vlastní projekty.

senzor VEML7700

Co je VEML7700

VEML7700 je digitální senzor okolního světla. Komunikuje přes sběrnici I2C, takže k Arduinu stačí připojit napájení a dvě datové linky: SDA a SCL.

Uvnitř senzoru je fotodioda, zesilovač a převodník, který převede naměřené světlo na digitální hodnotu. Díky tomu s ním Arduino nemusí měřit analogové napětí jako u fotorezistoru, ale jednoduše si přes I2C vyžádá hotovou hodnotu.

Senzor umí měřit velmi slabé světlo i silné denní osvětlení. V praxi se tedy hodí například pro:

  • měření osvětlení v místnosti,
  • automatické rozsvícení při setmění,
  • regulaci jasu displeje,
  • jednoduchou meteostanici,
  • sledování dne a noci u venkovního zařízení,
  • porovnání světelných podmínek při solárních pokusech,
  • různé Arduino experimenty pro začátečníky.

Pro úplně první pokusy je příjemné hlavně to, že knihovna pro Arduino umí rovnou vracet hodnotu v luxech. Člověk tedy hned vidí číslo, které má nějaký reálný význam.

Co jsou luxy

Hodnota v luxech říká, jak silně je osvětlená určitá plocha. Pro snadné pochopení si to můžeme představit jednoduše: čím víc luxů, tím víc světla dopadá na senzor.

Orientačně:

ProstředíPřibližná hodnota
tma0 lx
velmi slabé noční světlojednotky lx
chodba nebo slabě osvětlená místnostdesítky lx
běžně osvětlený pokojstovky lx
pracovní stůl / dílnastovky až jednotky tisíc lx
venku ve stínutisíce lx
přímé sluncedesítky tisíc lx

Tyto hodnoty berte jen orientačně. Měření hodně ovlivní natočení senzoru, vzdálenost od zdroje světla, stínění, kryt, sklo před senzorem i samotný typ světla. Jinak se bude chovat slunce, jinak LED žárovka a jinak třeba zářivka.

VEML7700 vs. obyčejný fotorezistor

Pro jednoduchou detekci světla se často používá fotorezistor. Ten je levný a jednoduchý, ale má jednu nevýhodu: většinou z něj dostaneme jen analogovou hodnotu, která záleží na zapojení, napájení a konkrétním kusu součástky.

Fotorezistor je dobrý, když chceme jen poznat, jestli je světlo nebo tma. Například pro jednoduché noční světlo úplně stačí.

VEML7700 je už o něco „chytřejší“ řešení. Vrací digitální hodnoty a knihovna nám dokáže rovnou spočítat osvětlení v luxech. To je výhoda, pokud chceme hodnoty ukládat, porovnávat, zobrazovat v grafu nebo podle nich řídit nějaké zařízení.

Zjednodušeně:

VlastnostFotorezistorVEML7700
zapojeníanalogový vstup + odporI2C
výstupneurčitá analogová hodnotadigitální hodnota
luxynutná kalibraceknihovna je umí spočítat
přesnostspíš orientačnílepší pro porovnávání
použitísvětlo/tmaměření a logování světla

Zapojení k Arduinu

Já budu v ukázkách používat Arduino MEGA 2560, ale postup je stejný i pro klasické Arduino UNO nebo kompatibilní desky. Liší se hlavně piny sběrnice I2C.

Pro Arduino UNO je zapojení následující:

VEML7700Arduino UNOArduino MEGA 2560
VIN5V5V
GNDGNDGND
SDAA420
SCLA521

U novějších desek Arduino UNO bývají piny SDA a SCL vyvedené i samostatně vedle AREF. Elektricky jsou ale stále propojené s A4 a A5.

Pokud používáte jinou desku, například ESP8266, ESP32, Arduino Nano RP2040 nebo Raspberry Pi Pico, je potřeba si ověřit, kde má konkrétní deska I2C piny.

Pin 3Vo není potřeba zapojovat. Jde o vyvedený výstup ze stabilizátoru 3,3 V přímo na modulu. V případě potřeby z něj lze napájet další drobnou elektroniku, ale je nutné počítat s maximálním zatížením přibližně 100 mA.

testovací zapojení

Pozor na napájení

U hotového modulu od Adafruit je na desce regulátor napětí a převodník logických úrovní. Díky tomu je možné modul připojit jak k 3,3V deskám, tak ke klasickému 5V Arduinu.

Pokud ale používáte jiný levný modul, je dobré zkontrolovat, co přesně na něm je. Samotný čip VEML7700 je nízkonapěťový, takže u holého čipu nebo jednoduššího modulu bez převodníků by připojení přímo na 5V nemuselo být bezpečné.

Instalace knihovny v Arduino IDE

Nejjednodušší je použít hotovou knihovnu od Adafruit.

V Arduino IDE otevřeme Manažéra knihoven a do vyhledávání zadáme:

Adafruit VEML7700

Knihovnu nainstalujeme. Arduino IDE si může říct ještě o instalaci dalších závislostí, například:

  • Adafruit BusIO
  • Adafruit GFX Library
  • Adafruit SSD1306

V mém případě se tyto knihovny nabídly automaticky při instalaci. Pokud se objeví možnost Instalovat vše, stačí ji potvrdit.

První test: výpis hodnoty v luxech

Začneme co nejjednodušším programem. Ten pouze najde senzor a každou sekundu vypíše hodnotu osvětlení v luxech na sériový monitor.

#include <Wire.h>
#include "Adafruit_VEML7700.h"

Adafruit_VEML7700 veml = Adafruit_VEML7700();

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

  if (!veml.begin()) {
    Serial.println("Senzor VEML7700 nebyl nalezen!");
    while (1);
  }

  Serial.println("Senzor VEML7700 nalezen.");
}

void loop() {
  float lux = veml.readLux();

  Serial.print("Osvetleni: ");
  Serial.print(lux);
  Serial.println(" lx");

  delay(1000);
}

Po nahrání programu otevřeme sériový monitor a nastavíme rychlost 9600 baud.

Teď stačí zkusit senzor zakrýt rukou, posvítit na něj mobilem nebo ho natočit směrem k oknu. Hodnoty by se měly měnit podle množství světla.

Co dělat, když senzor nefunguje

Pokud se v sériovém monitoru objeví hláška:

Senzor VEML7700 nebyl nalezen!

je potřeba zkontrolovat hlavně:

  • jestli je připojené napájení,
  • jestli je propojená zem GND,
  • jestli nejsou prohozené piny SDA a SCL,
  • jestli jsou použité správné I2C piny pro danou desku,
  • jestli je knihovna správně nainstalovaná,
  • jestli modul opravdu obsahuje VEML7700.

U Arduina UNO platí SDA = A4 a SCL = A5. U jiných desek to může být jinak.

Výpis více hodnot: lux, ALS a white

Kromě hodnoty v luxech umí knihovna přečíst i další údaje. Pro běžné použití bude většinou stačit readLux(), ale je dobré vědět, že existují i surovější hodnoty.

  • readLux() vrací vypočítané osvětlení v luxech.
  • readALS() vrací surovou hodnotu měření okolního světla.
  • readWhite() vrací hodnotu z bílého kanálu.

Pro začátečníka je nejzajímavější hlavně hodnota v luxech. Ostatní hodnoty se hodí spíš při pokročilejším nastavování, porovnávání nebo ladění.

#include <Wire.h>
#include "Adafruit_VEML7700.h"

Adafruit_VEML7700 veml = Adafruit_VEML7700();

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

  if (!veml.begin()) {
    Serial.println("Senzor VEML7700 nebyl nalezen!");
    while (1);
  }

  Serial.println("Senzor VEML7700 nalezen.");
}

void loop() {
  Serial.print("ALS: ");
  Serial.print(veml.readALS());

  Serial.print(" | White: ");
  Serial.print(veml.readWhite());

  Serial.print(" | Lux: ");
  Serial.print(veml.readLux());
  Serial.println(" lx");

  delay(1000);
}

Praktický příklad 1: automatické rozsvícení LED při setmění

První praktický příklad bude jednoduché automatické světlo. Když hodnota osvětlení klesne pod nastavenou hranici, Arduino rozsvítí LED.

Pro jednoduchost použijeme vestavěnou LED na pinu D13.

#include <Wire.h>
#include "Adafruit_VEML7700.h"

Adafruit_VEML7700 veml = Adafruit_VEML7700();

const int ledPin = LED_BUILTIN;
const float hraniceTmy = 30.0; // lx

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);

  if (!veml.begin()) {
    Serial.println("Senzor VEML7700 nebyl nalezen!");
    while (1);
  }
}

void loop() {
  float lux = veml.readLux();

  Serial.print("Lux: ");
  Serial.println(lux);

  if (lux < hraniceTmy) {
    digitalWrite(ledPin, HIGH);
  } else {
    digitalWrite(ledPin, LOW);
  }

  delay(500);
}

Hodnota 30 lx je jen ukázková. V reálném použití si ji každý musí upravit podle svého prostředí. V místnosti může být vhodná jiná hranice než venku nebo v krabičce za průhledným krytem.

Praktický příklad 2: automatické světlo s hysterezí

Předchozí ukázka funguje, ale v praxi může mít jeden problém. Pokud se hodnota pohybuje těsně kolem nastavené hranice, LED může rychle blikat nebo se často přepínat.

Lepší je použít dvě hranice:

  • pod nižší hranicí se světlo zapne,
  • nad vyšší hranicí se světlo vypne.

Tomu se říká hystereze. Není to nic složitého, jen tím vytvoříme malou mezeru mezi zapnutím a vypnutím.

#include <Wire.h>
#include "Adafruit_VEML7700.h"

Adafruit_VEML7700 veml = Adafruit_VEML7700();

const int ledPin = LED_BUILTIN;

const float zapnoutPod = 25.0;  // lx
const float vypnoutNad = 45.0;  // lx

bool svetloZapnute = false;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);

  if (!veml.begin()) {
    Serial.println("Senzor VEML7700 nebyl nalezen!");
    while (1);
  }
}

void loop() {
  float lux = veml.readLux();

  if (lux < zapnoutPod) {
    svetloZapnute = true;
  }

  if (lux > vypnoutNad) {
    svetloZapnute = false;
  }

  digitalWrite(ledPin, svetloZapnute ? HIGH : LOW);

  Serial.print("Lux: ");
  Serial.print(lux);
  Serial.print(" | Svetlo: ");
  Serial.println(svetloZapnute ? "zapnuto" : "vypnuto");

  delay(500);
}

Tahle verze je pro reálné použití lepší. Stejný princip se používá třeba u termostatů, nabíječek, automatických světel nebo řízení ventilátorů.

Praktický příklad 3: regulace jasu LED podle okolního světla

Další zajímavé použití je regulace jasu. Ve tmě bude LED svítit víc, na světle méně. Podobně funguje třeba automatický jas displeje u telefonu.

LED musí být připojená na pin, který podporuje PWM. U Arduina UNO jsou to například piny 3, 5, 6, 9, 10 a 11. V této ukázce použijeme pin 9.

Vestavěná LED na pinu D13 se pro tento příklad nehodí, protože pin D13 u Arduino UNO nepodporuje PWM regulaci jasu.

LED připojíme přes ochranný rezistor 330 Ω.

#include <Wire.h>
#include "Adafruit_VEML7700.h"

Adafruit_VEML7700 veml = Adafruit_VEML7700();

const int ledPin = 9;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);

  if (!veml.begin()) {
    Serial.println("Senzor VEML7700 nebyl nalezen!");
    while (1);
  }
}

void loop() {
  float lux = veml.readLux();

  // Pro jednoduchý převod si rozsah omezíme.
  // 0 lx = LED naplno, 500 lx = LED zhasnutá.
  float luxOmezeny = constrain(lux, 0, 500);

  int jas = map(luxOmezeny, 0, 500, 255, 0);

  analogWrite(ledPin, jas);

  Serial.print("Lux: ");
  Serial.print(lux);
  Serial.print(" | Jas LED: ");
  Serial.println(jas);

  delay(500);
}

Tady je dobré si pohrát s hodnotou 500. V tmavším pokoji může být lepší menší rozsah, u okna nebo venku bude potřeba větší rozsah.

Praktický příklad 4: jednoduché logování hodnot

VEML7700 se hodí i pro jednoduché sledování světelných podmínek během dne. Hodnoty můžeme vypisovat do sériového monitoru ve formátu, který se dá později uložit do CSV souboru.

Tahle ukázka vypisuje čas od startu Arduina v sekundách a hodnotu osvětlení v luxech. Data jsou oddělená středníkem, takže se dají snadno otevřít třeba v tabulkovém procesoru.

#include <Wire.h>
#include "Adafruit_VEML7700.h"

Adafruit_VEML7700 veml = Adafruit_VEML7700();

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

  if (!veml.begin()) {
    Serial.println("Senzor VEML7700 nebyl nalezen!");
    while (1);
  }

  Serial.println("cas_s;lux");
}

void loop() {
  unsigned long casSekundy = millis() / 1000;
  float lux = veml.readLux();

  Serial.print(casSekundy);
  Serial.print(";");
  Serial.println(lux);

  delay(5000);
}

Takhle se dá jednoduše porovnat, jak se mění světlo během dne, jak moc ubere světlo sklo v okně nebo jaký je rozdíl mezi zataženou oblohou a přímým sluncem.

Příklad grafu

Gain a integration time jednoduše

VEML7700 má dvě důležitá nastavení, která se hodí znát:

  • gain,
  • integration time.

Pro první pokusy je není nutné řešit. Knihovna má výchozí nastavení, které bude pro běžné experimenty fungovat. Ale je dobré vědět, co tyto pojmy znamenají.

Gain

Gain znamená zesílení. Když je světla málo, vyšší zesílení pomůže senzoru lépe měřit malé změny. Když je světla naopak hodně, moc velké zesílení by mohlo způsobit zahlcení měření.

Zjednodušeně:

  • málo světla → vyšší gain,
  • hodně světla → nižší gain.

Integration time

Integration time je doba, po kterou senzor světlo „sbírá“. Delší čas pomůže při slabém světle, protože senzor nasbírá víc signálu. Kratší čas je vhodnější pro silné světlo a rychlejší měření.

Zjednodušeně:

  • slabé světlo → delší integrační čas,
  • silné světlo → kratší integrační čas.

Kdy ladit nastavení

Pro běžné měření v místnosti nebo jednoduché pokusy můžeme nechat výchozí nastavení. Pokud ale budeme měřit venku na přímém slunci, v úplné tmě nebo přes nějaký tmavý kryt, může být potřeba nastavení upravit.

Toto nastavení se zadává v programu v části setup(), ideálně hned po úspěšném nalezení senzoru pomocí veml.begin().

Zjednodušeně to vypadá takto:

if (!veml.begin()) {
  Serial.println("Senzor VEML7700 nebyl nalezen!");
  while (1);
}

// Nastavení citlivosti senzoru
veml.setGain(VEML7700_GAIN_1_8);
veml.setIntegrationTime(VEML7700_IT_100MS);

Nastavení se tedy nedává do loop(), protože ho není potřeba nastavovat pořád dokola. Stačí ho provést jednou při startu programu.

Celý začátek programu pak může vypadat například takto:

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

  if (!veml.begin()) {
    Serial.println("Senzor VEML7700 nebyl nalezen!");
    while (1);
  }

  // Ruční nastavení senzoru
  veml.setGain(VEML7700_GAIN_1_8);
  veml.setIntegrationTime(VEML7700_IT_100MS);

  Serial.println("Senzor VEML7700 je pripraven.");
}

Možnosti gainu v knihovně jsou například:

VEML7700_GAIN_1_8
VEML7700_GAIN_1_4
VEML7700_GAIN_1
VEML7700_GAIN_2

Možnosti integračního času jsou například:

VEML7700_IT_25MS
VEML7700_IT_50MS
VEML7700_IT_100MS
VEML7700_IT_200MS
VEML7700_IT_400MS
VEML7700_IT_800MS

Pro začátek bych doporučil nastavení neměnit a nejdřív si vyzkoušet, jak se senzor chová v běžných podmínkách. Teprve pokud budou hodnoty podezřelé, příliš malé, příliš velké nebo nestabilní, má smysl se pustit do ladění.

Na co si dát při měření pozor

Měření světla vypadá jednoduše, ale v praxi ho ovlivňuje spousta věcí.

Natočení senzoru

Senzor měří světlo, které na něj dopadá. Když ho natočíme přímo ke zdroji světla, naměříme jinou hodnotu než při natočení bokem. U venkovního měření může hrát velkou roli i úhel slunce.

Kryt nebo krabička

Pokud bude senzor za průhledným krytem, plexisklem nebo ve vodotěsné krabičce, bude měření ovlivněné materiálem krytu. Kryt může část světla pohltit nebo rozptýlit.

Sklo v okně

Měření za oknem není stejné jako měření venku. Sklo část světla propouští, část odráží a výsledky tím mohou být nižší.

Typ světelného zdroje

Slunce, LED žárovka, zářivka i displej mají jiné spektrum světla. Senzor se snaží měřit okolní osvětlení, ale různé zdroje světla se mohou chovat trochu jinak.

Přímé slunce

Přímé slunce je velmi silné. Pokud chceme měřit venku, je dobré si ověřit, jestli zvolený rozsah a nastavení senzoru odpovídá tak vysokým hodnotám.

Rychlé změny světla

Pokud se světlo rychle mění, například při blikání LED pásku nebo projíždění stínů, může být vhodné měření průměrovat.

Jednoduché průměrování hodnot

Pokud hodnoty trochu poskakují, dá se použít jednoduchý průměr z několika měření. Program přečte hodnotu několikrát za sebou a vypočítá průměr.

#include <Wire.h>
#include "Adafruit_VEML7700.h"

Adafruit_VEML7700 veml = Adafruit_VEML7700();

float prectiPrumerLux(int pocetMereni) {
  float soucet = 0;

  for (int i = 0; i < pocetMereni; i++) {
    soucet += veml.readLux();
    delay(100);
  }

  return soucet / pocetMereni;
}

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

  if (!veml.begin()) {
    Serial.println("Senzor VEML7700 nebyl nalezen!");
    while (1);
  }
}

void loop() {
  float lux = prectiPrumerLux(5);

  Serial.print("Prumerne osvetleni: ");
  Serial.print(lux);
  Serial.println(" lx");

  delay(1000);
}

Tento příklad není potřeba pro všechno, ale u praktických projektů může pomoct. Třeba když podle hodnoty světla zapínáme LED, relé nebo posíláme data do grafu.

K čemu se může VEML7700 hodit v praxi

VEML7700 se dá použít všude tam, kde potřebujeme zjistit intenzitu okolního osvětlení. Pro jednoduché projekty může nahradit fotorezistor, ale díky digitálnímu výstupu a hodnotě v luxech se hodí i pro trochu pokročilejší měření.

Několik nápadů:

  • automatické noční světlo,
  • regulace jasu displeje,
  • měření osvětlení pracovního místa,
  • kontrola, jestli je v místnosti rozsvíceno,
  • venkovní čidlo dne a noci,
  • doplněk k meteostanici,
  • doplněk k solárnímu monitoringu,
  • jednoduché školní nebo domácí pokusy se světlem,
  • logování světla během dne do grafu.

Zajímavé je také spojení se solárním měřením. Senzor světla sice přímo neřekne výkon solárního panelu, ale může pomoct vysvětlit, proč panel v danou chvíli vyrábí málo nebo hodně. Když se měří výkon panelu a zároveň intenzita světla, dá se lépe porovnávat vliv počasí, mraků nebo natočení panelu.

Závěr

VEML7700 je zajímavý senzor pro první pokusy s měřením světla. Připojení přes I2C je jednoduché, knihovna pro Arduino je dostupná přímo v Manažeru knihoven a první hodnoty se dají zobrazit během pár minut.

Největší výhoda proti obyčejnému fotorezistoru je v tom, že nepracujeme jen s neurčitou analogovou hodnotou, ale můžeme rovnou číst osvětlení v luxech. Díky tomu se hodnoty lépe porovnávají, ukládají a zobrazují v grafech.

Pro začátečníka bych doporučil začít úplně jednoduše: připojit senzor, vypsat hodnotu v luxech na sériový monitor a zkusit měření v různých podmínkách. Teprve potom má smysl řešit pokročilejší nastavení, jako je gain, integrační čas nebo automatické přizpůsobení rozsahu.

Senzor se hodí nejen jako samostatný pokus, ale i jako doplněk k dalším projektům. Může řídit automatické světlo, upravovat jas displeje, zaznamenávat průběh osvětlení během dne nebo doplnit meteostanici či solární monitoring o další zajímavý údaj.

Tento senzor zakoupíte na Laskakit.cz přímý odkaz je ZDE.

Další díly ze začátečnické série o modulech najdete zde:

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *