Der Licht, Farbe und Gesten Sensor (APDS-9960) wurde mir kostenfrei vom Onlineshop Paradisetronic.com zur Verfügung gestellt.
Bezug
Den Sensor kann man für 10,79 € bei Paradisetronic.com beziehen. Die Versandkosten in höhe von 4,5 € (für Inlandsversand) kommen zusätzlich dazu.
Ab einem bestellwert von 40€ entfallen die Versandkosten, daher einfach mal im Shop schauen, es lohnt sich.
Technische Daten des Sensors
- Betriebsspannung 3.3V bis 5V
- Abmaße 17,8 mm x 17,8 mm x 3,2 mm
- Gewicht 1,3g
Anschluss
Der Sensor verfügt über 6 Pins welche wie folgt an den Arduino UNO angeschlossen werden:
APDS-9960 | Arduino UNO |
---|---|
VIN | 3,3V oder 5V |
3Vo | |
Gnd | GND |
SCL | SCL |
SDA | SDA |
Int | Interrupt Pin des Sensors |
In diesem Beispiel verwende ich den Arduino UNO welcher wohl der meist verbreiteste Microcontroller ist. Jedoch funktioniert dieser Sensor auch an anderen Microcontrollern, da muss man jedoch prüfen wo die SCL & SDA Pins liegen. Eine Google Suche mit “<<Microcontrollername>> pinout” führt hier immer zum Ziel.
Der mir vorliegende Arduino UNO Clone von der Firma Sunfounder verfügt über extra hinausgeführte SCL & SDA Pins.
Diese beiden Pins sind auf der Rückseite des Mikrocontrollers beschriftet.
Interrupt Pin
Der Interrupt Pin liefert ein Signal, wenn die nächste Messung erfolgen kann oder die Messung zu lange dauert. Der Interrupt Pin wird mit einem digitalen Pin des Mikrocontrollers verbunden und als Eingang gesetzt.
#define INTERRUPT D2 void setup(){ pinMode(INTERRUPT,INPUT_PULLUP); }
Schaltung
Der Sensor wird wie folgt an den Arduino UNO angeschlossen.
Quellcode
Für den nachfolgenden Quellcode wird die Adafruit Bibliothek für den Sensor benötigt. Diese Bibliothek kann unter https://github.com/adafruit/Adafruit_APDS9960/archive/master.zip als ZIP Datei heruntergeladen werden. Wie man eine Bibliothek in die Arduino IDE einbindet, habe ich im Tutorial Arduino IDE, Einbinden einer Bibliothek erläutert.
Wenn man nun die Bibliothek erfolgreich eingebunden hat, erhält man gleich zu jedem “Teil” des Sensors ein Beispiel.
Die nachfolgenden Sketche sind aus Teilen der oben genannten Beispiele entstanden. Ich habe diese nur etwas abgewandelt und vor allem an den wichtigen Stellen kommentiert.
Erkennen einer Geste
Im nachfolgenden Quellcode möchte ich die Gesten, d.h. eine Bewegung erkennen und auswerten.
Wenn sich vor dem Sensor etwas von rechts nach links bewegt, so soll dann die LED Bar ein Lauflicht in der Richtung anzeigen und andersherum.
#include "Adafruit_APDS9960.h" //Adafruit Bibliothek für den Sensor //LEDs für die Richtungsanzeige const int leds[8] = {2,3,4,5,6,7,8,9}; //Defaultwert für die Pause zwischen den Aktionen. const int PAUSE = 250; //Initialisieren des Objektes Adafruit_APDS9960 apds; void setup() { //Begin der seriellen Kommunikation //mit 115200 Baud. Serial.begin(115200); //Prüfen ob das Objekt und somit der Sensor //erfolgreich initialisiert wurde. if(!apds.begin()){ Serial.println("Initialiserung des Sensors fehlgeschlagen."); Serial.println("Bitte prüfen Sie die Verkabelung!"); } else { Serial.println("Der Sensor wurde erfolgreich initialisiert!"); } //Einstellen das der Sensor die Gesten erkennt. apds.enableProximity(true); apds.enableGesture(true); //Die digitalen Pins an welchen die LEDs angeschlossen sind //als Ausgänge setzen. for(int i=0;i<=7;i++){ pinMode(leds[i],OUTPUT); } } void loop() { //initial sollen alle LEDs aus sein! resetLeds(); //Lesen des aktuellen Wertes vom Sensor. uint8_t gesture = apds.readGesture(); //Der Sensor kann alle Richtungen erkennen, //oben, unten, rechts und links. //In diesem Beispiel werte ich nur die Richtungen rechts und links aus. switch(gesture){ case APDS9960_LEFT: leftToRight(); break; case APDS9960_RIGHT: rightToLeft(); break; } } //Funktion um alle LEDs auszuschalten. void resetLeds(){ delay(PAUSE); for(int i=0;i<=8;i++){ digitalWrite(leds[i],HIGH); } } //Erzeugt ein Lauflicht von links nach rechts. void leftToRight(){ for(int i=8;i>=0;i--){ digitalWrite(leds[i],HIGH); delay(PAUSE); digitalWrite(leds[i],LOW); } } //Erzeugt ein Lauflicht von rechts nach links. void rightToLeft(){ for(int i=0;i<=8;i++){ digitalWrite(leds[i],HIGH); delay(PAUSE); digitalWrite(leds[i],LOW); } }
Farbe erkennen
Für den nachfolgenden Quellcode wird zusätzlich eine RGB LED benötigt, ich habe die LED RGB 140C05 verwendet.
#include "Adafruit_APDS9960.h" //Adafruit Bibliothek für den Sensor Adafruit_APDS9960 apds; #define LED_RED 9 #define LED_GREEN 10 #define LED_BLUE 11 uint16_t r, g, b, c; void setup() { //Die Pins der 10mm RGB LED als Ausgang setzen. pinMode(LED_RED, OUTPUT); pinMode(LED_GREEN, OUTPUT); pinMode(LED_BLUE, OUTPUT); //Begin der seriellen Kommunikation mit 115200 baud. Serial.begin(115200); //Prüfen ob das Objekt und somit der Sensor //erfolgreich initialisiert wurde. if(!apds.begin()){ Serial.println("Initialiserung des Sensors fehlgeschlagen."); Serial.println("Bitte prüfen Sie die Verkabelung!"); } else { Serial.println("Der Sensor wurde erfolgreich initialisiert!"); } //Den Sensor als Farbsensor setzen. apds.enableColor(true); } void loop() { //Solange der Farbsensor nicht fertig ist 5ms warten... while(!apds.colorDataReady()){ delay(5); } //Liest den Farbwert vom Sensor //und speichert die Werte in den Variable r,g,b und c apds.getColorData(&r, &g, &b, &c); //Maximaler RGB Farbwert. const int maxColorValue = 255; int red = maxColorValue-r; int blue = maxColorValue-b; int green = maxColorValue-g; //Ausgabe des RGB Wertes auf den seriellen Monitor Serial.print("rgb["); Serial.print(red); Serial.print(","); Serial.print(green); Serial.print(","); Serial.print(blue); Serial.println("]"); //setzen der Farbe an der 10mm LED 140C05 analogWrite(LED_RED, red); analogWrite(LED_GREEN, green); analogWrite(LED_BLUE, blue); }
Video
In dem Video ist gut zuerkennen, dass eine separate Lichtquelle für den Sensor benötigt wird, damit dieser korrekt arbeitet. Ich habe hier die LED eines Handys benutzt da dieses sehr stark ist. Ich habe zusätzlich eine 10 mm RGB LED angeschlossen, welche den RGB Wert als Licht wieder gibt.
Das Video habe nicht extra zu YouTube hochgeladen, da die 5MB den Aufwand nicht rechtfertigen.
Abstandssensor
Der Sensor APDS9960 kann einen Abstand zu einem Objekt vor dem Sensor messen.
Der Sensor kann Abstände zwischen 0 cm und 6,5 cm erkennen.
Der Wert des Abstandes wird als ganzzahliger, positiver Wert zurückgegeben.
#include "Adafruit_APDS9960.h" //Der Interuptpin, für das erkennen einer neuen Messung. #define INT_PIN 2 //LED Balken anzeige mit 5mm LEDs #define LED_GR1 12 #define LED_GR2 11 #define LED_GR3 10 #define LED_GR4 9 #define LED_GR5 8 #define LED_GL1 7 #define LED_GL2 6 #define LED_GL3 5 #define LED_RT1 4 #define LED_RT2 3 //Array mit den Pins der LEDs. const int LEDS[10] = { LED_GR1,LED_GR2,LED_GR3,LED_GR4,LED_GR5, LED_GL1,LED_GL2,LED_GL3, LED_RT1,LED_RT2 }; //Erstellen des Objektes für den Sensor. Adafruit_APDS9960 apds; void setup() { //Begin der seriellen Kommunikation mit 115200 Baud. Serial.begin(115200); //Setzen des Interuptpins als Eingang über einen 10k Ohm PullUp Widerstand. pinMode(INT_PIN, INPUT_PULLUP); //Schleife über das Array mit den Werten der digitalen Pins für die LEDs. for(int i=0;i<=10;i++){ //Setzen des digitalen Pin der LED im Array an Position "i" als Ausgang. pinMode(LEDS[i], OUTPUT); } //Prüfen ob das Objekt und somit der Sensor //erfolgreich initialisiert wurde. if(!apds.begin()){ Serial.println("Initialiserung des Sensors fehlgeschlagen."); Serial.println("Bitte prüfen Sie die Verkabelung!"); } else { Serial.println("Der Sensor wurde erfolgreich initialisiert!"); } //Modus für den Abstandssensor aktivieren. apds.enableProximity(true); //Setzt den Wert für den interup. apds.setProximityInterruptThreshold(0, 1); //Aktiviert den Interupt Modus am Sensor. apds.enableProximityInterrupt(); } void loop() { //Wenn der Interup Pin nicht High ist dann... if(!digitalRead(INT_PIN)){ //Lesen des Wertes für den Abstand. int proximity = apds.readProximity(); //Mappen der möglichen Werte des Abstandssensors //von 0 bis 255 auf die Anzahl der LEDs 0 bis 9. int led = map(proximity,0,255,0,9); //Aktivieren der LED für den Abstand. digitalWrite(LEDS[led],HIGH); //Kleine Pause von 250ms damit die LED die die volle Leuchtstärke entwickeln kann. delay(250); resetLeds(); //Löschen des Interups. apds.clearInterrupt(); } } //Zurücksetzen der LEDs. void resetLeds(){ for(int i=0;i<=10;i++){ digitalWrite(LEDS[i],LOW); } }