Inhaltsverzeichnis
ESP32-CAM OV2640 resp. Nikon D90
Um die Qualität von RGBW-Leds beurteilen zu können, und weil mir die Messwerte des AS7343-Sensors [https://www.mikrocontroller.net/topic/562653|Beitrag „AS7343 irgendwer?“] dabei zu grob sind, bastele ich an einem Spektrometer herum.
Ich habe zwei recht klare und noch ein etwas unklareres Ziel.
Die zwei klaren Ziele sind, LED-Lieferungen grob auf Einhaltung von Farbtemperatur und CRI-Angabe zu überprüfen. Für das erstere könnte der AS7343 (nach Bestimmung und Anwendung der Kalibrationsfaktoren) ausreichend sein. Für das zweitere soll das Spektrometer, und dann der spektrale Vergleich des LED-Weiß z.B. mit einem Halogenleuchtmittel, dienen.
Das etwas unklarere Ziel ist, bei weiteren Bestellungen bei denselben Lieferanten eine maximal akzeptable Abweichung zu vorherigen Lieferungen zu vereinbaren. BTF zum Beispiel hat mir zugesagt, dass Folgelieferungen von der vorherigen nicht zu unterscheiden sein werden. Und sollte das dann nicht der Fall sein, dann möchte ich in der Lage sein, das nachweisen zu können. Mit allen Vorbehalten, was die Erfolgsaussichten dabei angeht …
Anbei ein Foto eines ersten Aufbaus, und ein Bild der Spektren von vier SK6812-RGBW-5050-LEDs von Loamlin mit Nikon D90 und Micro Nikkor 60mm f/2.8.
Zum Aufbau: Links sind vier LEDs übereinander angeordnet, deren Farbe ich steuern kann. Danach folgt ein Diffusor (hier noch vier Laminierfolien; Diffusorfolien von Lee incl. deren Spektralverhalten habe ich erhalten und muss ich noch zuschneiden), dann der Spalt aus zwei schmalen Cuttermesserklingen, und dann in einigem Abstand die Beugungsfolie (1000l/mm) und die Kamera.
In dieser Version war die Kamera ein ESP32-CAM mit OV2640 mit Standardlinse, aus der ich den IR-Filter entfernt habe (war nicht so einfach, weil der IR-Filter vor der Linse war und aus Glas bestand).
Beim den Fotos mit der Nikon befand sich die Objektivvorderkante in so 1-2cm Abstand von der Folie. Lichtquelle -~2cm→ Diffusor -~2cm→ Spalt -~11cm→ Kollimatorlinse -~10cm→ -~16°→ Beugungsgitter -~16°→ -~3cm→ Vorderkante Objektiv Nikon.
Der Spalt ist laut Fühlerlehre weiter als 100um und schmaler als 150um.
Das Beugungsgitter (1000 l/mm) ist also um 16° aus der optischen Achse gedreht (sonst stößt das Objektiv gegen den Rahmen), und die Kamera um etwa 32° um das Beugungsspektrum 1. Ordnung zu erfassen.
Als Kollimator verwende ich hier eine einfache Lupenlinse mit 60mm Durchmesser und einer Brennweite von 120mm. Sie ist absichtlich etwas näher am Spalt, damit ich am Objektiv die beste Schärfe noch gerade einstellen kann. Das Objektiv ist ein AF Micro Nikkor 60mm f/2.8 mit Entfernungseinstellung 1.5m (also ganz knapp vor unendlich für parallel einfallende Strahlen).
Allerdings ist der Effekt der Kollimatorlinse eher minimal. Durch die doch schon recht große Entfernung der Beugungsfolie vom Spalt fallen die Lichtstrahlen, die letztendlich vom Objektiv erfasst werden, eh schon sehr parallel auf die Folie. Und die Linse führt zu Verzerrungen im Strahlengang und wohl auch im Spektrum. Die Streifigkeit verringert sich allerdings stark. Anbei zwei Fotos eines E27-LED-Leuchtmittels von Ikea, einmal mit und einmal ohne Kollimator. Ich habe dieses Leuchtmittel dann auch benutzt, um auf die spektralen Linien scharf zu stellen.
Im Bild meine aktuellen Ergebnisse für verschiedenes Licht, mit Kollimatorlinse:
RasPi Pico, PiCam 1.3, M12-Adapter, M12-Objektive 6mm, 8mm, 12mm, 16mm
Ich habe den Spektrometerprototypen umgebaut. Es gibt jetzt einen verstellbareren Spalt, einen Raspberry Pi Zero W, die Raspberry Kamera 1.3 mit einem 12mm Objektiv anstelle des originalen (mit selbstgedrucktem M12-Adapter), die Hauptstrahlenwege sind in mattem schwarzen Karton eingefasst, die Kamera ist (relativ) fest montiert, und ein oberer Steg reduziert die Wölbbarkeit der Bodenplatte. Anbei ein Foto (bei dem der Kamerabereich aber noch nicht kartoniert ist).
Ich erhalte mit diesem Aufbau jetzt Spektralfotos wie das angehängte
ikealed.12mm.png (hier ausnahmsweise in vollen 4MB). Der dazu verwendete
Befehl lautet:
libcamera-still -n –width 2592 –height 1944 –mode 2592:1944:12:P –rawfull -e png -r -v 3 –shutter 1000000 –gain 1 –awbgains 1,1 –framerate 0 –sharpness 0 –immediate -o ikealed.12mm.png
Ich habe dann begonnen, die Spektralfotos auszuwerten. Anbei der aktuelle Stand meines spectrogram.py. Ich suche dabei im Bild nach den luminantesten Streifen mit 64 Zeilen Höhe und werte diese aus.
Die erzeugten Quasi-Spektrogramme sind natürlich massiv durch die Spektralantwort meines Gesamtaufbaus verzerrt, also durch Diffusor, Beugungsfolie, Objektiv, Mikrolinsen, Bayerfilter und Kamerasensor. Ich sehe zum Beispiel einen massiven Einbruch des Spektrums an der Gelbseite des Grün. Dieser Einbruch zeigt sich aber natürlich auch im Quasi-Spektrogramm meiner Halogenbirne, und lässt sich also womöglich herausrechnen. Die Effekte sind allerdings zum Teil auch vom Ort auf dem Bild abhängig.
Dazu kommt noch eine Verzerrung des Spektrums durch die nicht mehr zum Objektiv passenden Linsenkorrektur der Bildverarbeitungspipeline, die sich auch bei nur 64 Pixel Streifenhöhe wohl schon auswirkt.
Die Quasi-Spektren sind auch noch gar nicht in der Wellenlänge kalibriert. Die X-Achse zeight also pur die Pixelspalte auf dem Foto. Ich warte noch auf eine Osram Dulux EL Energiesparla … äh, Spektroskopkalibriergerät.
Ich hänge dennoch mal zur Anschauung die Quasi-Spektren einer der Loamlin-SK6812-5050-RGBW-LEDs an.
Außerdem ist der Aufbau aus Lego weiterhin nicht ausreichend stabil, zum Beispiel gegen Torsion. Auch die Fassung der Beugungsfolie ist derart, dass die Folie nicht wirklich plan bleibt.
Ich habe jetzt Energiesparlampen zur Kalibrierung des Spektrometers. Ein Python-Skript sucht im Spektralfoto der ESL die 436nm-, 546nm- und 611nm-Linien, approximiert deren Verläufe als Polynome 2. Grades, approximiert dann linear die Koeffizienten dieser Polynome in Abhängigkeit von der Horizontalposition, und berechnet daraus ein Deformationskorrekturgitter wie im angehängten Bild gezeigt. Danach wird in den deformationskorrigierten Spektren erneut nach den Spektrallinien gesucht und die Umrechnung zwischen Pixelspalte und Farbfrequenz ermittelt.
Ich erhalte so dann die angehängten Quasi-Spektrogramme für die Energiesparlampe und eine 70W Halogenbirne.
Für letztere zeige ich sieben Intensitätsverläufe als Ausschnitte aus demselben Spektralfoto in unterschiedlichen Spalthöhen, skaliert auf den Höchstwert des jeweiligen Intensitätsverlaufs. Ich habe das Beugungsgitter durch einen anderen Ausschnitt aus dem 15x30cm-Bogen ersetzt und das Sichtfenster stark verkleinert, so daß eine etwaiige Wölbung des Gitters sich stark reduziert haben sollte. Dennoch ist auch hier immer noch gut die seltsame „Streifigkeit“ erkennbar, die auch auf den Fotos mit der Nikon erkennbar waren.
Der nächste Schritt ist jetzt die Korrektur der Intensitäten über das Verhältnis zwischen der für die Halogenbirne ermittelten Spektralantworten und den bekannten (?) Spektralintensitäten einer Halogenbirne.
Ich habe Korrekturfaktoren ermittelt, die die Spektralantwort meines Geräts bei Beleuchtung mit einer 70W-Halogenbirne in ein Plancksches 3200K-Schwarzkörperspektrum entzerren, und wende diese Korrekturfaktoren an, um aus den besten 64-Pixel-hohen Streifen des Spektralfotos jetzt „echte“ (aber einheitslose) Spektrogramme zu generieren.
Anbei die Ergebnisse für a) vier Streifen aus dem Spektralfoto der 70W-Halogenbirne, b) einen Streifen der 8W-Energiesparlampe, c) jeweils einem Streifen der Spektren der R,G,B und W-LED der SK6812-RGBW-LED von Loamlin, d) dito für die SK6812-RGBW-LED von BTF, e) ein Vergleich des Loamlin-W-Spektrums mit dem der Halogenbirne, und f) dito für das BTF-W-Spektrum.
Bei a), b), e) und f) ist jedes Einzelspektrum so skaliert, dass die Durchschnittsluminanz der Fläche im Bereich zwischen 420nm und 640nm 1.0 ergibt.
Bei c) und d) zeigen die Einzelspektren die korrigierte aber ansonsten unskalierte Durchschnittsluminanz jeder entsprechenden Spalte im Streifen, so dass man die Intensitäten der LED-Spektren gegeneinander vergleichen kann.
Ich würde jetzt gerne aus den Spektrogrammen den CRI-Wert der W-LEDs von Loamlin und BTF ermitteln. Dazu sollte ich wohl zunächst aus dem Spektrogramm deren Farbtemperatur bestimmen, und dann den CRI-Wert aus der Different zum Schwarzkörperspektrum bei dieser Temperatur berechnen.
Kennt jemand die dazu nötigen Rechenschritte? Hier https://www.bs-ballasts.com/Workshop/N_Unzner/PDF/Lichtanalyse.pdf scheinen die Rechenwege gut erklärt, oder?
Die oben ermittelten Korrekturfaktoren waren fehlerhaft, weil ich für die spektrale Intensität des Schwarzkörpers das Infinitesimal der Frequenz anstatt der Wellenlänge berechnet hatte. Ich habe diesen Fehler jetzt korrigiert.
Ich erhalte mit dem o.g. Python-Paket jetzt erste „Quasi“ CRI- und Farbtemperaturangaben.
Die Luminanzen der PNG-Spektralfotos sind wohl im dort verwendeten sRGB-Farbraum nicht mehr linear (Stichwort Gammakorrektur), und das verfälscht die Spektren? Anstelle einer Rückrechnung überlege ich stattdessen direkt die RAW-Dateien des Sensors im DNG-Format verarbeiten. Für eine erste Analyse dieser Rohdaten benutze ich zur Zeit RawTherapee (http://rawtherapee.com) und Rawpi (https://pypi.org/project/rawpy). Allerdings widersprechen sich diese beiden Ansätze bezüglich der Luminosität der einzelnen Bayer-Pixel bisher, obwohl ich in RawTherapee die Farbinterpolation auf „keine“ stelle. Mmh …
Selbst im RAW-Spektralfoto sind die Streifen noch zu sehen. Ich möchte jetzt als Ursage die Qualität der Beugungsfolie ausschließen und habe also neue Beugungsfolien (und gleich noch diverse Achromaten und ein Handspektroskop) bei https://astromedia.de/ bestellt.
Anbei die Spektralantworten der rohen CCD-Pixel für die vier RGBG-Bayer-Farbfilter bei 70W-Halogenbirne. Die Wellenlänge der Beleuchtung der Pixels ist dabei aus dem Spektrallinienverlauf in der ESL-Aufnahme ermittelt.
Seltsam, dass sich die CCD-Antwort für die zwei Grünfilter leicht unterscheidet. Kann dieses Verhalten vielleicht durch das nicht-originale Objektiv und dessen anderen Chief Ray Angle erklärt werden? Aber warum tritt dieser Effekt dann nicht auch auf der anderen Seite des Bildes auf? Wo befindet sich der Bayer-Filter überhaupt – vor oder hinter den Mikrolinsen?
Untersuchung PiCam 1.3 (OVund M12-Objektive
Raspberry Pi Camera Module v1.3
- Sensor: OmniVision OV5647
- Sensor resolution: 2592 × 1944 pixels
- Sensor image area: 3.76 × 2.74 mm (diagonal is then 4.65mm)
- M12 adapter e.g. https://www.thingiverse.com/thing:539517
12mm ("25°")
- Length (tube): 13mm
- Front lens inset (from outmost point of lens to tube edge): 4mm
- Back lens inset (from outmost point of lens to tube edge): 2.2mm
- Front-focal distance (from tube edge): 4mm
- Back-focal distance (from tube edge): 7mm
- Front-focal distance (from outmost point of lens): 8mm
- Back-focal distance (from outmost point of lens): 9.2mm
- Lens (system) thickness: 6.8mm
- Aperture: ~5mm
This means we can consider this lens system as one 12mm focal lens resting at 8mm behind the front tube edge resp. 5mm in front of the back tube edge.
FoV
Picture taken with 12mm lens at a distance of 232mm from the lens tube front edge, i.e. 240mm from the virtual center of the 12mm lens. FoV width is 68.5mm = 16.3°, FoV height is 51.5mm = 11.9°, diagonal FoV is 20.1°.
Design
- Min. wavelength (nm): 390
- Max. wavelength (nm): 670
- Resolution (nm): 1
- Deviation from Littrow (degrees): 0
- Groove density (l/mm): 1000
- Magnification: 0.13
- Detector width (mm): 3.76
- Numerical aperture: 0.17 (focal length 12mm, opening 4mm → N=3; NA = 1/2N = 1/6 = 0.17)
- Slit width (um): 103.3
- Collimator focal l. (mm): 99.6
- Focusing focal l. (mm): 12.9
- Grating AOI (degrees): 15.4
- Diffr. angle ( 390 nm): 7.2
- Diffr. angle ( 530 nm): 15.4
- Diffr. angle ( 670 nm): 23.9
- Grating size (mm): 35.6
3D-Print
spektrometer.zip FreeCAD-Dateien für Körper und Deckel des Spektrometers, ausgelegt auf die PiCam 1.3 mit M12-Adapter und dem obigen M12-Objektiv mit 12mm Brennweite, ein 1000l/mm-Beugungsgitter (https://astromedia.de/Das-Durchlicht-Beugungsgitter-gross-1000), und https://astromedia.de/Opti-Media-Achromat-50 als Kollimator. Spektrometer01 hat eine 14mm Öffnung für das Objektiv, Spektrometer02 erlaubt die Schraubmontage der PiCam 1.3 mit M12-Adapter an der Gehäusewand.
spectro02b-nocoll Messergebnisse
- xxx.spectro02b-nocoll.awbg1.yyy.dng, SHP:(369.0, 666.0, 1.0)
- esl8w, 200ms: CRI:82.9951912483, CCT:1917.69521832
- halogen70w, 200ms: CRI:99.4474813203, CCT:3008.80897641
- b2-w255, 500ms: CRI:82.3428516625, CCT:3554.89167571
- l-w255, 500ms: CRI:78.0307590008, CCT:2589.40114975
- sun-dim, 1s: CRI:97.1256645918, CCT:5935.08904576
- sun-dim-stegplatte-unilux, 1s: CRI:82.4329530983, CCT:6377.63908505
3D-Print Spectro04
- campcbthickness 1.0→1.2
- camwidth 25.0→25.6
- camheight 24.0→24.6
- overlap between body and lid → remove body part rising from half height to top
- camlcwasherdia + 1mm
- remove lid top cam cover between the to slots to allow cable run
- give camera more room in lid generally
- tilt top and bottom grating and diffusor slits to ease entry
- increase slit screw hole to 2.2mm such that M3 can be cut straight away
- add mounting holes for raspizero
- mounting picam upside-down cuts into red area until 643nm. Seems the sensor itself is slightly tilted? increase diffraction angle again, possibly to something BIGGER that the calculated 15.4°.
- increase slit wall size to improve slit screw tightness
- increase opposite slit blade ridge slightly (0.6?)
- produce washers that protrude more onto slit blades
spectro04b Messergebnisse
- xxx.spectro02b-nocoll.awbg1.yyy.dng, SHP:(390.0, 642.0, 1.0)
- b20-w255, 1s: CRI:85.9034215468, CCT:3131.1124742
- b-w255, 1s: CRI:87.0508662918, CCT:3478.61844897
- b40-w255, 1s: CRI:86.7221149838, CCT:3193.60480905
- b30-w255, 1s: CRI:85.9157843505, CCT:3113.79070282
TODO
- Gehäuse in bestem Winkel, Stabilitätselemente, Aufnahme Diffusorfolie
- Gehäuse inclusive RasPi Zero W, potentiell Akkus?, evtl. Touch-Display? Auslösen einer Messung durch Bedienknopf?
- Effekt Kollimator – wird das Spektrum dadurch scharf? Wie groß ist die Dämpfung im Violett wirklich?
- Scharfstellen auf Fraunhoferlinien?
- Die zur Kalibrierung verwendete Halogenbirne könnte einen UV-Stop enthalten, also unter ca. 430nm NICHT einem schwarzen Strahler entsprechen. Diese Vermutung kommt daher, dass das dagegen kalibrierte Spektrum des Sonnenlichts im diesem Blau-Violettbereich seltsam unstetig erscheint.
Referenzen
- TCD1304AP (https://www.ebay.de/itm/394814910832)
- C12666MA von Hamamatsu