Der BH1750 ist ein toller Heligkeitssensor, der über den I²C-Bus digital seine Werte ausschreibt.. Es gibt an dem BH1750 eien Addresspin, der (wenn er zum Aufstarten high oder low gelegt wird) die Adresse des Sensors für den I²C vorgibt. Es ist als möglich, zwei BH1750 an einem I²C-Bus zu betreiben. EInen mit High-Pegel auf dem Adresspin und einen mit Low-Pegel auf dem Adress-Pin. Die Adressen sind dann 0x23 und 0x5C.
Desweiteren kann die Genauigkeit der Daten vorgegeben werden. Dies macht dann Sinn, wenn die Abfragegeschwindigkeit hoch sein soll (hohe Abfrageraten bei kleinerer Genauigkeit und umgekehrt). Wolle hat dazu einen schönen Artikel geschrieben.
Wer aber mehr als zwei Sensoren betreiben möchte, und nicht mehrere I²C-Bussysteme aufbauen möchte, muss sich etwas einfallen lassen.
Mein erster Versuch scheiterte, als ich versucht habe mit einem 8-Bit Schieberegister (IC sn74hc595n) den Adresspin jeweils HIGH zu setzen, und dann die Abfrage zu starten. Das geht nicht, da der Adresspin des BH1750 zum Start des Moduls sein Niveau haben muss und nicht unter Spannung wechseln kann. Aber grundsätzlich machen Schieberegister schon Spaß am Arduino 😉 – Hier ein schönes Video dazu:
Zurück zum eigentlichen Problem und dessen Lösung.
Grundsätzlich war nämlich die Abfrage nacheinander schon eine gute Idee, aber eben nicht mit dem Umschalten der Adresspins, sondern mit der Datenleitung! Die SDA des I²C immer auf den auszulesenden BH1750 zu legen funktioniert nämlich tadellos. Dann kann jeder Chip immer die Adresse behalten und wird nacheinander abgefragt. Klatt gut mit einem Multiplexer!
Ich habe es mit einem „sn74hc4051n“ aufgebaut und es läuft. Geholfen hat mit dabei dieses Video:
Der Autor „Mark Ahn“ beschreibt in seinem Blog „/blog.naver.com/ysahn2k/“ diese Methode… Leider behersche ich die Schriftzeichen nicht 😉
Daher hier meine Zusammenfassung mit einigen Tipps!
Der Aufbau:
Ich beschreibe hier erst einmal den Grundlegenden Aufbau. Später gehe ich auf ein paar Extras ein.
Wie gesagt verwende ich
– einen Multiplexer „sn74hc4051n„
– eine ESP 8266 NodeMCU – (Ich beschreibe auch die Differenzen zwischen Arduino Nano und NodeMCU)
– ein 2×16 LCD-Display
– und später einen Portextender PCF8574 (Siehe hier)
Mark Ahn beschreibt die Nutzung eine OLED-Dispays… Das tut aber nichts zur Sache.. Hier geht es ja um die Sensoren.

Grundsätzlich brauchen wir für die 8-Bit-Adressierung des Multiplexers drei GPIOs. Wie oben zu sehen werden zum Beispiel die GPIO D5, D6 und D/ auf die Eingänge A, B und C des Multiplexers zur Addressierung gelegt.
Den SDA aus aus dem Arduino (bei einem ESP8266 NODEMCU V3 sind die SDA und SCL die Pins D2 und D1!) legen wir auf den IO-Null-Port des Multiplexers. Wir wollen ja den Datenstrom vom BH1750 und vom Arduino durch den Multiplexer an den richtigen Sensor senden.
Die IO-1 bis IO-8-Ports können wir dann mit den SDA der Sensoren verbinden. SCL als Clocksignal geben wir direkt und immer auf die Sensoren und (wer mag) auf ein Display. Das Display kann dann auch direkt mit dem SDA verbuden werden. Ich habe zusätzlich (oben nicht im Schema enthalten, aber im Netz gut dokumentiert, – z.B. hier) zwei Pull-Up-Wiederstände auf den I²C-Bus gelegt. Also immer 3,3V über je einen 10K-Ohm-Wiederstand auf die SDA und einen auf die SCL gelegt. Das erhöht die Zuverlässigkeit, wenn man etwas Leitungslänge braucht.
Alle Adresspins legen wir auf Masse – So haben alle Sensoren als Adresse die 0x23. Jetzt noch Spannungsversorgung an die Sensoren und den Multiplexer. Bei dem Arduino Nano kein Ding, Aber Obacht! Die BH1750 vertragen sowohl 3,3V, als auch 5V… Die GPIOS des ESP8266NodeMCU-V3 mögen keine 5V! Entweder arbeitet Ihr mit den 3,3V aus dem Bord, oder ihr müsst Pegelwandler einsetzen. Ich habe mit 3,3V gute Erfahrungen gemacht.
Am Ende sollte es dann ungefähr so aussehen:

