Skip to Content

APDS-9930 Näherungs- und Lichtsensor mit Arduino

APDS-9930 Näherungs- und Lichtsensor mit Arduino

In diesem Tutorial lernst du, wie du den APDS-9930 Näherungs- und Lichtsensor mit einem Arduino oder einem anderen gängigen Mikrocontroller (ESP32/ESP8266) verwendest.

Der APDS-9930 ist ein sehr kleiner Sensor, der häufig in Smartphones und Tablets zur automatischen Anpassung der Bildschirmhelligkeit und zur Näherungserkennung während Telefonaten eingesetzt wird. Du kannst ihn auch als einfachen Gestensensor nutzen, um zum Beispiel Lichter oder andere Geräte zu aktivieren, wenn du mit der Hand davor winkst.

Benötigte Teile

Für dieses Projekt benötigst du einen APDS-9930 Sensor und einen Mikrocontroller. Ich habe einen Arduino Uno verwendet, aber jeder andere Arduino oder ein ESP32/ESP8266 funktioniert ebenfalls, solange er eine 3,3V Stromversorgung bereitstellt.

APDS-9930 Sensor

Arduino

Arduino Uno

USB Data Sync cable Arduino

USB-Kabel für Arduino UNO

Dupont wire set

Dupont-Kabelset

Half_breadboard56a

Breadboard

Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.

Eigenschaften des APDS-9930 Näherungs- und Lichtsensors

Der APDS-9930 ist ein winziger (3,94 x 2,36 x 1,35mm) Sensor zur Näherungserkennung und digitalen Umgebungslichtmessung. Das Bild unten zeigt die Vorder- und Rückseite des APDS-9930 Chips.

APDS-9930 Chip
APDS-9930 Chip

Der Sensor misst die Nähe eines Objekts, indem er einen IR-Impuls über die integrierte IR-LED aussendet und die Intensität des reflektierten Lichts misst. Umgebungslicht wird von zwei Fotodioden erfasst. Eine Fotodiode erkennt sichtbares Licht plus Infrarot (Ch0), die andere nur Infrarot (Ch1). Ein integrierter Mikroprozessor kombiniert die beiden Signale, um einen Umgebungslichtwert (ALS) zu berechnen, der dem menschlichen Auge nachempfunden ist. Siehe das folgende Bild mit dem Funktionsblockdiagramm des APDS-9930:

Funktionsblockdiagramm des APDS-9930 ( source )

Der APDS-9930 ermöglicht es dir außerdem, obere und untere Schwellenwerte für Licht- und Näherungswerte festzulegen und sendet ein Interrupt-Signal (INT), wenn diese Schwellen überschritten werden. Für Kommunikation und Programmierung bietet der APDS-9930 eine I2C-Schnittstelle (SCL, SDA).

Die folgende Liste fasst die wichtigsten Eigenschaften des APDS-9930 zusammen:

  • Umgebungslichtmessung (ALS)
  • Annäherung an das menschliche Sehvermögen
  • Programmierbare Interrupt-Funktion mit oberen und unteren Schwellenwerten
  • Bis zu 16-Bit Auflösung
  • Hohe Empfindlichkeit auch hinter dunklem Glas
  • 01lux niedrige Lichtleistung
  • Näherungserkennung
  • Vollständig kalibriert für 100 mm Erkennung
  • Integrierte Infrarot-LED und synchroner LED-Treiber
  • Ermöglicht den Verzicht auf eine Werkskalibrierung des Näherungssensors
  • Programmierbarer Warte-Timer
  • Stromverbrauch im Wartezustand – typisch 90μA
  • Programmierbarer Bereich von 2,7 ms bis über 8 Sekunden
  • I2C-Schnittstelle kompatibel
  • Bis zu 400kHz (I2C Fast Mode)
  • Eigener Interrupt-Pin
  • Stromverbrauch im Sleep-Modus – typisch 2,2μA

Für detailliertere Informationen wirf einen Blick ins unten verlinkte Datenblatt:

Breakout-Board für APDS-9930

