Lichtsensor Avago APDS-9300

Aus Hobbyelektronik.org
Version vom 3. Januar 2016, 23:40 Uhr von Chris (Diskussion | Beiträge) (Datelinks auf Bilder korrigiert)

Vor einiger Zeit (genau genommen noch im Studium) wollte ich mit Lichtsensoren (ambient light sensors, ALS) spielen. Da ich bei Farnell bestellen konnte, kamen zwei Avago APDS-9300 mit auf das Bestellformular (Mittlerweile auch beim blauen Claus bzw. Völkner zu haben).

Aufgrund der Bauform und Zeitmangel blieben sie relativ lange in der ESD-Tüte.

Der Sensor

Was soll man groß Worte über einen Lichtsensor verschwenden?

Licht rein, aufbereitetes Signal raus und gut ist. Ganz so einfach ist es (zumindest beim APDS-9300) leider nicht.

Viele optische Sensoren drehen bei Infrarot wild, das menschliche Auge zeichnet sich dagegen als ziemlich unempfindlich aus. In Digitalkameras werden aus diesem Grund IR-Filter verbaut (die Astrofotografen wieder entfernen), allerdings scheint das den Entwicklern bei Avago entweder zu teuer oder zu unpraktisch gewesen zu sein - sie haben zwei Fotodioden verbaut: Eine ist empfindlich auf das sichtbare Licht und Infrarot, die andere nur auf Infrarot (siehe Seite 7 vom Datenblatt). Der Rest ist Mathematik.

Da die menschliche Wahrnehmung weitestgehend logarithmisch ist, braucht man zur Nachbildung einen großen Dynamikumfang. Daher kann der ALS mehrere Betriebsmodi. Zum einen kann man die Integrationszeit (also die Zeit, in der die Lichtdosis gesammelt wird) wählen - konkret zwischen 13,7 ms, 101 ms und 402 ms. Zum anderen kann man einen 16-fach-Verstärker zuschalten. Dadurch gewinnt man zwar Empfindlichkeit, bezahlt die aber mit der Auflösung und Rauschen.

Die Wahl der richtigen Einstellung hängt selbstverständlich von der Umgebungshelligkeit ab, ansonsten liest man entweder 0 oder der bekommt Werte in der Sättigung, die einfach keinen Sinn ergeben.

Hardware

Bei der Fertigung meiner ersten Fuhre Leiterkarten bei DirtyPCBs landete auch ein kleines Breakout-Board auf dem Panel:

Neben dem Sensor selbst befindet sich aufgrund dessen etwas unpraktischen Versorgungsspannung ein 2,5 V-LDO-Spannungsregler.

Die Wahl auf den LDO fiel, damit die Schaltung neben den eher altmodischen 5 V auch bei 3,3 V (und somit zum Beispiel mit dem Raspberry Pi) funktioniert.

Als Schnittstelle dient bei dem Lichtsensor I²C, die Treiberstufen sind hier zwar zwangsläufig Open Drain und können deshalb in aller Regel etwas höhere Spannungen als die Betriebsspannung ab, bei den Eingangstufen bzw. ESD-Schutz wird es für das Bauteil bei höheren Spannungen ungemütlicher.

Levelshifter

Damit man den I²C mit höherer Spannung betreiben kann, wird ein (bzw. eher zwei) Levelshifter benötigt.

Diesen kann man entweder fertig kaufen oder mit nur wenigen Bauteilen aufbauen - AN10441 von NXP erklärt, wie es funktioniert.

Für alle, die zu faul zum Klicken oder des Englischen nicht ganz so mächtig sind: Bei der Schaltung wird sowohl die Body-Diode als auch die schaltende Wirkung des FET genutzt (und als Beifang die Pull-Up-Widerstände, die man für I²C eh braucht).

Das Schaltungsprinzip ist einfach wie genial:

Wird keine der beiden Seiten auf Masse gezogen, ist U_GS nahezu 0 oder zumindest weit unter U_GS,th - der FET sperrt und dadurch dass die Spannung auf der Kathoden-Seite der Diode höher als auf der Anoden-Seite ist, sehen sich die Schaltungsteile nicht. Den Rest erledigen die Pull-ups.

Wird auf der 3,3 V-Seite das Signal auf Masse gezogen, steigt U_GS über U_GS,th und der Transistor beginnt zu leiten. Dadurch sieht man auf der 5 V-Seite die Masse der 3,3 V-Seite.