SOFTWARE:
Wie oben schon mehrfach angerissen. Es gibt unterschiede zwischen Arduinos und ESP NodeMCUs. Nachfolgendes Script ist für ein Arduino!
// Aufbau:
//
// VCC -> 3V3 or 5V
// GND -> GND
// SCL -> SCL (A5 auf Arduino Uno, auf esp8266 D1)
// SDA -> SDA (A4 auf Arduino Uno, auf esp8266 D2)
//
// ADD pin der Sensoren auf GND, damit die Adressen aller Sensoren immer auf 0x23 bleiben
include <Wire.h> // für die generelle Kommunikation der Pins
include <BH1750.h> //Für BH1750-Sensor
// Messmethoden!!! Nachfolgend bitte die Messmethode festlegen - Es geht hauptsächlich um die Geschwindigkeit des Rohdatens.
// Wert 0x10 ergibt Messung mit 1Lux-Genauigkeit - ermöglicht Messung in 120ms
// Wert 0x11 ergibt Messung mit 0,5Lux-Genauigkeit - ermöglicht Messung in 120ms
// Wert 0x13 ergibt Messung mit 4Lux-Genauigkeit - ermöglicht Messung in 16ms
// Wert 0x20 ergibt Messung mit 1Lux-Genauigkeit - ermöglicht Messung in 120ms
// Wert 0x21 ergibt Messung mit 1Lux-Genauigkeit - ermöglicht Messung in 120ms
// Wert 0x23 ergibt Messung mit 4Lux-Genauigkeit - ermöglicht Messung in 16ms
define RES_MODE 0x10 // Messung mit 1Lux-Genauigkeit - ermöglicht Messung in 120ms
// I2C Addresse
define BH1750Adresse 0x23 // Sensoren auf GND
// LED auf dem Bord festlegen - Status-LED
define LED_PIN 13
// Definition der Multiplexerports !!! ACHTUNG !!! BEI ESP8266NODEMCUS müssen hier die Pins mit einem D beschrieben Werden - Also D5, D6, D7 usw.!!
int16_t s_en = 4; // Der Enable-Port
int16_t s0 = 5; // Der Adressieungspin A am Multiplexer
int16_t s1 = 6; // Der Adressieungspin B am Multiplexer
int16_t s2 = 7; // Der Adressieungspin C am Multiplexer
int16_t RawData; //Die Rohdaten aus dem Sensor zurück
int16_t SensorValue[4]; //Anzahl der Sensoren am Multiplexer - Maximal 8! Bei einem Multiplexer - Gern Mehr mit mehreren
boolean blinkState = false;
void setup() {
Wire.begin();
Serial.begin(115200); // Baud Rate
pinMode(s_en, OUTPUT); //Initialisieren der Pins als Ausgänge für den Enable-Switch
pinMode(s0, OUTPUT); //Initialisieren der Pins als Ausgänge für den Adresseingang A
pinMode(s1, OUTPUT); //Initialisieren der Pins als Ausgänge für den Adresseingang B
pinMode(s2, OUTPUT); //Initialisieren der Pins als Ausgänge für den Adresseingang C
digitalWrite(s_en, HIGH); //Auf High legen für die Initialisierung (nicht zwingend erforderlich
digitalWrite(s0, HIGH);
digitalWrite(s1, HIGH);
digitalWrite(s2, HIGH);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, HIGH);
}
void loop() {
digitalWrite(s_en, LOW); // Einschalten des Multiplexers / Durchschalten der Daten
for(int i = 0; i < 4; i++){ //Anzahl der Sensoren eintragen - Hier sind 4 eingetragen
Auslesen(i); // Untenstehende Funktion "Auslesen" aufrufen und Daten zurückbekommen
init_BH1750(BH1750Adresse, RES_MODE); // Daten in gewünschter Auflösung abrufen delay(120); RawData_BH1750(BH1750Adresse); SensorValue[i] = RawData / 1.2; // Schreiben der Daten in die vier Variablen delay(20);
}
Serial.print("Sensor_1 = "); Serial.print(SensorValue[0]); //Log-Schreiben für die Sensoren
Serial.print(" | Sensor_2 = "); Serial.print(SensorValue[1]);
Serial.print(" | Sensor_3 = "); Serial.print(SensorValue[2]);
Serial.print(" | Sensor_4 = "); Serial.println(SensorValue[3]);
blinkState = !blinkState;
digitalWrite(LED_PIN, blinkState);
} //Ende des Loops
// Initialisieren der Sensoren
void init_BH1750(int ADDRESS, int MODE){
//BH1750 Initializing & Reset
Wire.beginTransmission(ADDRESS);
Wire.write(MODE); // PWR_MGMT_1 register
Wire.endTransmission(true);
}
// Abruf
void RawData_BH1750(int ADDRESS){
Wire.beginTransmission(ADDRESS);
Wire.requestFrom(ADDRESS,2,true); // Abruf der zwei Registereinträge
RawData = Wire.read() << 8 | Wire.read(); // Lesen der Rohdaten des BH1750
Wire.endTransmission(true);
}
// Setzen der Adressen am Multiplexer. Als Schleife durch die acht Möglichkeiten. Je nach Anzahl der Sensoren.
int Auslesen(int channel) {
int controlPin[] = {s0, s1, s2};
int muxChannel[8][3] = {
{0,0,0}, //channel 0
{1,0,0}, //channel 1
{0,1,0}, //channel 2
{1,1,0}, //channel 3
{0,0,1}, //channel 4
{1,0,1}, //channel 5
{0,1,1}, //channel 6
{1,1,1}, //channel 7 //Schleife durch die Signale
};
for(int i = 0; i < 3; i++){ // Setzen der drei GPIOs für die Adressierung des Multiplexers
digitalWrite(controlPin[i], muxChannel[channel][i]);
}
}
Bitte nicht vergessen, die Bibliotheken vorher zu laden und das passende Board einzustellen;)
Der Nächste Schritt ist das Einbinden des WLAN und des Displays… das folgt in den kommenden Tagen! Viel Spaß beim Basteln
Hallo,
I2C ist eigentlich nicht für längere Strecken ausgelegt. Mit je einem P82B96 kann man aber doch bis zu 100 m erreichen (getestet im Prüflabor!). Wenn dann noch I2C-Multiplexer genutzt werden, wird der Aufbau doch schnell größer und könnte den Anforderungen genügen.
Sory, der Post ist mir untergegangen :$ … Danke für den Tipp