Der APDS-9930 Chip ist zu klein, um ihn direkt an einen Arduino anzuschließen. In der Regel benötigst du ein Breakout-Board wie unten gezeigt:

Front and Back of Breakout board for APDS-9930
Vorder- und Rückseite des Breakout-Boards für APDS-9930

Breakout-Boards für den APDS-9930 haben normalerweise sechs Pins:

  • VCC : Stromversorgung (2,4 – 3,6V)
  • GND : Masse
  • VL : IR-LED-Stromversorgung
  • SDA : I2C-Datensignal
  • SCL : I2C-Taktsignal
  • INT : Interrupt-Pin

In den meisten Fällen benötigst du nur die Stromversorgungspins (VCC, GND) und die Pins für die I2C-Kommunikation (SCL, SDA). Der INT-Pin wird aktiv, wenn das Umgebungslicht oder die Nähe programmierbare Schwellenwerte überschreitet.

VL ermöglicht es dir, der IR-LED eine externe Stromversorgung bereitzustellen. Auf der Rückseite des Breakout-Boards befindet sich ein Lötjumper, den du schließen musst, wenn du VL für die IR-LED-Stromversorgung nutzen möchtest.

Beachte, dass der APDS-9930 mit 3,3V betrieben wird und die meisten Breakout-Boards normalerweise keinen Spannungsregler haben. Das bedeutet, du musst VCC mit 3,3V verbinden und darfst den 5V-Ausgang eines Arduino nicht verwenden!

APDS-9930 mit Arduino verbinden

Dank der I2C-Schnittstelle des APDS-9930 ist der Anschluss an einen Arduino ganz einfach. Verbinde zuerst den SCL-Pin des APDS-9930 Breakout-Boards mit A5 des Arduino. Verbinde ebenso SDA mit A4 des Arduino. Danach verbindest du GND mit Masse und 3,3V mit VCC des APDS-9930.

Connecting APDS-9930 to Arduino
APDS-9930 mit Arduino verbinden

Achte darauf, dass du 3,3V als Stromversorgung verwendest. Der APDS-9930 Sensor ist nicht für 5V ausgelegt und die typischen Breakout-Boards für den APDS-9930 haben keinen Spannungsregler.

APDS-9930 Bibliothek installieren

Bevor wir den APDS-9930 nutzen können, müssen wir eine Bibliothek installieren. Die einzige Bibliothek, die ich finden konnte, ist die APDS-9930 Library by Depau , die zwar nicht mehr gepflegt wird, aber trotzdem einwandfrei funktioniert. Um sie zu installieren, gehe zum repo und klicke auf den grünen „Code“-Button. Dann klicke auf „Download Zip“, wie unten gezeigt:

Download APDS-9930 library
APDS-9930 Bibliothek herunterladen

Gehe dann zu „Sketch“ -> „Include Library“ -> „Add .Zip Library..“ und wähle die „APDS9930-master.zip“ Datei aus, die du gerade heruntergeladen hast:

Adding APDS-9930 library to sketch
APDS-9930 Bibliothek zum Sketch hinzufügen

Alternativ kannst du auch den gesamten Code des Repos herunterladen, zippen und die Bibliothek dann auf die gleiche Weise einbinden. Jetzt können wir mit dem Programmieren loslegen.

Umgebungslicht mit dem APDS-9930 messen

Der folgende Code liest Umgebungslichtwerte vom APDS-9930 Sensor aus.

#include "Wire.h"
#include "APDS9930.h"

APDS9930 sensor = APDS9930();

void setup() {
  Serial.begin(9600);
  sensor.init();
  sensor.enableLightSensor(false);
  delay(500); 
}

void loop() {
  static float light = 0;
  
  if (sensor.readAmbientLightLux(light)) {
    Serial.print("light:");
    Serial.println(light);
  }

  delay(500);
}

Wir beginnen damit, die benötigten Bibliotheken einzubinden und das Sensorobjekt zu erstellen. Im setup -Abschnitt wird der Sensor initialisiert und der Lichtsensor aktiviert.

