This is an old revision of the document!
Notwendiges Wissen: [HW] Sensors Module, [HW] lcd, [ELC] Voltage Divider, [AVR] Analog-to-digital Converter, [LIB] Analog to Digital Converter, [LIB] Alphanumeric LCD, [PRT] Installation instructions for Windows
Ein Fotowiderstand ist ein Sensor, dessen elektrischer Widerstand sich je nach einfallender Lichtintensität verändert. Je intensiver das Licht ist, desto mehr freie Ladungsträger werden gebildet, und umso geringer wird dadurch der Widerstand des Bauteils. Zwei externe Metallkontakte des Widerstands reichen durch das keramische Basismaterial zur lichtempfindlichen Membran, dessen Widerstand abhängig von der Geometrie und den Materialeigenschaften ist. Da lichtempfindliches Material mit der schmalen, kurvigen Spur zwischen den Elektroden selbst bereits einen hohen Widerstand hat, kann der niedrigste totale Widerstand schon bei durchschnittlichen Lichtintensitäten erreicht werden. Ähnlich zum menschlichen Auge, reagiert der Fotowiderstand nur auf bestimmte Wellenlängen, was bei der Auswahl eines solchen Bauteils bedacht werden muss. Andernfalls kann es vorkommen, dass der Widerstand nicht auf die in der Anwendung genutzte Lichtquelle reagiert. Nachfolgend ist eine Tabelle dargestellt, welche vereinfacht die Wellenlängen des sichtbaren Lichts unterteilt nach den entsprechenden Farben zeigt: :
| Farbe | Wellenlängen (nm) |
|---|---|
| Violett | 400 – 450 |
| Blau | 450 – 500 |
| Grün | 500 – 570 |
| Gelb | 570 – 590 |
| Orange | 590 – 610 |
| Rot | 610 – 700 |
Es gibt einen bestimmten Temperaturbereich für einen Fotowiderstand. Wenn man den Sensor bei anderen Temperaturen nutzen will, müssen präzise Umrechnungen gemacht werden, da die Widerstandseigenschaften des Sensors abhängig von der Umgebungstemperatur ist.
Um Lichtintensität zu bemessen wird die Beleuchtungsstärke (E) genutzt, diese zeigt die Menge an Licht die eine bestimmte Oberfläche erreicht. Die Messeinheit ist Lux (lx), wobei 1 lux der konstante Lichtfluss von einem 1 Lumen entspricht, welcher auf eine Fläche von 1m² einstrahlt. In der Realität fällt jedoch Licht kaum gleichmäßig auf eine Oberfläche und daher ist die Beleuchtungsstärke meistens ein Durchschnittswert. Unterhalb sind ein paar Beispiele von Beleuchtungsstärken:
Werte von Beleuchtungsstärken zum Vergleich:
| Umgebung | Beleuchtungsstärke (lx) |
|---|---|
| Vollmond | 0,1 |
| Abenddämmerung | 1 |
| Auditorium | 10 |
| Klassenraum | 30 |
| Sonnenaufgang | 400 |
| OP (Krankenhaus) | 500 - 1000 |
| direktes Sonnenlicht | 10000 |
Das Sensor-Modul von HomeLab hat einen VT935G Fotowiderstand. Ein Pin des Widerstands ist am +5 V angeschlossen der zweite an Kanal 1 (Pin PF1) des ADC. Zwischen diesem Pin und der Erde ist ein 10 kΩ angeschlossen, welcher einen Spannungsteiler mit dem Fotowiderstand erzeugt. Da der elektrische Widerstand des Fotowiderstands sich mit der Lichtintensität verkleinert, wird die gemessene Spannung am Pin des Microcontrollers mit dem Ansteigen der Lichtstärke größer. Man sollte bedenken, dass der Fotowiderstand im HomeLab am meisten auf orangefarbenes und gelbes Licht reagiert.
Der Sensor VT935G sollte kein spezifisches Messinstrument sein. Es ist mehr ein Gerät, welches die allgemeinen Lichtverhältnisse angibt - Gibt es eine Lampe im Raum oder nicht. In diesem Fall müsste man nur den Widerstand des Sensors in einem halb-dunklen Raum messen, dies in ein Programm eintragen und die gemessenen Werte vergleichen - ist es heller oder dunkler.
Die Aufgabe hier, ist ein wenig komplexer, da die Beleuchtungsstärke in Lux gemessen wird. Dafür gibt es eine Annäherungsformel und Gleitkomma-Variablen. In C-Sprache sind Gleitkomma-Variablen float- und double--Typ Variablen, welche genutzt werden können um Brüche darzustellen. Der Nachteil ist ein erhöhtes Nutzen von Ressourcen. Computer haben spezielle Hardware um Gleitkomma-Variablen zu berechnen, in den 8-Bit AVR Microcontrollern wird die Berechnung von Software gemacht, was viel Zeit und Speicher benötigt. Falls die Nachteile nicht kritisch sind, sind Gleitkomma-Variablen es aber wert, genutzt zu werden.
Es gibt eine Annäherungsformel für den Zusammenhang zwischen Beleuchtungsstärke und elektrischen Widerstand im Datenblatt des Sensors. Wie man im Graphen (rechts) sieht, in einer logarithmischen Skala, ist der Widerstand und die Beleuchtungsstärke fast linear abhängig, und bilden eine Lineare Funktion auf Grund der folgenden Konversion:
log(a/b) = log(a) - log(b)
Die Relation wird durch das Steigen des Faktor Y charakterisiert, welcher 0,9 für den VT935G Sensor ist. Wir haben auch Daten für einen Punkt auf der Linie: Widerstand 18.5 kΩ (RA) bei 10 lx Beleuchtungsstärke (EA). Daher haben wir die Koordinaten von einem Punkt und die Steigung der Gerade, daher können wir jeden anderen Punkt berechnen. D.h. wenn der Widerstand (RB) am Sensor gemessen wird, ist es möglich die Beleuchtungsstärke EB) mit der Formel der Geraden zu berechnen. Finden von EB mit der Geraden-Formel:
log(EB) = log(RA/RB) / γ + log(EA)
EB = 10log(RA/RB) / γ + log(EA)
Dies gibt uns die Formel um die Beleuchtungsstärke zu berechnen, wenn der Widerstand gegeben ist. Der Widerstand kann nicht direkt von Microcontroller gemessen werden. Dafür ist der Fotowiderstand in einem Spannungsteiler. Die Output-Spannung des Spannungsteilers wird vom ADC zu einer spezifischen Variable konvertiert. Um den Widerstand zu finden, muss die Output-Spannung vom (U2) Spannungsteiler zuerst berechnet werden, mit dem ADC Wert. Man muss auch die Vergleichs-Spannung vom Konverter berücksichtigen. Die Formel ist Folgende:
U2 = Uref * (ADC / 1024)
Aus der Formel für Spannungsteiler (siehe Kapitel über Spannungsteiler) kann der Widerstand des Fotowiderstands (R1) gefunden werden:
R1 = (R2 * U1) / U2 - R2
In der folgenden Berechnung von Spannung und Widerstand, werden die gegebenen Werte eingetragen und die Indizes entfernt:
U = 5 * (ADC / 1024)
R = (10 * 5) / U - 10
Um die Beleuchtungsstärke des Lichts zu finden, kann eine vereinfachte Konversion genutzt werden:
E = 10log(18.5/R) / 0.9 + 1 = 10log(18.5/R) * 10/9 * 101 =
= 10log18.5*10/9 - logR*10/9 * 10 = (10log18.5*10/9 / 10logR*10/9) * 10 =
= (18.510/9 / R10/9) * 10 = 18.510/9 * 10 * R-10/9
Durch Berechnen der Konstante vor der Variable des Felds R, bleicht folgender Ausdruck:
E = 255,84 * R-10/9
Diese Formeln helfen nur, wenn man ein Fotowiderstand des HomeLab Sensor-Moduls nutzt. Falls ein Schaltkreis mit anderen Komponenten genutzt wird, müssen die Variablen verändert werden. Es folgt ein Quellcode eines Beispielprogramms, welches die Beleuchtungstärke misst, mit dem ADC berechnet und die Beleuchtungsstärke am LCD darstellt. Bevor das Programm kompiliert wird, müssen die Einstellungen für die Gleitkomma-Variablen in das Projekt geschrieben werden. Wie das funktioniert, wird im Kapitel über die Softwareinstallation erklärt.
Im Beispielprogramm werden Variablen für die Spannung, Widerstand und Beleuchtungsstärke als double Gleitkomma-Variablen definiert. Die Variablen, welche nun als Gleitkomma-Variablen genutzt werden, müssen nun immer ein Dezimalpunkt enthalten (es geht auch einfach 0, da der Kompiler es korrekt versteht). Wenn man sprintf nutzt um die Gleitkomma-Variable zu Text konvertiert, muss man “%f” Format nutzen. Dies kann man durch Integer und Dezimalstellen erweitern. Z.B.: “%3.2”, welches nun immer 3 Integer und 2 Dezimalstellen angibt. In the example program variables of voltage, resistance and intensity are defined using type
// // The example program of the photoresistor of the module of sensors of the HomeLab // Approximate value of the intensity of light is displayed on the LCD. // #include <stdio.h> #include <math.h> #include <homelab/module/lcd_alpha.h> #include <homelab/adc.h> #include <homelab/delay.h> // // Main program. // int main(void) { char text[16]; unsigned short adc_value; double voltage, resistance, illuminance; // Initializing the LCD lcd_alpha_init(LCD_ALPHA_DISP_ON); // Clearing the LCD. lcd_alpha_clear(); // Name of the program lcd_alpha_write_string("Luxmeter"); // Setting the ADC adc_init(ADC_REF_AVCC, ADC_PRESCALE_8); // Endless loop. while (true) { // Reading the average value of the photoresistor adc_value = adc_get_average_value(1, 10); // Calculating the voltage in the input of the ADC voltage = 5.0 * ((double)adc_value / 1024.0); // Calculating the resistance of the photoresistor in the voltage divider resistance = (10.0 * 5.0) / voltage - 10.0; // Calculating the intensity of light in lux illuminance = 255.84 * pow(resistance, -10/9); // Converting the intensity of light to text sprintf(text, "%0.1f lux ", illuminance); // Displaying it on the LCD lcd_alpha_goto_xy(0, 1); lcd_alpha_write_string(text); // Delay 500 ms sw_delay_ms(500); } }