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. Durch das keramische Basismaterial führen zwei externe Metallkontakte des Widerstands zur lichtempfindlichen Membran, dessen Widerstand abhängig von der Geometrie und den Materialeigenschaften ist. Da lichtempfindliches Material durch die schmale, kurvige Spur zwischen den Elektroden bereits einen hohen Widerstand hat, kann der niedrigste totale Widerstand schon bei durchschnittlichen Lichtintensitäten erreicht werden. Der Fotowiderstand reagiert ähnlich dem menschlichen Auge 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 abgebildet, welche vereinfacht die Wellenlängen des sichtbaren Lichts mit den entsprechenden Farben darstellt:
| Farbe | Wellenlängen (nm) |
|---|---|
| Violett | 400 – 450 |
| Blau | 450 – 500 |
| Grün | 500 – 570 |
| Gelb | 570 – 590 |
| Orange | 590 – 610 |
| Rot | 610 – 700 |
Der Fotowiderstand arbeitet innerhalb eines bestimmten, festgelegten Temperaturbereichs. Soll der Sensor bei anderen Temperaturen genutzt werden, müssen präzise Umrechnungen durchgeführt werden, da die Widerstandseigenschaften des Sensors abhängig von der Umgebungstemperatur sind.
Zur Kennzeichnung der Lichtintensität wird die Beleuchtungsstärke (E) genutzt. Diese zeigt die Menge Licht an, die auf eine bestimmte Oberfläche trifft. Die Maßeinheit ist Lux (lx), wobei 1 Lux dem konstanten Lichtfluss von einem 1 Lumen entspricht, welcher auf eine Oberfläche von 1m² strahlt. In der Realität fällt Licht jedoch eigentlich nie gleichmäßig auf eine Oberfläche weshalb die Beleuchtungsstärke meistens als Durchschnittswert ermittelt wird. Unten sind ein paar Beispiele von Beleuchtungsstärken dargestellt:
Vergleichswerte von Beleuchtungsstärken:
| Umgebung | Beleuchtungsstärke (lx) |
|---|---|
| Vollmond | 0,1 |
| Abenddämmerung | 1 |
| Auditorium | 10 |
| Klassenraum | 30 |
| Sonnenaufgang / -untergang | 400 |
| OP-Saal (Krankenhaus) | 500 - 1000 |
| direktes Sonnenlicht | 10000 |
Das Sensormodul aus dem HomeLab verfügt über einen VT935G Fotowiderstand. Ein Pin des Widerstands ist an der +5 V Stromversorgung angeschlossen, der zweite an Kanal 1 (Pin PF1) des ADC. Zwischen diesem Pin und der Masse ist ein 10 kΩ Widerstand angeschlossen, welcher zusammen mit dem Fotowiderstand einen Spannungsteiler erzeugt. Da sich der elektrische Widerstand des Fotowiderstands mit einfallender Lichtintensität verkleinert, wird die gemessene Spannung am Pin des Mikrocontrollers mit dem Ansteigen der Lichtstärke größer. Hierbei sollte bedacht werden, dass der Fotowiderstand des HomeLab am stärksten auf oranges und gelbes Licht reagiert.
Der Sensor VT935G ist nicht als spezifisches Messinstrument gedacht. Er soll vielmehr dazu dienen, Informationen über die allgemeinen Lichtverhältnisse (z. B. befindet sich eine eingeschaltete Lampe im Raum oder nicht) anzugeben. Dazu muss nur der Widerstand des Sensors in einem halbdunklen Raum gemessen und ins Programm eingetragen werden. Daraufhin kann man die gemessenen Werte vergleichen und feststellen ob es heller oder dunkler ist.
Die folgende Aufgabe hier ist ein wenig komplexer, da die Beleuchtungsstärke in Lux gemessen wird. Hierzu gibt es eine Annäherungsformel und Gleitkomma-Variablen. In C-Sprache sind Gleitkomma-Variablen float- und double--Typ Variablen, welche zur Darstellung von Brüchen genutzt werden können. 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); } }