Das false in enableLightSensor(false) bedeutet, dass wir keine Interrupts verwenden, wenn wir das Umgebungslicht messen. Du kannst den INT-Ausgang des APDS-9930 mit einem digitalen Eingang des Arduino verbinden und eine Interrupt Service Routine (ISR) auslösen, wenn ein bestimmter Lichtwert erreicht wird. Der APDS-9930 bietet example code dafür.

Im loop -Abschnitt lesen wir den Lichtwert mit readAmbientLightLux(light) aus und geben ihn, falls erfolgreich, im Serial Monitor aus. Siehe folgende Beispielmessungen:

Ambient light levels printed to Serial Monitor
Umgebungslichtwerte im Serial Monitor ausgegeben

Und wenn du den Serial Plotter öffnest und den APDS-9930 auf eine Lichtquelle richtest, z.B. eine Schreibtischlampe, solltest du einen Ausschlag im Diagramm sehen:

Ambient light levels on Serial Plotter
Umgebungslichtwerte im Serial Plotter

Näherung mit dem APDS-9930 messen

Der APDS-9930 erkennt die Nähe eines Objekts, indem er einen IR-Impuls von der internen IR-LED aussendet und die Menge des reflektierten IR-Lichts misst. Je näher das Objekt, desto mehr Energie wird reflektiert.

Der Code zur Messung der Nähe ist dem Code zur Messung des Umgebungslichts sehr ähnlich. Die einzigen beiden Unterschiede sind, dass wir enableProximitySensor(false) im setup -Abschnitt aufrufen und readProximity(proximity) in der loop-Funktion verwenden. Siehe das folgende Beispiel:

#include "Wire.h"
#include "APDS9930.h"

APDS9930 sensor = APDS9930();

void setup() {
  Serial.begin(9600);
  sensor.init();
  sensor.enableProximitySensor(false);
  delay(500); 
}

void loop() {
  static uint16_t proximity = 0;
  
  if (sensor.readProximity(proximity)) {
    Serial.print("proximity:");
    Serial.println(proximity);
  }

  delay(500);
}

Wie zuvor bedeutet das false in enableProximitySensor(false) , dass wir keine Interrupts verwenden, sondern kontinuierlich Näherungswerte auslesen. Typische Näherungswerte liegen etwa zwischen 300 (kein Objekt) und 1023, wenn das Objekt sehr nah ist.

Wenn du den Serial Plotter öffnest und deine Hand wiederholt näher oder weiter vom Sensor entfernst, solltest du ein wellenförmiges Muster sehen, ähnlich wie unten gezeigt:

Proximity values on Serial Plotter
Näherungswerte im Serial Plotter

Näherung und Licht mit dem APDS-9930 messen

Natürlich können wir auch gleichzeitig Nähe und Umgebungslicht messen. Das folgende Codebeispiel aktiviert den Näherungs- und Lichtsensor im setup -Abschnitt und liest die Näherungs- und Lichtwerte in der loop -Funktion aus:

#include "Wire.h"
#include "APDS9930.h"

APDS9930 sensor = APDS9930();

void setup() {
  Serial.begin(9600);
  sensor.init();
  sensor.enableProximitySensor(false);  
  sensor.enableLightSensor(false);  
}

void loop() {
  static uint16_t proximity = 0;
  static float light = 0;
  
  if (sensor.readProximity(proximity)) {
    Serial.print("proximity:");
    Serial.println(proximity);
  }
    
  if (sensor.readAmbientLightLux(light)) {
    Serial.print("light:");
    Serial.println(light);
  }  

  delay(500);
}

Wenn du diesen Code ausführst und den Serial Plotter öffnest, wirst du feststellen, dass der Lichtsensor und der Näherungssensor ein negativ korreliertes Verhalten zeigen. Siehe das Bild unten.

Proximity and Light values on Serial Plotter
Näherungs- und Lichtwerte im Serial Plotter

