Es gibt verschiedene Möglichkeiten Lichtintensität zu erfassen. Den klassischen Weg der analogen Messung (Lichtwiderstand, Photodiode) habe ich von vornherein ausgeschlossen. Vor allem wegen der erforderlichen Kalibrierung. Zum Glück habe ich leicht einen digitalen (Kommunikation erfolgt über I2C Bus) Sensor finden können: BH1750FVI. Dieser kann Lichtintensität im Bereich von 1 bis 65535 lx (Lux) erfassen. Das ist schon ganz gut. Die Spezifikation besagt, dass der Sensor auch zur Erfassung von Werten von 0,11 bis max. 100000 lx umprogrammiert werden kann. Das ist sehr beeindruckend.

Ein paar Werte zum Vergleich (Wikipedia):

5 mW Laserpointer, grün (532 nm), 3 mm Strahldurchmesser  427.000 lx
5 mW Laserpointer, rot (635 nm), 3 mm Strahldurchmesser 105.000 lx
Heller Sonnentag 100.000 lx
Bedeckter Sommertag 20.000 lx
Im Schatten im Sommer 10.000 lx
Operationssaal 10.000 lx
Bedeckter Wintertag 3.500 lx
Fußballstadion 1.400 lx
Beleuchtung TV-Studio 1.000 lx
Büro-/Zimmerbeleuchtung 500 lx
Flurbeleuchtung 100 lx
Wohnzimmer 50 lx
Straßenbeleuchtung 10 lx
Kerze ca. 1 Meter entfernt 1 lx
Vollmondnacht 0,25 lx
Sternklarer Nachthimmel (Neumond) 0,001 lx
Bewölkter Nachthimmel ohne Mond und Fremdlichter 0,00013 lx

 

Natürlich ist die Empfindlichkeit und der Umfang in keinester Weise mit denen des menschlichen Auges vergleichbar. Dennoch ist 0,11 lx schon sehr dunkel und 100000 lx verdammt hell. Damit kann ich die Dämmerung, die Dunkelheit und die gleißende Sonne zuverlässig erkennen. Auch die Verleichbarkei zwischen mehreren Sensore ist gegeben. Es geht mir vor allem um die subjektive Wahrnemung, die Genauigkeit der Lux-Werte ist mir dagegen weniger wichtig.

 

Der nachte SMD-Chip ist viel zu unhandlich um seiner reiner Form verwendet zu werden. Glücklicherweise sind mehrere Breakout-Boards günstig verfügbar. Ich habe mir zwei davon angesehen.

Die erste Version ist sehr sinple aufgebaut. Ein 3,3V-Spannungsregler und PullUp-Widerstände. Dennoch kann dadurch dieses board gleich an ein Arduino angeschlossen werden. Solange sie allein an I2C Bus hängt, wird das ganz gut funktionieren. Bei mehreren Geräten muss man (wie immer) auf die verwendete Spannung und die Gesamtwerte der PullUps Acht geben.

 

 

 

 

Die Variante 2 ist etwas besser für die Verwendung mit 5V geeignet. Ein 3,3v-Regler ist wieder dabei. Die SDA-Leitung hat sogar einen einfachen Level-Shifter bekommen (MOSFET). Die SCL muss sich alledings mit einem PullUp (und einer Diode) begnügen.

 

 

 

Die Suche nach Code-Beispielen verlief eher enttäuschend. Das meiste, was zu finden war, waren einfache Direktezugriffe über I2C Bus. Ich wollte schon eine fertige Bibliothek. Und nach Möglichkeit nicht so 'low level'. Ich konnte nur eine Arduino Bibliothek für BH1750 finden: https://github.com/claws/BH1750. Sie war jedoch auch eine Enttäuschung. Die Werte im höchstaufgelösten Modus waren falchs berechnet (interessanterweise war ein fix bereits in einem Bransh vorhanden, ging aber bei Merge verloren). Es war auch keine Möglichkeit vorhanden, dem Sensor Werte außerhalb von 1 - 65535 zu entlocken.

