Ich experementiere gerade mit Leds als Lichtsensoren. Ich habe mich an
dem Artikel aus dem Wiki gehalten.
Mein Aufbau:
-Arduino Nano auf dem Steckbrett mit USB und Atmega328P
-Led mit Vorwiderstand hängt zwischen PB0 und PB1, wobei die Anode an
PB0 hängt
-CPU-Takt 16MHZ
Nun habe ich ein kleines Testprogramm geschrieben, um mal zu schauen wie
die Leds, dich ich hier so rumliegen habe, als Lichtsensor
funktionieren. Habe rote, blaue, gelbe und grüne probiert, bekomme aber
immer den selben Wert bei meiner Zeitmessung. Egal ob dunkel oder hell.
Selbst wenn ich die Led vom Steckbrett entferne, kommt der selbe
Messerwert raus. Ich lasse mir diesen per UART an den PC senden. Sind
immer 0.1ms.
Das Programm läuft interruptgestuert ab. Zuerst soll die Led in
Sperrichtung 10ms geladen werden. Danach stell ich den PIN PB1 auf
Eingang um, damit der Strom abfließen kann und messe die Zeit. Hier
komme ich immer auf 0.1ms.
das kommt mir doch arg wenig vor.
Vielleicht habe ich einen Fehler im Code oder sonst einen Denkfehler.
Ich würde mich freuen, wenn mir jemand auf die Sprünge helfen könnte.
Juli
ehe du den Timer erneut startest, den Timer auf 0 zurück setzen und
eventuell in der Zwischenzeit aufgelaufene Overflow Compare Interrupts
löschen.
1
....
2
measure=1;
3
TCNT0=0;// Timer auf 0
4
GTCCR|=(1<<PSRSYNC);// Prescaler resetten
5
TIFR0=(1<<OCF0A);// aufgelaufene Compares löschen
6
TCCR0B|=(1<<CS00)|(1<<CS01);// Timer starten
7
....
Allerdings: einen Wert von minimum 0.1 wirst du immer haben. Denn so wie
du misst, musst du mindestens einmal in die Compare-Interrupt Routine
rein. Selbst wenn da die Messung gleich als beendet erklärt wird, weil
der Pin schon abgefallen ist. Teil der ISR ist aber das Hochzählen
deiner Zehntelmillisekunden. Bei einem Startwert von 0 ergibt das dann
natürlich 1.
>Leds als Lichtsensoren
Ja, gute LEDs können als Sensor arbeiten.
Es entsteht eine Spannung bei Beleuchtung, an hochohmigem Widerstand.
Man kann das auf einen A/D Eingang geben.
Aber man braucht nichts "aufladen" und umschalten dabei.
Gruss
Karl Heinz schrieb:> Du solltest hier> ehe du den Timer erneut startest, den Timer auf 0 zurück setzen und> eventuell in der Zwischenzeit aufgelaufene Overflow Compare Interrupts> löschen.>
Danke für den Hinweis. Das hatte ich nicht bedacht. Leider hat dies
keine Änderung bewirkt.
>> Allerdings: einen Wert von minimum 0.1 wirst du immer haben. Denn so wie> du misst, musst du mindestens einmal in die Compare-Interrupt Routine> rein. Selbst wenn da die Messung gleich als beendet erklärt wird, weil> der Pin schon abgefallen ist. Teil der ISR ist aber das Hochzählen> deiner Zehntelmillisekunden. Bei einem Startwert von 0 ergibt das dann> natürlich 1.
Genau. 0.1ms habe ich immer als Ausgabe, wenn die Messung kleiner ist.
Demzufolge müsste ich noch feiner messen, oder? Scheinbar entläd sich
die Led schneller. Kann das sein? Im Wiki wird alle 5ms gemessen, sodass
ich davon ausging, dass die Entladung schon länger benötigen wird.
kommt mir aus dem Bauch raus seltsam vor.
Willst du nicht eigentlich die Messung beenden, wenn der Pin von 1 auf 0
wechselt?
D.h. die Messung ist beendet, wenn der Pin auf 0 gegangen ist. Du
beendest die Messung aber, wenn der Pin auf 1 ist.
Karl Heinz schrieb im Beitrag #4006543:
> Das hier>
1
>ISR(TIMER0_COMPA_vect)
2
>{
3
>...
4
>if(PINB&(1<<PINB1)&&measure)
5
>...
6
>
> kommt mir aus dem Bauch raus seltsam vor.>> Willst du nicht eigentlich die Messung beenden, wenn der Pin von 1 auf 0> wechselt?
Genau das möchte ich messen. Ich muss ehrlich zugeben, dass ich dies aus
dem Bsp.-Code aus dem Wiki angepasst habe
Juli V. schrieb:> Karl Heinz schrieb im Beitrag #4006543:>> Das hier>>
1
>>ISR(TIMER0_COMPA_vect)
2
>>{
3
>>...
4
>>if(PINB&(1<<PINB1)&&measure)
5
>>...
6
>>
>> kommt mir aus dem Bauch raus seltsam vor.>>>> Willst du nicht eigentlich die Messung beenden, wenn der Pin von 1 auf 0>> wechselt?>> Genau das möchte ich messen. Ich muss ehrlich zugeben, dass ich dies aus> dem Bsp.-Code aus dem Wiki angepasst habe
Dann musst du das aber auch so machen: Die Messung wird als beendet
erklärt, wenn der Pin auf 0 gewechselt hat. Solange er 1 ist,
interessiert das nicht weiter.
Juli V. schrieb:> Ich muss ehrlich zugeben, dass ich dies aus> dem Bsp.-Code aus dem Wiki angepasst habe
Im Wiki steht
1
while(PINB&(1<<PIN3)&&(entladezeit!=0xff)){
2
++entladezeit;
3
_delay_ms(5);
4
}
d.h. hier läuft die Zeit solange, solange der Pin auf 1 ist.
Du hast aber bei dir die Logik umgedreht. Dich interessiert nicht, wie
lange du noch weiter messen musst, sondern in deinem Programm kommt es
darauf an, wann die Messung zu beenden ist. Daher dreht sich dann die
Port-Pin Bedingung logischerweise bei dir um.
Juli V. schrieb:> Karl Heinz schrieb im Beitrag #4006543:>> Das hier>>
1
>>ISR(TIMER0_COMPA_vect)
2
>>{
3
>>...
4
>>if(PINB&(1<<PINB1)&&measure)
5
>>...
6
>>
>> kommt mir aus dem Bauch raus seltsam vor.>>>> Willst du nicht eigentlich die Messung beenden, wenn der Pin von 1 auf 0>> wechselt?>> Genau das möchte ich messen. Ich muss ehrlich zugeben, dass ich dies aus> dem Bsp.-Code aus dem Wiki angepasst habe
Ups. Da fehlt wo ein !
1
...
2
if(!(PINB&(1<<PINB1))&&measure)
3
...
Hab es mal geändert. Jetzt läuft es ganz schön lange XD. Selbst nach 10s
ist die Messung noch nicht fertig. Komisch
Karl Heinz schrieb:> Juli V. schrieb:>>> Ich muss ehrlich zugeben, dass ich dies aus>> dem Bsp.-Code aus dem Wiki angepasst habe>> Im Wiki steht>
1
>while(PINB&(1<<PIN3)&&(entladezeit!=0xff)){
2
>++entladezeit;
3
>_delay_ms(5);
4
>}
5
>
> d.h. hier läuft die Zeit solange, solange der Pin auf 1 ist.>> Du hast aber bei dir die Logik umgedreht. Dich interessiert nicht, wie> lange du noch weiter messen musst, sondern in deinem Programm kommt es> darauf an, wann die Messung zu beenden ist. Daher dreht sich dann die> Port-Pin Bedingung logischerweise bei dir um.
Stimmt genau. Man sollte immer genau schauen, was man sich kopiert O:-)
Danke für den Hinweis. Das ist nun behoben.
Tada. Danke für deine Hilfe.
Ich habe jetzt meine Messung gemacht. Die längste dauet knapp 12s. Ich
poste später nochmal das komplette Programm, falls jemand ebenfalls dies
ausprobieren möchte.
Erich schrieb:>>Leds als Lichtsensoren>> Ja, gute LEDs können als Sensor arbeiten.> Es entsteht eine Spannung bei Beleuchtung, an hochohmigem Widerstand.> Man kann das auf einen A/D Eingang geben.>> Aber man braucht nichts "aufladen" und umschalten dabei.>> Gruss
Bitte informiere dich nochmal genauer. Hier im Wiki
http://www.mikrocontroller.net/articles/Lichtsensor_/_Helligkeitssensor
findest du unter LED informationen dazu, wie man eine LED ganz einfach
mit normalen Vorwiderstand als Lichtsensor missbrauchen kann.
>Bitte informiere dich nochmal genauer.
Ob dein Zauber geht, kann ich nicht sagen.
Was geht ist das hier:
http://www.eeweb.com/blog/extreme_circuits/using-led-as-a-light-sensor
Es hat den Nachteil, daß es sofort arbeitet.
Ohne 12 Sekunden warten zu müssen.
In Bruchteilen von uS oder ns, eben wie schnell du den Ausgang mit
Comparator oder uC/AD in der Lage bist auszuwerten.
Die Lichtgeschwindigkeit ist hoch.
Gruss
Erich schrieb:>>Bitte informiere dich nochmal genauer.>> Ob dein Zauber geht, kann ich nicht sagen.
Doch. Der funktioniert.
Allerdings: die 12 Sekunden sind unegwöhnlich. Das sollte wesentlich
schneller gehen. Da stimmt was in der Hardware nicht, würde ich mal
sagen.
Erich schrieb:> Ob dein Zauber geht, kann ich nicht sagen.> Was geht ist das hier:> http://www.eeweb.com/blog/extreme_circuits/using-led-as-a-light-sensor>> Es hat den Nachteil, daß es sofort arbeitet.
Außerdem auch die Nachteile, dass es:
- einen OpAmp braucht
- ggf. eine separate Versorgung
- ein Häufchen Bauteile
- und ist stark nichtlinear, wobei es sich der Vorteil einer
exponentiellen Kennlinie einer Diode zum logarithmieren nicht nutzen
lässt...
Wenn man z.B. nur wissen will, ob man die Hintergrundbeleuchtung der
LCD-Anzeige einschalten soll ist das ein Overkill... ;-)
Gruß!
Marek
Erich schrieb:>>Bitte informiere dich nochmal genauer.> Was geht ist das hier:> http://www.eeweb.com/blog/extreme_circuits/using-l...>> Es hat den Nachteil, daß es sofort arbeitet.> Ohne 12 Sekunden warten zu müssen.> In Bruchteilen von uS oder ns, eben wie schnell du den Ausgang mit> Comparator oder uC/AD in der Lage bist auszuwerten.
Bist wirklich so oder willst du nur trollen? Diese Schaltung hat bei den
typ. 50pF LED-Kapazität eine Zeitkonstante von 1,5ms!
Karl Heinz schrieb:> Erich schrieb:>>>Bitte informiere dich nochmal genauer.>>>> Ob dein Zauber geht, kann ich nicht sagen.>> Doch. Der funktioniert.>> Allerdings: die 12 Sekunden sind unegwöhnlich. Das sollte wesentlich> schneller gehen. Da stimmt was in der Hardware nicht, würde ich mal> sagen.
Das lag scheinbar an der Led(rote). Hab mal Messungen mit anderen Leds
gemacht.
Meine Messung:
rote Led - dunkel 2.8s
rote Led - Tageslicht(stark bewölkt) 2.286s
rote Led - Schreibtischlampe an 1.726s
grüne Led - dunkel 1.649s
grüne Led - Tageslicht(stark bewölkt) 0.171s
grüne Led - Schreibtischlampe an 0.17s
blaue Led - dunkel 6.72s
blaue Led - Tageslicht(stark bewölkt) 1.878s
blaue Led - Schreibtischlampe an 0.022s
gelbe Led - dunkel 1.7s
gelbe Led - Tageslicht(stark bewölkt) 0.07s
gelbe Led - Schreibtischlampe an 0.01s
Auffälig war, je dunkler es war, desto größer die Messunterschiede.
Wobei die rote ein sehr diffuse Verhalten gezeigt hat->also nicht
geeignet wäre
>ein Häufchen Bauteile
Man kann die LED auch direkt an den uC Eingang anschliessen.
Falls dessen Eingangswiderstand definiert ist und nach Gnd geht.
Oder eben einen 2M2 dort anschliessen.
Natürlich ist dann der Hub (die max. Spannung) geringer.
Oder 'nen Buffer Type "HCU" (74hcu04) verwenden, dann kann's hochohmig
bleiben.
>eine Zeitkonstante von 1,5ms
Der 30 MOhm ist der Arbeitswiderstand.
Siehe Hinweis oberhalb.
Ausserdem wird sich die Helligkeit nicht in jedem Meßschritt von ganz
dunkel auf ganz hell ändern.
Die "Zeitkonstante" ist bei Verwendung eines uC sowieso Kappes.
@ Juli V.
>dunkel>Schreibtischlampehttp://de.wikipedia.org/wiki/Lichtst%C3%A4rke_%28Photometrie%29
Gruss
Juli V. schrieb:> Das lag scheinbar an der Led(rote). Hab mal Messungen mit anderen Leds> gemacht.>> Meine Messung:
Da ich gerade auch an etwas Ähnlichem rumtüftle, ich versuche aus den
Messungen an den drei Chips von RGB-LEDs Farbinformationen zu gewinnen,
wundere ich mich sehr über Deine rote LED. Generell werden ja rote LEDs
sogar für solche Anwendungen empfohlen, und bei mir sind die Zeiten, bei
der roten LED deutlich kürzer, als bei den Grünen und Blauen. Bei
Tageslicht habe ich, an der Roten, ca. 0,01 Sekunden, bei Dunkelheit
sind die Zeiten deutlich höher, und liegen teilweise im Sekundenbereich.
Da ich bei mir 8 RGB-LEDs am Controller habe, also 24 LED-Chips, fällt
auf, daß die Exemplarstreuungen riesig sind. Bei mir sind allerdings die
Roten LED-Chips die besten, was die Stabilität der Messungen anbelangt.
Bei Grün und Blau variieren die Ergebnisse stark, selbst bei konstanten
(Licht-)Verhältnissen. Daß das bei längeren Zeiten instabiler wird, ist
prinzipbedingt. Erstens ändert sich die Spannung langsamer, die mit der,
eher unsicheren, Schaltschwelle des Portpins verglichen wird, zweitens
haben störende Einflüsse, wie z.B. Leckströme, mehr Einfluß.
Bei einem anderen Projekt, was aber auch mit solchen Messungen arbeitet,
konnte ich die Qualtät der Messungen, durch eine Abwandlung des
Verfahrens, deutlich verbessern. Dort lade ich die LEDs auch in
Sperrrichtung, schalte dann den einen Pin auf Eingang, warte eine feste,
definierte Zeit, und messe dann die Spannung an diesem Pin per internem
A/D-Wandler. Die Messzeit ist dabei recht kurz.
Mit freundlichen Grüßen - Martin
Die Leds mit denen ich die Messung gemacht habe sind alles
Low-Current-Leds. Habe jetzt fünf verschiedene rote Leds probiert und
bei allen ist keine sinnvolle Messung durchzuführen. Warum auch immer.
Die anderen Farben scheinen sich in diesem Fall besser zu eignen. Habe
aber gerade nur diese zur Hand, sodass ich nicht noch mehr Messungen
machen kann.
Ich werde bei der nächsten Elektronikbestellung neue Leds für dieses
Experiment ordern. Vielleicht sind die Ergebnisse dann besser.
Im Anhang noch der komplette Code. Vielleicht kann das jemand
gebrauchen.
Martin Schlüter schrieb:> Nimm keine 'Low Current', da ist der Chip oft kleiner -> Weniger> sensitive Fläche, nimm was 'Superhelles'.>> Mit freundlichen Grüßen - Martin
Ok. Wenn ich welche habe(muss erst welche kaufen), dann werde ich
nochmal meine Ergebnisse posten. Habe mir das schon gedacht.
Danke auch für deinen informativen Beitrag. Die Messung ohne ADC ist bei
mir vollkomen ausreichend, aber vielleicht benötige ich mal genauere
Werte, dann habe ich die Idee schonmal im Hinterkopf. Ich möchte nur
wissen, ob Tag, Dämmerung oder Nacht ist, um die Helligkeit meiner
Anzeige anzupassen.
Für diese Anwendung sollte das locker reichen, man hat ja auch Zeit,
könnte also den Mittelwert vieler Messungen verwenden. Vielleicht sogar
einen Tiefpass nachbilden, dann fährt die Anzeige 'weich' auf die
passende Helligkeit. Sprunghafte Änderungen können da durchaus nerven.
Bei Anzeige käme mir die Idee, nicht leuchtende Segmente, oder
unbenutzte Dezimalpunkte zur Messung zu 'missbrauchen'.
Mit freundlichen Grüßen - Martin
Hallo Juli,
für einen Roboter habe ich als Liniensensor mal zwei LEDs benutzt:
http://www.hobby-roboter.de/forum/viewtopic.php?f=4&t=133&
Ich kann Deine Beobachtung bestätigen, es ist tatsächlich so, dass bei
sehr schwacher Beleuchtung die Integrationszeit in den Sekundenbereich
geht.