Szenario Nummer 3 ist nicht ganz so offensichtlich: Wird die 5 V-Seite auf Masse gezogen, fällt zunächst der Drain-Pin des FETs auf Masse. Jetzt kommt ein Teil vom Transistor ins Spiel, der einem manchmal einen Knoten ins Gehirn macht: Die Body-Diode. Ist auf deren Kathoden-Seite ein niedrigeres Potenzial als auf deren Anoden-Seite, wird sie leitfähig, somit zieht sie den Source-Pin ebenfalls gegen die Masse, die auf der Source-Seite anliegt. Gegen - nicht auf - da noch ein bisschen Vorwärtsspannung abfällt. Allerdings fällt steigt auch U_GS über U_GS,th (der zweite Knoten im Gehirn) und der FET wird leitfähig. Somit ist die Masse der 5 V-Seite auf der 3,3 V-Seite (relativ) sauber sichtbar.

Fertig ist der pillepalle einfache bidirektionale Levelshifter.

Einziger Nachteil: die Spannung "links" muss immer kleiner sein als die "rechts". Zudem ist man mit den Spannungspegeln begrenzt (zum einen durch U_GS,th des FET und zum anderen durch die U_f der Body-Diode).

Übrigens kann man durch das Abklemmen des Gates die Seite mit der niedrigeren Spannung isolieren.

Software - der erste Versuch

Wie kann man relativ einfach mit I²C basteln? Bei denen im PC kommt man zumindest unter Windows nicht ran (und will es auch nicht), bei Mikrocontrollern muss man erst Soft- und Hardware basteln - das ist aufwändig und fehleranfällig.

Was liegt also näher, als den Raspberry Pi zu verwenden?

Dort gibt es neben den i2c-tools auch eine Integration in Python.

Da ich keine besonderen Erfahrungen mit letztere Sprache habe, möge man mir die Codequalität entschuldigen.

apds9300.py ist eine Klasse, die die Kommunikation mit dem Sensor beinhaltet. Mit viewapds.py wird der Sensor im Halbsekunden-Takt ausgelesen und sowohl die rohen als auch der berechnete Wert ausgegeben.

So viel zur Theorie.

In der Praxis verwandelte sich die Verwunderung sehr schnell in Verzweiflung - es kamen einfach keine auch nur halbwegs sinnvollen Werte heraus. Zuerst hatte ich meine kläglichen Versuche in Python im Verdacht, nach mehrmaligem Überprüfen und neu schreiben stellte sich allerdings heraus, dass anscheinend etwas mit dem Chip oder Datenblatt nicht passt, denn ein Vergleich mit Beispielen in Wikipedia sagte mir nur: du liegst falsch.

Nach ein paar Recherchen stellte sich heraus, dass der APDS-9300 auf einem anderen Sensor basiert (oder zumindest nicht verleugenbare Ähnlichkeiten besitzt), dem TS256x von TAOS. Auch der physische Aufbau hat gewisse Ähnlichkeiten (und die Formeln zur Berechnung der Helligkeit ebenfalls). Zudem hatten auch schon andere das Problem mit den Berechnungen, nur gab es keine Lösung.

Kalibrierung

Da hilft nur noch eines: Kalibrieren. Nur gegen was? Die Helligkeitswerte aus dem oben erwähnten Wikipedia-Artikel kann man nicht so einfach und vor allem nicht so genau nachstellen, also muss entweder eine kalibrierte Lichtquelle her oder Vergleichsmessungen gemacht werden.

Es liegen ja genügend "Messgeräte" in Form von Handy und Tablet herum. Mit einer passenden App bekommt man die Helligkeit mundgerecht angezeigt, nur: bei meinen HTC (Sensation, Flyer und Explorer) kann man nur zwischen heller Sommertag, bedeckter Sommertag und Zappenduster unterscheiden.

Das LG-Handy war in der interessanten Zeit in Reparatur und das Samsung-Tablet hatte zwar eine sehr hohe Auflösung aber dafür eine völlig unbrauchbare Winkelabhängigkeit.

Ich habe mir sogar überlegt, mit der Fotokamera zu messen. Aber wie zum Henker kommt man von Blende, Belichtungszeit, Bildempfindlichkeit und Bildausschnitt auf einen brauchbaren Helligkeitswert in Lux? Nachdem die Granularität durch die festen Schritte bei den drei ersten Parametern recht schlecht ist und die Messung durch den Bildausschnitt noch heikler wird, habe ich es bei der Idee belassen.

Es muss also ein geeignetes Messgerät her. Nur für das Vermessen eines Sensors Messequipment kaufen (das den Sensor auch gleich ersetzt)? Muss nicht sein:

Minolta T-10

In der Arbeit ist u. a. ein portables Luxmeter vorhanden und ich durfte es mir freundlicherweise für zwei Wochenenden ausleihen.

