Image

Quelle: Adafruit

TSL2561

Der TSL2561 ist ein digitaler Lichtsensor mit folgenden Eigenschaften:

  • Hohe Präzision
  • Temperaturbereich von -30 bis +80 Grad Celsius
  • Dynamischer Meßbereich 0,1 bis 40.000 Lux
  • Spannungsversorgung 2,7 bis 3,6 Volt
  • 2 Fotodioden: 1 x Gesamtspektrum, 1 x Infrarot
  • integrierten ADC-Konverter
  • filtert 50/60-Hz "Flimmern" aus
  • niedriger Stromverbrauch (0,5 mA aktiv, 15 ųA Schlafmodus)
  • I²C-Bus für bis zu 3 Sensoren

Hier ein Funktionsdiagramm:

Image

Das Breakout-Board wird mit einer Steckerleiste 6-fach geliefert. Diese ist nicht montiert.

Belegung:

Breakout-BoardPin ArduinoBemerkung
GNDGND 
ADDR-bestimmt I2C-Adresse, bei einem Sensor unbeschaltet, sonst an GND oder VDD
INT-Interrupt vom Sensor, hier unbeschaltet
SCLA5I2C-Clock
SDAA4I2C-Data
VCC3,3 VoltAchtung

 

Weitere Hinweise

Der TSL2561 darf nicht an einer Spannung über 3,6 Volt betrieben werden, also sind die vom Arduino bereitgestellten 3,3 Volt geeignet. Aber Vorsicht: Wenn weitere Sensoren wie z.B. ein DS1307 mit einer Betriebsspannung von 5 Volt am selben I²C-Bus betrieben werden, gibt es Ärger. Ich zitiere:

You may be wondering, how is it OK to connect a 3.3V chip like the TSL2561 to 5.0V data pins like the Arduino? Isn't that bad? Well, in this specific case its OK. I2c uses pullup lines to the 3.3V power pin, so the data is actually being sent at 3.3V. As long as all the sensors/device on the i2c bus are running on 3.3V power, we're fine. However, don't use a 5.0v powered i2c device (like the DS1307) with pullups at the same time as a 3.3V device like the TSL2561! If you want to use this sensor with a datalogger that uses the DS1307, remove any/all of the pullup resistors from the DS1307 SDA/SCL pins. The pullups built into the TSL2561 will then be active and keep the voltage at 3.3V which is safe for both the RTC and the sensor.

Quelle: Tutorial Adafruit, Seite 2

Software

 

Beispiel I

 

Vorbemerkungen

Das folgende einfache Programm liest die Werte der Infrarot- und der Vollspektrum-Fotodioden aus und gibt diese auf der seriellen Konsole aus. Da der Mensch Infrarotstrahlung nicht sehen kann, wird das für das menschliche Auge sichtbare Lichtspektrum wie folgt ermittelt: Gesamtspektrum - Infrarot. Weiterhin wird die Beleuchtungsstärke in Lux errechnet und angezeigt.

Eine kurze grobe Orientierungshilfe:

Kerzenlicht bei 20 cm10 bis 15 Lux
Straßenlicht10 bis 20 Lux
Normales Raumlicht100 Lux
Büro Leuchtstofflampe300 bis 500 Lux
Halogenlampe750 Lux
Sonnenlicht 1 Stunde vor Aufgang1000 Lux
Tageslicht bewölkt5000 Lux
Tageslicht wolkenlos10,000 Lux
Helles Sonnenlicht20,000 Lux

Quelle: hobbytron.de

Sieht dann ungefähr so aus:

Image

Der Sketch wurde auf einem Uno unter der Arduino-IDE 1.0.4 getestet. Ich habe diese Bibliothek von K. Townsend eingesetzt.

Code I (ein TSL2561)

 

/* Einfaches Beispiel fuer TSL2561 library

   SDA an Pin 4 analog
   SCL an Pin 5 analog
   Achtung: VCC an 3.3 Volt
   ADDR I2C-Addresse:
   an GND (TSL2561_ADDR_LOW (0x29)
   an VCC TSL2561_ADDR_HIGH (0x49) 
   unbeschaltet (addr 0x39)
   
   Beruht auf einem Bespiel von K. Townsend
   modifiziert von fribbe fuer http://macherzin.net
   2012-12-11 Rev. 0.3
   getestet unter IDE 1.04

   Under Public Domain
*/

#include <wire.h>
#include "TSL2561.h"

TSL2561 tsl(TSL2561_ADDR_FLOAT); 