Das liegt daran, dass der Näherungswert hoch ist, wenn du die Hand nah an den Sensor bringst, aber da die Hand das Umgebungslicht blockiert, ist der gemessene Lichtwert niedrig. Umgekehrt ist der Näherungswert niedrig, wenn kein Objekt in der Nähe ist, aber der Lichtwert ist höher (sofern Licht vorhanden ist).

Automatische Helligkeitsanpassung mit dem APDS-9930

Im letzten Beispiel setzen wir die typische Anwendung des APDS-9930 um. Wir schalten eine LED ein, wenn ein Objekt (Hand) in der Nähe des Sensors ist, und passen die Helligkeit der LED entsprechend dem Umgebungslicht an.

Dafür müssen wir nur eine LED zu unserer Schaltung hinzufügen. Im unten gezeigten Aufbau habe ich eine LED mit einem 220Ω Widerstand an Pin 11 angeschlossen. Du kannst auch einen anderen Ausgangspin verwenden, aber er muss PWM-fähig sein.

Connecting APDS-9930 and LED to Arduino
APDS-9930 und LED mit Arduino verbinden

Im folgenden Code lesen wir die Näherungs- und Lichtwerte aus. Wenn der Näherungswert 500 überschreitet (Hand ist nah am Sensor), stellen wir die Helligkeit der LED relativ zum Umgebungslicht ein. Je mehr Umgebungslicht, desto heller die LED.

#include "Wire.h"
#include "APDS9930.h"

APDS9930 sensor = APDS9930();
const int ledPin = 11;  // PWM

void setup() {
  Serial.begin(9600);
  sensor.init();
  sensor.enableProximitySensor(false);
  sensor.enableLightSensor(false);
  pinMode(ledPin, OUTPUT);
  delay(500);
}

void loop() {
  static uint16_t proximity = 0;
  static float light = 0;
  static float maxLight = 0;

  sensor.readProximity(proximity);
  sensor.readAmbientLightLux(light);

  if (proximity > 500) {
    maxLight = max(light, maxLight);
    int brightness = map(light, 0, maxLight, 0, 1023);
    analogWrite(ledPin, brightness);
  } else {
    analogWrite(ledPin, 0);
  }

  delay(100);
}

Da wir vorher nicht wissen, wie hell das Umgebungslicht maximal sein kann, aktualisiert der Code in jeder Schleife den maximalen Lichtwert. Du kannst aber auch ein paar Tests machen und einen festen Maximalwert wählen.

Und das war’s! Ich hoffe, du hattest Spaß beim Ausprobieren des APDS-9930 Näherungs- und Lichtsensors – ich auf jeden Fall ; )

Fazit

In diesem Tutorial hast du gelernt, wie du mit dem APDS-9930 Näherungs- und Lichtsensor und einem Arduino Objekte erkennen und Umgebungslicht messen kannst.

Beachte, dass der APDS-9930 Library by Depau mehr Funktionen bietet, als wir hier gezeigt haben. Du kannst zum Beispiel die Werte der beiden Fotodioden (Ch0, Ch1) auslesen, Schwellenwerte für Nähe und Licht setzen und auf Interrupts reagieren. Schau dir dazu die example code an, die mit der Bibliothek geliefert wird.

Der APDS-9930 ist ein guter Sensor, um einfache Gesten zu erkennen und auf Licht zu reagieren. Wenn du zum Beispiel ein Display durch eine Handbewegung davor aktivieren und gleichzeitig die Helligkeit je nach Umgebungslicht anpassen möchtest, ist der APDS-9930 ideal dafür.

Wenn du jedoch Entfernungen zu Objekten genau messen möchtest, z.B. für Robotik-Anwendungen, bist du mit Infrarot-Abstandssensoren wie dem GP2Y0A710K0F , die per Triangulation die Entfernung bestimmen, besser beraten. Oder noch besser: Verwende einen Time-of-Flight (ToF) Laser-Entfernungssensor wie den TOF10120 oder den VL53L1X library , die auch große Distanzen sehr genau messen können.

Wenn du Fragen hast, schreib sie gerne in die Kommentare.

Viel Spaß beim Tüfteln ; )