Das Teil hat eine RS-232-Schnittstelle, wenn auch mit einem etwas komischen Stecker.

Nach der Protokollbeschreibung muss man etwas suchen, allerdings ist die Implementierung (abgesehen vom etwas verschwurbelten Ausgabeformat) relativ einfach zu bewerkstelligen. Wer in die Verlegenheit kommt, so ein T-10 (oder vergleichbare Modelle) auszulesen: unten in den Downloads gibt es sowohl für Python als auch C# Quelltexte.

Versuch 1

Der Messaufbau umfasst:

  • ALS und Luxmeter (über USB-RS232-Wandler) am Pi
  • eine windig zusammengebaute Lichtquelle aus LED-Streifen, Kühlkörper und Diffusor aus einem alten Notebook-Display.
  • Ein Rigol DP832 als Spannungsquelle
  • Eine Metallschiene sowie ein Pappkarton zum Aufbauen eines "Lichtgalgen"

Beide Lichtsensoren (Minolta und mein Kalibrierkandidat) wurden auf gleiche Ebene gebracht (wichtig!) und fixiert.

Das Netzteil kann Spannungs- und Stromsweeps, die für solch einen Zweck auf den ersten Blick perfekt geeignet sind. Also den Strom von 0 bis IIRC knapp 1,5 A in 400 Schritten zu je 2 Sekunden durchlaufen lassen, das Messgerät und Sensor mit etwas höherer Frequenz abfragen und in eine Log schreiben lassen. Das Ganze mit allen möglichen Konfigurationen des ALS.

Excel auf dem großen PC macht den Rest.

Naja, denkste. Die Helligkeit ging alles andere als linear hoch. Die Daten habe ich direkt weggeworfen und die Messung erneut mit Variation Spannung laufen lassen - entgegen dem allgemeinen Glauben ging die Helligkeit linear hoch. Trotzdem ist und bleibt die Regel: LEDs über Stromquellen versorgen. Die Gründe breite ich hier jetzt nicht aus.

Dort die beiden Helligkeitswerte im X-Y-Diagramm auftragen lassen und feststellen, dass der Sensor fernab von dem ist, was zu erwarten ist. Genauso sind die Daten in der Hinsicht etwas ungeschickt zum Auswerten, dass es für jede tatsächliche Helligkeit mehrere Wertepaare gibt. Gleichzeitig gibt es aber auch (erwartungsgemäß) ungültige Wertpaare, da ein Sensor vor und der andere nach dem Umschalten der Spannung ausgelesen wurde. Die ganzen Messartefakte kann man zwar filtern, aber das ist unnötig und nervig.

Nachdem die ganzen Messungen durch waren, musste das Luxmeter auch schon wieder zurück in die Arbeit. Nachdem der erste Lauf vielversprechend war, glaube ich, dass die anderen Messungen ok waren. Zudem war es viel zu heiß (Sommer 2015), um im Büro zu sitzen. Long story short: ein kleiner Programmierfehler und die Integrationszeiten wurden nicht in den Sensor geschrieben.

Aarrgghh!

Versuch 2

Fehler darf man machen, solange man daraus lernt.

Das Rigol kann USB, und für das Auslesen des ALS habe ich eine Schaltung mit dem MCP2221 aufgebaut.

Die Lichtquelle bleibt die selbe, sie steckt aber nun in der Decke eines Schuhkartons. Dadurch kann der Abstand, Position und Helligkeit (Streulicht!) relativ gut definiert werden:

Software: Dieses Mal in C#. Das kenne ich halbwegs und mag es.

Automatisierung

Zur Ansteuerung vom Netzteil muss erst einmal NI VISA installiert werden. Ich hasse es, ich liebe es. Ich hasse es, weil die VISA-Treiber ein riesiges Bollwerk sind und man beim ersten Versuch immer die falschen erwischt. Zudem gibt es einen schönen Bug, bei dem Windows nach deren Installation irgendwann anfängt, knapp 20 Minuten für den Login zu braucht. Den offiziellen Fix habe ich selbst noch nicht getestet, mit der im NI-Forum beschriebenen Vorgehensweise habe ich gute Erfahrungen gemacht. Dadurch macht man sich unter Umständen zwar LXI kaputt, was in den meisten Fällen eh nicht verwendet wird.

Was ich an VISA liebe? SCPI! Messautomatisierung ist etwas wirklich feines und nicht nur, weil man auf dem Weg in die Mittagspause noch kurz "MAHLZEIT" auf dem Multimeter anzeigen lassen kann. Mir hat es in der Arbeit bereits unbeschreiblich viel manuelle Messzeit erspart. Dazu kommt, dass die Wiederholbarkeit sehr gut ist.