void setup()
{
  delay(1000);  
  Serial.begin(9600);
  
  if (tsl.begin()) // wenn Sensor gefunden ...
  {
    Serial.println("Sensor gefunden");
  }
  else // sonst ...
  {
    Serial.println("Kein Sensor?");
    while (1);
  }

  // Verstaerkung kann dynamisch an Lichtverhaeltnisse angepasst werden
  // tsl.setGain(TSL2561_GAIN_0X); // keine Verstaerkung: bei hoher Helligkeit
  tsl.setGain(TSL2561_GAIN_16X); // 16fache Verstaerkung: bei geringer Helligkeit
  
  // Aenderung des Werts INTEGRATIONTIME veraendert die Messdauer
  // hoehere Werte = langsamer (bei geringem Licht)
  //tsl.setTiming(TSL2561_INTEGRATIONTIME_13MS); // bei großer Helligkeit
  tsl.setTiming(TSL2561_INTEGRATIONTIME_101MS); // bei durchschnittlicher Beleuchtung
  //tsl.setTiming(TSL2561_INTEGRATIONTIME_402MS); // bei geringem Licht
}

void loop()
{
  /* Liesst Infrarot- und Vollsprektrum-Fotodiode,
     ermittelt Anteil des sichtbaren Lichts, also Differenz zwischen beiden
     Dauer 13 bis 402 Millisekunden
  */
  // uint16_t x = tsl.getLuminosity(TSL2561_VISIBLE); // sichtbares Licht    
  //uint16_t x = tsl.getLuminosity(TSL2561_FULLSPECTRUM); // volles Spektrum
  //uint16_t x = tsl.getLuminosity(TSL2561_INFRARED); // Infrarot
  
  //Serial.println(x, DEC);

  // etwas anspruchsvoller, liest 32 bits - 16 Bits IR (Top) und 16 Bits Vollspektrum
  uint32_t lum = tsl.getFullLuminosity();
  uint16_t infrarot, gesamtSpektrum;
  infrarot = lum >> 16;
  gesamtSpektrum = lum  0xFFFF;
  Serial.print("Geamt: "); Serial.print(gesamtSpektrum);
  Serial.print("\t");
  Serial.print("IR: "); Serial.print(infrarot);
  Serial.print("\t\t");
  Serial.print("Sichtbar: "); Serial.print(gesamtSpektrum - infrarot);
  Serial.print("\t");
  Serial.print("Lux: "); Serial.println(tsl.calculateLux(gesamtSpektrum, infrarot));
  
  delay(1000); 
}

// haben fertig

 

Beispiel II

In diesem Beispiel werden zwei digitale Lichtsensoren des Typs TSL2561 benutzt. Der Sketch/Code sollte selbsterklärend sein, deshalb nur einige kurze Bemerkungen:

Die Werte (Gesamtspektrum, sichtbares Licht, Infrarot und Lux) werden formatiert auf der seriellen Konsole angezeigt; zusätzlich noch die Differenz im Infrarot-Bereich zwischen den beiden Sensoren. Warum ausgerechnet Infrarot? Diesen Wert benötige ich noch für ein anderes Projekt.

Die beiden Sensoren sind per I²C-Bus mit einem Arduino verbunden. Der Adress-Pin (ADDR) des ersten Sensors ist nicht belegt (Floating) und wird deshalb über die Adresse 0x39 angesprochen. Der ADDR-Pin des zweiten Sensors ist auf GND gelegt und deshalb über die Adresse 0x29 anzusprechen. Diese Aufgabe übernimmt aber die verwendete Bibliothek/Library).

Noch einmal der Hinweis: VCC = 3,3 Volt!

Hardware (Steckbrett)

Image

Code II (zwei TSL2561)

 

/* 2 digitale Sensoren TSL2561 

   SDA an Pin 4 analog
   SCL an Pin 5 analog
   Achtung: VCC an 3.3 Volt !!!
   ADDR I2C-Addresse:
   unbeschaltet (addr 0x39) = FLOATING = Sensor-1
   an GND (TSL2561_ADDR_LOW (0x29) = LOW = Sensor-2
   an VCC TSL2561_ADDR_HIGH (0x49) = HIGH (nicht genutzt, waere Sensor-3)
   
   Beruht auf einem Beispiel von K. Townsend
   modifiziert von fribbe fuer http://macherzin.net
   2013-03-28 Rev. 0.4
   getestet unter IDE 1.04

   Unter Public Domain
*/

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

TSL2561 tsl1(TSL2561_ADDR_FLOAT); // Pin ADDR nicht belegt (FLOATING)
TSL2561 tsl2(TSL2561_ADDR_LOW); // PIN ADDR an GND (LOW)