Also habe ich Datasheet gelesen und beschlossen, eine eigene Bibliothek zu entwickeln. Rausgekommen ist etwas mit folgenden Eigenschaften:

  • Unterstützung beider möglichen I2C-Adressen des Sensors: Standardadresse: 0x23, Alternativadresse: 0x5C. Es sind entsprechende Konstanten definiert: BH1750_DEFAULT_I2CADDR und BH1750_SECOND_I2CADDR.

  • Alle Hardware-Auflösungsmodi:

    • RESOLUTION_LOW: Physische Sensormodus mit 4 lx Auflösung. Messzeit ca. 16ms. Bereich 0-54612.
    • RESOLUTION_NORMAL: Physische Sensormodus mit 1 lx Auflösung. Messzeit ca. 120ms. Bereich 0-54612.
    • RESOLUTION_HIGH: Physische Sensormodus mit 0,5 lx Auflösung. Messzeit ca. 120ms. Bereich 0-54612.
  • Virtueller Modus:

    • RESOLUTION_AUTO_HIGH: Die Werte im MTreg ('Measurement Time'-Register) werden je nach Helligkeit automatisch so angepasst, dass eine maximalmögliche Auflösung und Messbereich erziehlt werden. Die messbaren Werte fangen von 0,11 lx und gehen bis über 100000 lx. (ich weis nicht, wie genau die Werte in Grenzbereichen sind, besonders bei hohen Werte habe ich da meine Zweifel. Die Werte scheinen jedoch weitgehend linear mit der steigenden Helligkeit zu wachsen.) Auflösung im Unteren Bereich ca. 0,13 lx, im mittleren 0,5 lx, im oberen etwa 1-2 lx. Die Messzeiten verlängern sich durch mehrfache Messungen und die Änderungen von Measurement Time (MTreg) bis max. ca. 500 ms.
  • Methode zur Änderung von 'Measurement Time'-Registers. Damit kann die Empfindlichkeit beeinflusst werden.

  • 'auto power down': Der Sensor wird nach der Messung in den Stromsparmodus versetzt. Das spätere Aufwecken wird ggf. automatisch vorgenommen, braucht jedoch geringfügig mehr Zeit.


Ich habe die Bibliotrhek unter LGPL veröffentlicht und hoffe, dass es jemandem nützlich sein wird ;-)
Das fertige Ergebniss ist bei GitHub zu finden: https://github.com/hexenmeister/AS_BH1750.
Die Verwendung ist recht einfach, folgendes Demo soll es verdeutlichen.

#include <Wire.h>
#include <AS_BH1750.h>
#include <LiquidCrystal.h>