Wie auch immer, die Software ist schnell und hässlich - aber zweckmäßig - runtergerissen. Die Messungen sind zum Einstellen der Helligkeit der Lichtquelle synchronisiert und neben den deutlich besseren Ergebnissen kann ich zugleich meine Lichtquelle kalibrieren.

Ein Messlauf dauert nicht ganz zwei Minuten, wegen der unterschiedlichen Integrationszeiten und den beiden möglichen Verstärkungsfaktoren mal 6 und schon hat man einen Sensor vermessen.

Auswertung

Das ganze nochmal in Excel verwurstet und es sieht gar nicht mal so gut aus:

Im ersten Diagramm sieht man, dass die Werte schön und nahezu linear nach oben gehen, allerdings ist da - je nach Integrationslänge ordentlich Faktor drauf. Bei der Ausgabe wurde die Integrationszeit nicht berücksichtigt. Die Einbrüche im zweiten Diagramm lassen sich durch die tatsächlichen Messwerte erklären:

Kanal 0 geht bei 16-facher Verstärkung sehr früh in Sättigung - das ist alles.

Ok, nun müssen die Helligkeitswerte noch richtig skaliert werden. Meine Vermutung geht stark in die Richtung, dass entweder die Lichtempfindlichkeit oder die Integrationszeit bei den Sensoren nicht ganz richtig sind. Man kann den Korrekturfaktor zwar auf die berechnete Helligkeit anwenden - dadurch dass es in den Berechnungen keine Offsets gibt, sollte das auch funktionieren. Mir ist es allerdings deutlich lieber, direkt die rohen Werte zu behandeln.

Also die Messwerte skalieren, durch die Formel zur Berechnung der Helligkeit jagen und das Ergebnis vergleichen. Excel kann das relativ gut automatisch - mit der Zielwertsuche. Der Parameter dafür ist die prozentuale Abweichung der berechneten Helligkeit und der Referenzmessung vom Luxmeter. Damit das Ganze funktioniert, muss der Algorithmus zur Berechnung in Excel implementiert werden. Ich habe aufgehört zu zählen...

Unter Berücksichtigung der Integrationszeiten ergibt sich ein Faktor von relativ genau 0,2, um auf die "richtige" Helligkeit zu kommen.

Zum Vermessen des zweiten Sensors habe ich diesen Faktor für die Berechnung des ausgegebenen Wertes in meine Software eingetragen und es kommt relativ gut hin - über den kompletten Messbereich war die Abweichung nicht größer als 5 %. Selbstverständlich ist das statistisch nicht aussagekräftig aber trotzdem eine Bestätigung, dass die ganze Aktion nicht grob falsch war.

Die Erkenntnisse sind auch direkt in die C#-Software gewandert. Mit dieser kann im aktuellen Zustand die Helligkeit angezeigt werden.

"Kalibrierung" der Lichtquelle

Das Luxmeter musste ich selbstverständlich zurückgeben, aber was nun, wenn plötzlich und völlig unerwartet wieder ein Lichtsensor auf dem Tisch liegt und getestet werden muss, ob er richtig liegt, wenn das Licht angeht?

Warum nicht einfach schauen, wie stabil die Lichtquelle ist? Natürlich ist der 15-Minuten-Aufbau nichts, was man für professionelle Zwecke auch nur in Erwägung ziehen würde, aber für den Heimbedarf - und um einen groben Anhaltspunkt zu finden: warum nicht?

LEDs verändern sich in ihrem Leben. Wie sie bei Umgebungstemperatur altern: da habe ich kein wirkliches Gefühl. Allerdings weiß ich sehr genau, dass sie mit der Betriebszeit und durch Temperatur altern. Zugleich können sie ihre momentane Ausbeuten durch Erwärmung verändern. Da der Aufbau vermutlich nur für kurze Tests verwendet werden soll, kann die "Abnutzung" durch Betriebsdauer vernachlässigt werden. Anders ist es bei der Veränderung durch Betriebstemperatur.

Allerdings kann man das relativ einfach testen: LEDs auf maximaler Leistung betrieben, Lichtsensor darunter packen und während den laufenden Messungen warten. Nach gut 20 Minuten (Länger ist das Ding wahrscheinlich eh nie am Stück im Betrieb) tat sich: nichts. Die LEDs sind offensichtlich stabil genug - oder die Messeinrichtung zu ungenau. Wer weiß.

Auf jeden Fall habe ich jetzt eine zumindest grob brauchbare Ergebnisse, falls mal wieder ein Sensor vermessen werden will.

Leiterkarten

Ein paar der oben gezeigten Leiterkarte sind noch übrig. Wer will, kann eine haben.

Downloads