int differenzIR = 0; // Variable fuer Differenz IR Sensor-1 und Sensor-2

void setup()
{
  Serial.begin(9600); // starte serielle Kommunikation

  // Verstaerkung kann dynamisch an Lichtverhaeltnisse angepasst werden ...
  // tsl1.setGain(TSL2561_GAIN_0X); // Sensor-1, keine Verstaerkung (hohe Helligkeit)
  // tsl2.setGain(TSL2561_GAIN_0X); // Sensor-2, keine Verstaerkung (hohe Helligkeit)
  tsl1.setGain(TSL2561_GAIN_16X); // Sensor-1, 16-fache Verstaerkung (geringe Helligkeit)
  tsl2.setGain(TSL2561_GAIN_16X); // Sensor-2, 16-fache Verstaerkung (geringe Helligkeit)
  
  // Aenderung von INTEGRATIONTIME veraendert die Messdauer ...
  // hoehere Werte = langsamer (bei schlechten Lichtverhaeltnissen)
  //tsl1.setTiming(TSL2561_INTEGRATIONTIME_13MS); // Sensor-1 (hohe Helligkeit)
  //tsl2.setTiming(TSL2561_INTEGRATIONTIME_13MS); // Sensor-2 (hohe Helligkeit)
  tsl1.setTiming(TSL2561_INTEGRATIONTIME_101MS); // Sensor-1, durchschnittliche Beleuchtung
  tsl2.setTiming(TSL2561_INTEGRATIONTIME_101MS); // Sensor-2, durchschnittliche Beleuchtung
  // tsl1.setTiming(TSL2561_INTEGRATIONTIME_402MS); // Sensor-1 (geringe Helligkeit)
  // tsl2.setTiming(TSL2561_INTEGRATIONTIME_402MS); // Sensor-2 (geringe Helligkeit)
}

void loop()
{
  // lese 32 Bits = 16 Bits IR (High) und 16 Bits Vollspektrum (Low)
  uint32_t lum1 = tsl1.getFullLuminosity(); // lese Daten Sensor-1
  uint32_t lum2 = tsl2.getFullLuminosity(); // lese Daten Sensor-2
  uint16_t infrarot1, gesamtSpektrum1; // Variablen fuer Gesamtsprektrum und Infrarot Sensor-1
  uint16_t infrarot2, gesamtSpektrum2; // Variablen fuer Gesamtsprektrum und Infrarot Sensor-2
  infrarot1 = lum1 ›› 16; // Sensor-1, siehe Artikel
  infrarot2 = lum2 ›› 16; // Sensor-2, siehe Artikel
  gesamtSpektrum1 = lum1 & 0xFFFF; // Sensor-1, siehe Artikel
  gesamtSpektrum2 = lum2 & 0xFFFF; // Sensor-2, siehe Artikel
  // Ausgabe Werte auf serieller Konsole
  Serial.print("Gesamt-1: ");
  Serial.print(gesamtSpektrum1);
  Serial.print("\t");
  Serial.print("IR-1: ");
  Serial.print(infrarot1);
  Serial.print("\t\t");
  Serial.print("Sichtbar-1: ");
  Serial.print(gesamtSpektrum1 - infrarot1);
  Serial.print("\t");
  Serial.print("Lux-1: ");
  Serial.println(tsl1.calculateLux(gesamtSpektrum1, infrarot1));
  Serial.print("Gesamt-2: ");
  Serial.print(gesamtSpektrum2);
  Serial.print("\t");
  Serial.print("IR-2: ");
  Serial.print(infrarot2);
  Serial.print("\t\t");
  Serial.print("Sichtbar-2: ");
  Serial.print(gesamtSpektrum2 - infrarot2);
  Serial.print("\t");
  Serial.print("Lux-2: ");
  Serial.print(tsl2.calculateLux(gesamtSpektrum2, infrarot2));
  Serial.print("\t");
  differenzIR = (infrarot1 - infrarot2);
  Serial.print("Differenz-IR: ");
  Serial.println(differenzIR);
  
  delay(5000); // nur fuer Ausgabe, ansonsten sollten 100 - 500 mS reichen
}

// haben fertig

Datei zum Herunterladen: TSL2561_2fach.ino

Links

 

 

TLS45315

 

Vorbemerkungen

Der TLS45315 von AMS-TAOS ist ein digitaler Lichtsensor zur Messung des Umgebungslichts. Die Helligkeitswerte in Lux werden direkt per I²C übermittelt.

Hier das Datenblatt.