/*
* LightMeter_LCD
*
* Version 1.2
* Datum: 05.08.2013
*
* Das Programm benutzt den BH1750 (Umgebiungslichtsensor)
* und zeigt die Werte in Lux auf einem 16x2-Symbol-LCD.
*
* Verdrahtung (UNO, Nano...)
*
* BH1750:
* Sensor SCL pin an A5
* Sensor SDA pin an A4
* Sensor VDD pin an 5V
* Sensor GND pin an GND
* Sensor ADDR pin frei
*
* LCD in 4-Bit-Modus:
* LCD RS pin an digital pin 8
* LCD RW pin an digital pin 13
* LCD Enable pin an digital pin 9
* LCD D4 pin an digital pin 4
* LCD D5 pin an digital pin 5
* LCD D6 pin an digital pin 6
* LCD D7 pin an digital pin 7
*
*
* Copyright (c) 2013 Alexander Schulz. All right reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

AS_BH1750 lightMeter;

// Setup LCD-Shield
LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);

void setup() {
  // Display initialisieren
  lcd.clear();
  lcd.begin(16, 2); // 16x2 Zeichen
  lcd.setCursor(0,0);
  lcd.print("LightMeter v1.0");
  lcd.setCursor(0,1);
  lcd.print("Initializing...");
  delay(1000);
  lcd.clear();

  if(!lightMeter.begin()){
    // Prüfen, ob Sensor vorhanden ist
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("BH1750 not found");
    lcd.setCursor(0,1);
    lcd.print("check wiring!");
    while (1) {
      delay(1000);
    }
  }

}

void loop() {
  char clux[9];

  // Werte auslesen und aufbereiten
  float lux = lightMeter.readLightLevel();
  dtostrf(lux, 8, 1, clux);

  lcd.setCursor(0,0);
  lcd.print("Light level: ");
  lcd.setCursor(5,1);
  lcd.print(clux);
  lcd.print(" lx");

  delay(500);
}

 

Technische Informationen:

Description: http://www.rohm.com/web/global/products/-/product/BH1750FVI
Datasheet: http://rohmfs.rohm.com/en/products/databook/datasheet/ic/sensor/light/bh1750fvi-e.pdf

 

Kommentare (8)

Cancel or

  • Alexander Schulz
    @branther
    Inwiefern? Ist das Problem eher in der Messung begründet, oder in der Formel? Ist es möglich mit dem Parameter CL (255) eine zielführende Anpassung vorzunehmen?
    Leider kenne ich mich mit der Analogen-Fotographie und der dazugehörigen Lichtmessung nicht aus.

    Grüße,

    Alexander
  • branther
    @Alexander Schulz
    ja, ich weis, da gibt's wohl auch eine Formel, mit der ich leider keine gescheiten Ergebnisse bekomme oder ich mach was falsch.
    t=255*pow(Blende, 2)/lux*pow(10,(-DIN/10));
    aus dieser Website--> http://www.filmtechnik-online.de/filmtechnik/lux.htm
    grüße
  • Alexander Schulz
    @branther
    Hallo!

    So eine Lib ist mir leider nicht bekannt. Wenn Du die Formeln zum Umrechnen von Lux-Werten in die gewünschte Daten kennst, kannst ja so etwas bestimmt auch selbst erstellen.
    Viele Erfolg!

    Grüße,

    Alexander
  • branther
    Super, Danke fuer die lib.
    ich wuerde das teil sehr gerne als belichtungsmesser zum fotografieren einsetzen. Wie muss ich da vorgehen?
    gibt es eine lib die gleich belichtungszeiten und blendenwerte bei bestimmter iso ausspuckt? Das waer echt mal spitze.
    beste gruesse
    branther
  • Alexander Schulz
    @Ronny
    Hallo,

    die Konstanten sind in der Datei AS_BH1750.h definiert.
    Die erste Adresse ist Default. Um die zweite zu verwenden, muss in Construktor die andere Konstante angegeben werden:
    AS_BH1750 lightMeter(BH1750_SECOND_I2CADDR);
    statt AS_BH1750 lightMeter;
    Außerdem muss der Addr-Pin an VCC angeschlossen werden.

    Grüße,

    Alexander
  • Ronny
    Hallo, danke für die modifizierte Library. Wie funktioniert das mit den 2 Adressen von 2 BH1750? Wo wird BH1750_DEFAULT_I2CADDR und BH1750_SECOND_I2CADDR definiert so dass Sensor 1 und Sensor 2 als Varible im Sketch verwendet werden kann.
    Gruß
  • Super User
    @PI User
    Ich habe leider keinen PI hier und kenne mich damit nicht aus, aber der Unterschied dürfte recht gering sein. Es müssen wohl lediglich andere Libs für die Zugriffe auf I2C Bus (hier: Wire.h) und für die delay-Funktion (Arduino.h) verwendet werden. Beides sollte kein Problem darstellen.
    Auch eine Übersetzung in eine Andere Sprache wäre nicht besonders schwierig.
    Wenn Sie die Portierung versuchen wollen, kann gerne zu helfen versuchen.

    Grüße,
    Alex

    P.S. hübsche Auswertungen ;-)
  • PI User

    Wie macht man das (code) mit einen Raspberry PI ?

    Grusse....

    pi.gids.nl