Einige der Eigenschaften:

  • Direkte Ausgabe in Lux
  • ermittelte Werte entsprechen menschlicher Wahrnehmung
  • Korrektur von 50 bzw. 60Hz Einflüssen
  • geringer Strombedarf (110mA typisch), Stromsparmodus 2,2mA typisch
  • großer Dynamikbereich von 3 bis 220k Lux
  • 3 auswählbare "Meßbereiche" (100mS, 200mS und 400mS)
  • I²C-Interface 3,3 - 5V tolerant
  • Eingangsspannung 3,3 bis 5V
  • Onboard 2,5V-Spannungsregler mit 1,8 Logik
  • Onboard Pegelwandler

Für den Normalanwender empfiehlt sich wie so oft der Einsatz eines Break-Out-Boards. Ein solches findet ihr bei Watterott unter TSL45315 Lichtsensor Breakout.

Anbindung Hardware

Anbindung des Moduls an Arduinos per I²C:

ModellArduino SDAArduino SDC
UnoA4A5
Mega2021
Leonardo23
Due2021
Yun23

Dazu GND an GND und VIN an 5 bz. 3,3V.

Software

  Achtung: Aufgrund technischer Probleme werden im folgenden Sketch einige Sonderzeichen nicht korrekt dargestellt. Sorry!

tsl14614_01
/* Kurzes Beispiel fuer TSL45315-Breakout (Digitaler Licht-Sensor)
   Misst Umgebungslicht und gibt Lux ueber I2C an serielle Konsole aus
   beruht auf https://github.com/watterott/TSL45315-Breakout/blob/master/src/TSL45315.ino
   Getestet auf Arduino Leonardo unter IDE 1.5.6r2
   
   2014-04-28 Rev 0.2 leicht modifiziert von fribbe fuer http://macherzin.net

  Arduino I2C/TWI Pins:   SDA SCL 
  Arduino Uno             A4  A5
  Arduino Mega            20  21
  Arduino Leonardo         2   3
  Arduino Due             20  21
  Arduino Yun              2   3 

  GND an GND
  VIN an 5 bzw. 3,3V  
*/

#include <wire.h>

const int I2C_ADDR = 0x29;
const int REG_CONTROL = 0x00;
const int REG_CONFIG = 0x01;
const int REG_DATALOW = 0x04;
const int REG_DATAHIGH = 0x05;
const int REG_ID = 0x0A;

void setup()
{
   Serial.begin(9600);
   while(!Serial); // fuer Leonardo und Co.
   Wire.begin(); // starte Wire

   Serial.print("ID: ");
   
   Wire.beginTransmission(I2C_ADDR); // beginne Uebertragung
   Wire.write(0x80|REG_ID); // starte Autoincrement mit Register 0h
   Wire.endTransmission(); // beende Uebertragung
   Wire.requestFrom(I2C_ADDR, 1); // fordere 1 Byte an
   while(Wire.available()) // wenn Wire bereit ...
   {
     unsigned char c = Wire.read(); // lese Zeichen
     Serial.print(c&0xF0, HEX); // Ausgabe serielle Konsole
   }
   Serial.println("");

   Serial.print("Starte ");
   Wire.beginTransmission(I2C_ADDR); // beginne Uebertragung
   Wire.write(0x80|REG_CONTROL);
   Wire.write(0x03);
   Wire.endTransmission(); // beende Uebertragung

   Serial.println("und konfiguriere ...");
   Wire.beginTransmission(I2C_ADDR);  // beginne Uebertragung
   Wire.write(0x80|REG_CONFIG); // sende Wert
   Wire.write(0x00); // M = 1 T = 400ms
   // Wire.write(0x01); // M = 2 T = 200ms
   // Wire.write(0x02); // M = 4 T = 100ms
   Wire.endTransmission(); // beende Uebertragung
}

void loop()
{
   uint16_t l, h;
   uint32_t lux;

   Wire.beginTransmission(I2C_ADDR);
   Wire.write(0x80|REG_DATALOW);
   Wire.endTransmission();
   Wire.requestFrom(I2C_ADDR, 2); // fordere 2 Bytes an
   l = Wire.read();
   h = Wire.read();
   while(Wire.available())
   {
     Wire.read(); 
   }
   lux = (h‹‹8) | (l‹‹0);
   lux *= 1; // M=1
   // lux *= 2; // M= 2
   // lux *= 4; //M = 4
   Serial.print("Lux: ");
   Serial.println(lux, DEC);
   delay(1000);
}

// haben fertig

Datei zum Herunterladen: tsl45315.ino

Bezugsquelle: Watterott