PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : AT90S2343: LED als Blinklicht und Lichtsensor



Radio Eriwan
07.11.2005, 13:46
Moin alle,

ich habe ein 'kleines' Problem und bräuchte dabei mal Eure Hilfe:

Vor ein paar Tagen habe ich im Internet einen sehr interessanten Artikel darüber gelesen, wie man eine LED am µ-Controller als Signalindikator (Blinken, Dauerlicht) und 'gleichzeitig' als Lichtsensor benutzen kann (siehe Link 1 (http://www.merl.com/projects/LEDcomm/) und Link 2 (http://www.merl.com/reports/docs/TR2003-35.pdf)).

Wie sie zum Leuchten gebracht wird, ist klar - als Sensor wird sie benutzt, in dem man einfach nur ihre lichtabhängige Kapazität mißt. Dazu wird die LED in Sperrrichtung an +Ub gelegt, und danach über den normalen Strombegrenzungswiderstand entladen. Die Zeit, die sich daraus ergibt, ist ein Maß für die lichtabhängige Kapazität.

Zur Verdeutlichung dazu folgendes Bild:

http://img330.imageshack.us/img330/6749/led3kr.gif

Aus dem PDF-Dokument bzw. den darin enthaltenen Oszillogrammen habe ich entnommen, daß eine Meßperiode von 100 µs ausreichen sollte, um festzustellen, ob die LED angeleuchtet wird oder nicht.

Ich bin, was die Atmel-Programmierung angeht, noch blutiger Anfänger, habe aber trotzdem mal probiert, in AVR-Basic ein kleines Programm dafür zu schreiben (siehe Anhang). Als µ-Controller habe ich den AT90S2343 genommen, da ich davon noch einen übrig habe.

Das Grundgerüst ist relativ einfach und noch nicht optimiert, das Programm macht folgendes:

- die LED blinkt drei mal kurz, einmal lang als Indikator für den Programmstart und die bevorstehende Messung
- jetzt folgt 1 s Pause (LED dunkel), dann die Messung
- nun blinkt die LED drei mal kurz und signalisiert das Ende der Messung
- jetzt wird das Ergebnis der Messung ausgegeben: Ein mal lang blinken -> LED wurde angeleuchtet oder zwei mal lang blinken -> LED wurde nicht angeleuchtet

Bei der Messung gehe ich wie folgt vor: Ich schalte die LED in Sperrrichtung an +Ub, warte 1 ms (zwecks 'Aufladen' ihrer Kapazität) und starte dann Timer0. Wenn dieser überläuft (nach ca. 255 µs), verzweige ich in eine Unterroutine, in der der eine Ausgang auf Eingang umgeschaltet und dann abgefragt wird. Aus der Unterroutine kommend, wird mir der Zustand des Einganges nun per LED ausgegeben.

So weit, so gut. Das Problem dabei ist, es ändert sich nichts. Der Eingang bleibt laut Messung immer auf '1'.

Was mache ich falsch und wie mache ich es richtig?

Ich freue mich auf Eure Antworten und bin für jeden Hinweis dankbar!

Viele Grüße,

Radio Eriwan


'
$regfile = "2343DEF.dat"
$crystal = 1000000
'
Dim A As Byte
Dim An_oder_aus As Bit
'
Config Timer0 = Timer , Prescale = 1 'Timer0 als Timer konfigurieren
Stop Timer0 'Timer0 wieder anhalten, da er bei Konfiguration gleich gestartet wird
Timer0 = 0 'Timer0 auf '0' setzen - Tcnt0 soll auch gehen!?
On Timer0 Tim0_isr 'Bei Überlauf (>255) zu Tim0_isr springen
Enable Timer0 'Timer-Interrupt einschalten
Enable Interrupts 'Interrupt-Handling einschalten
'
Config Portb = &B00000000 'Grundzustand einstellen -> alle Pins als Eingänge
Portb = &B11111111 'Pullup-Widerstände zuschalten
'
Do
'
Config Portb.3 = Output
Config Portb.4 = Output
Portb.4 = 0
'
For A = 1 To 3
Portb.3 = 1
Waitms 50
Portb.3 = 0
Waitms 1000
Next A
Portb.3 = 1
Waitms 1000
Portb.3 = 0
Waitms 1000
'
Portb.4 = 1
Waitms 1
Start Timer0 'Vor Ablauf der folgenden Wartezeit sollte die Messung fertig sein
Waitms 1
'
For A = 1 To 3
Portb.3 = 1
Waitms 50
Portb.3 = 0
Waitms 50
Next A
Waitms 1000
'
If An_oder_aus = 0 Then
Portb.3 = 1
Waitms 1000
Portb.3 = 0
Waitms 1000
End If
If An_oder_aus = 1 Then
Portb.3 = 1
Waitms 1000
Portb.3 = 0
Waitms 1000
Portb.3 = 1
Waitms 1000
Portb.3 = 0
Waitms 1000
End If
'
Loop
'
Tim0_isr:
Stop Timer0
An_oder_aus = 0
Config Portb.4 = Input
An_oder_aus = Pinb.4
Config Portb.4 = Output
Portb.4 = 0
Timer0 = 0
Return
'
End

SprinterSB
07.11.2005, 13:56
Sowas hab ich auch mal Versuch mit ner LED, allerdings nicht die C-Änderung versucht zu messen, sondern die LED als Stromquelle verwendet und via A/D-Wandler ausgemessen.

Bild c.) ist mir nicht ganz klar. Wie soll sich die LED denn entladen? IN ist hochohmig. Und mit den Kapazitäten wird's auch nicht einfach. Die C einer LED würd ich im pF-Bereich ansiedeln oder ein paar 100 fF. Das gegen die um einiges größere Port-Kapazität auszumessen dürfte sehr schwer sein, vor allem weil die Kapazitätsänderung noch kleiner ausfällt. Und mir ist auch nicht klar, wie man den von der LED erzeugten Strom unterdrückt/rausrechnet.

Bei der A/D-Wandler-Lösung geh ich über Transimpedanzwandler und nachgeschalteten Verstärker um niederohmig genug für den ADC des AVR zu sein. Das ist aber alles *sehr* verrauscht und die Werte sehr klein, vor allem bei Schummerlicht oder normaler Raumbeleuchtung.

Wenn ich's richtig verstehe, willst du nur ein binäres on/off messen können und nicht die Umgebungshelligkeit?

Evtl geht's dann viel simpler: Die LED in Sperrichtung an den Analog-Komparator. Den anderen Port des AnaComp via Trimmpoti auf festes Potential. Parallell zur LED nen großen Widerstand. Bei Beleuchtung setzt die LED Ladungsträger frei und bildet eine Spannung zwischen ihren Anschlüssen, die teilweise durch den R parallel zu ihr wieder abfliesst. U=I*R eben. Versuch mal verschiedene Werte für R so um 1MOhm oder höher. Den Ausgang des AnaComp kannst du abfragen und abhängig davon ne 2te LED an/aus schalten.

Radio Eriwan
07.11.2005, 15:55
Hallo Sprinter,

die Idee mit dem A/D-Wandler klingt auch sehr interessant!

Ich würde nur gerne erstmal 'mein' Prinzip zum funktionieren bringen, da dies dann auch auf den ganz kleinen Atmels ohne A/D-Wandler laufen könnte/würde.

Die LED-Kapazität soll sich über den Vorwiderstand plus Eingangswiderstand des µ-Controllers gegen Masse entladen. Was mir nur nicht ganz klar ist: Wie mache ich das programm-technisch? Ich setze den betreffenden Pin ja vorher auf +Ub, um die LED 'aufzuladen'. Was aber dann? Ein einfaches Umschalten auf 'Eingang' scheint nicht die Lösung zu sein. Leider habe ich im Datenblatt des AT's weder ein Bild mit einer typischen Ein- bzw. Ausgangsbeschaltung gefunden, noch die Angabe eines Eingangswiderstandes.

Wenn ich die Oszillogramme richtig interpretiere, dann kann ich von folgenden Kapazitäten ausgehen:

- LED wird beleuchtet -> Entladung dauert ca. 60 µs -> C = 55 nF
- LED wird nicht beleuchtet -> Entladung dauert ca. 900 µs -> C = 820 nF

Als Widerstand habe ich bei der Berrechnung nur den Vorwiderstand mit 220 Ohm genommen (+Ub = 5 V); den Ri des µ-Controllers also vernachlässigt. Wenn ich als Eingangswiderstand z.B. noch mal 10 kOhm dazurechne, dann sind es 5,4 nF und 81 nF. In der Realität dürfte die Kapazität aber noch geringer sein, weil der Eingang mit Sicherheit mehr als 10 kOhm hat.

Das PDF-Dokument sagt dazu:


... The actual measurement is made in "Discharge" mode shown in Figure 5c. Since the current flowing into a CMOS input is extremely small, the low value current limiting resistor has little impact on the voltage seen at the input pin. ...

Das Programm der Mitsubishi-Ingenieure läuft übrigens auf einem 8 pol. PIC. Vielleicht sollte ich zwecks Eingangswiderstand dazu mal ein PIC-Datenblatt 'wälzen'.

Im übrigen wird ja genau genommen nicht die Kapazität gemessen, sondern nur nach einer vorgegebenen Zeit abgefragt, ob die Kapazität der LED noch ge- oder schon entladen ist.

Weiß jemand weiter?

Viele Grüße,

Radio Eriwan

SprinterSB
07.11.2005, 16:11
Oben hab ich noch was geschrieben zum ADC.

Kapazitätsmessung kann man so machen (AT90S2313 geht prima):
C über einen Port des Analog Comparators (AC) und Vorwiderstand aufladen. Bei LED kann der Vorwiderstand natürlich wegfallen. Den anderen Port des AC auf Vcc/2 legen. Wenn der C voll ist, den LED-Pin auf hochohmigen Eingang und den C über einen externen R entladen. R geht von Port nach GND.
Zeitmessung: Timer1 wird auf 0 gesetzt und in dem Moment gestartet, wo man anfängt, den C zu entladen. Den Ausgang des AC konfiguriert man zum eingang des InputCapture. In dem Moment, wo der AC seine Polarität wechselt, wird der Stand von Timer1 im ICR1 gemerkt. Die so gemessene Zeit ist direkt proportional zum C (AFAIR bis auf 4 Taktzyklen Versatz). Im Faktor stecken noch die Taktfrequenz, R und ln(2).

Das ganze geht bestimmt auch anders rum: C entladen und über einen AC-Pin durch aktiviertem Pullup aufladen. Die Pullups liegen so bei 50-80kOhm, dürften also zu klein sein. Dann könnte man den Entlade-R sparen.

::EDIT::

Den Eingangswiderstand kannst du mit mehreren 100 MOhm oder einigen GOhm ansetzen.

Radio Eriwan
07.11.2005, 16:42
Hi,

wir hatten wohl gerade zeitgleich geschrieben! O:)


Wenn ich's richtig verstehe, willst du nur ein binäres on/off messen können und nicht die Umgebungshelligkeit?

Genau das! Mit Veränderung der Meßzeit könnte ich dann sogar den Umschaltzeitpunkt hell/dunkel bestimmen bzw. festlegen.

Aber sag mal, habe ich da etwas übersehen, oder hat der 2343 keinen Analog-Komparator? Einen 2313 habe ich (noch) nicht.

Ich habe nun nochmal das Datenblatt des AT's durchgearbeitet und dabei folgendes gelesen:


I/O Pin Pull-up 30 - 150 kOhm

und


Input Leakage Current I/O Pin (Vcc = 6 V) 8 µA

Aus letzterem ergäbe sich ein Ri von genau 750 kOhm!

Bleibt nur die Frage, wie bekomme ich den Pin zwecks Entladung auf Masse ohne daß er danach als Eingang geschaltet dieses Setzen auf '0' als Eingangswert interpretiert?!?

Grummel, grübel...

Viele Grüße,

Radio Eriwan

SprinterSB
07.11.2005, 16:59
Das Entladen geht wie gesagt durch hochohmig-schalten des Pins. Entladen wird über einen R parallel zum C, der beim Aufladen ja nicht weiter stört. Bei den Größen geht das Entladen allerdings *sehr* schnell, der C einer LED liegt wie gesagt in Bereich von einigen pF. Wie groß die Kapazitätsänderung dC/dI ist hab ich auch keinen Schimmer (I=Intensität). Jedenfalls ist das stark anhängig von der LED und ihrer Temperatur, evtl ist die Kapazität auch spannungsabhängig.

Zeitmessung geht evtl auch über den INT0. AC scheint das Winz-Teil keinen zu haben: LED laden, INT0 scharf machen, Port auf IN ohne pullup. Polling würd ich nicht empfehlen, sondern über Interrupt, weil du dann die Zeit kennst zwischen INT0-IRQ und Auslesen bzw Anhalten des Timers.

Zu den Werten wie Input Leakage Current etc kann ich nix sagen, sind vermutlich nur Maximalwerte und unterliegen zudem einer recht starken Streuung, wie die Pullups auch.

Evtl gehen auch andere Aufbauten... mal die Brainware 1.0 ankurbeln ;-)

Radio Eriwan
07.11.2005, 17:27
Hi Sprinter,

was genau meinst Du mit "hochohmig-schalten des Pins"?

Wenn ich jetzt mal Dein Beispiel nehme:

Ich schalte der LED (Kapazität sagen wir mal beleuchtet 10 pF) einen 1 MOhm Widerstand parallel. Ri des µ-Controllers nehmen wir mal mit 100 MOhm an und vernachlässigen selbiges. Dann würde eine vollständige Entladung bei Beleuchtung ca. 50 µs dauern. Wäre also noch gut zu erfassen.

Ich habe nur Schwierigkeiten, daß als Programm umzusetzen. Pin auf 'High' setzen ist klar, danach dann einfach nur als Eingang mit 'Config Portb.4 = Input' und 'An_oder_aus = Pinb.4'? So hatte ich das bisher gemacht, leider ohne Erfolg.

Mit den ganzen INT's stehe ich nämlich noch ein wenig auf Kriegsfuß...

Es grüßt...

...Radio Eriwan

SprinterSB
07.11.2005, 18:28
Also mit BASIC kann ich dir net helfen und was sich hinter dem ominösen Config verbirgt. Meine BASIC-Zeiten sind spätestens siet den Anfängen von C64 passé.

Die I/Os der AVRs kannst du auf 2 Arten als IN verwenden: Mit pullup und ohne. Ohne pullup ist das ganze hochohmig.

IN, highZ: DDRx.y=0, PORTx.y=0 (default)
IN+pullup:DDRx.y=0, PORTx.y=1

Welche SFRs man anfassen muss, um den INT0 einzustellen, kannst du im Datenblatt finden. Am transparentesten wär es, die SFRs dann so zu setzen, wie es im Datenblatt steht. Welche Zauberworte man BASIC da zuflüstern muss -- keine Ahnung. Vielleicht geht das ja auch in BASIC direkt hinzuschreiben?

Radio Eriwan
08.11.2005, 18:30
Hi Sprinter,

ich hatte in meinem Programm auch mal die Pullup's weggelassen, ging leider trotzdem nicht.

Ich vermute mal, daß das vorherige Setzen des Ausganges auf '1' das Problem ist. Beim Umschalten auf Eingang bleibt sie wohl im Register und erscheint dann als Eingangswert. Wenn ich nämlich statt einer '1' eine '0' ausgeben lasse, dann lies er die ein. Merkwürdig!

Mit den INT's werde ich mich nochmal speziell beschäftigen.

Mal schauen, ob ich das doch noch irgendwie gelöst bekomme...

Danke für Deine Hilfe!

Viele Grüße,

Radio Eriwan

08.11.2005, 21:15
Config Portb = &B00011000 'Grundzustand einstellen -> Pins als Eingänge(ausser 3,4)
Portb = &B11100111 'Pullup-Widerstände zuschalten

waitms 1000 = wait 1

spart speicher und ablaufzeit.
mfg psft

SprinterSB
08.11.2005, 22:27
Ich vermute mal, daß das vorherige Setzen des Ausganges auf '1' das Problem ist. Beim Umschalten auf Eingang bleibt sie wohl im Register und erscheint dann als Eingangswert. Wenn ich nämlich statt einer '1' eine '0' ausgeben lasse, dann lies er die ein. Merkwürdig!

nur mal sicherheitshalber nachgefragt: Den Input liest du über Pinx-Register ..... nicht etwa über Portx-Register?

Radio Eriwan
09.11.2005, 08:28
Moin alle,


Config Portb = &B00011000 'Grundzustand einstellen -> Pins als Eingänge(ausser 3,4)
Portb = &B11100111 'Pullup-Widerstände zuschalten

waitms 1000 = wait 1

spart speicher und ablaufzeit.
mfg psft

Danke für den Tip mit 'wait' statt 'waitms'! Wieder was gelernt.

Die eigentliche Portkonfiguration hatte ich schon ähnlich gemacht, nur daß ich erstmal alle Pullup's zugeschaltet hatte.

Ich werde das Problem jetzt mal anders angehen, und eine LED als Sensor benutzen und eine andere als Indikator. Das sollte doch wohl hinzukriegen sein! :-k


nur mal sicherheitshalber nachgefragt: Den Input liest du über Pinx-Register ..... nicht etwa über Portx-Register?

Ja, das mache ich so. Ich hatte mir nämlich mal heftig ein Ei gelegt, als ich der Hilfe von Bascom blind vertraut hatte: Die schreiben in der Hilfe, daß der 'bitwait'-Befehl angeblich mit 'Portx.x' funktioniert, also z.B. 'Portb.7'. Das ist vollkommener Quatsch und funktioniert nicht. Richtig muß es da heißen 'Bitwait Pinb.7 , Reset' und nicht 'Bitwait Portb.7 , Reset'! Habe mir also gemerkt, daß eine Ausgabe mit 'Port' und eine Eingabe mit 'Pin' gemacht werden muß.

Bevor ich nun weiter an der eigentlichen Lösung arbeite, werde ich mal etwas mit den Pins spielen, um das Verhalten des Atmels besser zu verstehen.

Dank' Euch für Eure Hilfe, wenn jemand noch eine Idee oder einen Tip hat, dann immer her damit! =P~

Viele Grüße,

Radio Eriwan

P.S. oder EDIT: Ich habe gerade mal folgendes ausprobiert: Wenn ich mein Programm (Pullup's nun für Portb.3 und .4 deaktiviert) laufen lasse, und mit einer Drahtbrücke während der Messung Masse an den Eingang lege, dann gibt er mir das auch hinterher richtig aus. So weit scheint mein Programm also schon mal einigermaßen richtig zu laufen.

Eine Frage noch zum Befehl 'Portb = &B': Mit diesem Befehl schalte ich ja (binär) die Pullup's ein oder aus. Es ist doch aber auch gleichzeitig der Befehl für eine 'normale' Portausgabe!?! Wo liegt der Unterschied zwischen 'Pullup's schalten' und 'Ausgabe'?

SprinterSB
09.11.2005, 09:27
Port auf Ausgang (DDRx=1) --> PORTx legt Potential fest
Port auf EIngang (DDRx=0) --> PORTx kontrolliert Pullups

Radio Eriwan
09.11.2005, 12:16
Danke für die Erklärung!

So, hier nun die neusten Ergebnisse meiner Tests der Ein- bzw. Ausgänge:

Ich habe mal eine kleine Testschaltung gebaut, bei der ich jeweils eine LED mit Vorwiderstand vom jeweiligen Pin (Pinb.3 und Pinb.4) des AT's an Masse gelegt habe. Eine LED zeigt mir den Programmschritt an, die andere den Zustand des Ein- bzw. Ausganges. Das Programm dazu befindet sich im Anhang.

Ergebnis: Eine an einen Ausgang gesendete '1' wird im Register gespeichert (logo!), beeinflußt aber auch das Ergebnis beim Einlesen, wenn dieser Pin nun als Eingang geschaltet wird. Es scheint, als wenn beim Umschalten auf Eingang das Register nicht vollständig 'abgekoppelt' wird.

Die entsprechende LED am auf Eingang geschalteten Pin glimmt munter so vor sich hin (Spannung mit LED Ausgang - Masse: 1,7 Volt); wenn ich sie rausnehme, habe ich volle 5 Volt.

Setze ich den Pin als Ausgang vorher auf '0', dann bleibt diese ebenfalls erhalten, wenn ich den Pin auf Eingang schalte; die LED bleibt dunkel und das Voltmeter zeigt nahezu null Volt.

Eine testweise gegen +Ub geschaltete LED verrät mir noch etwas anderes: Bei einem als Eingang geschalteten Pin gibt es, egal ob vorher eine '1' oder '0' auf den Ausgang gegeben wurde, keine (niederohmige) Verbindung zu Masse wie die zu +Ub.

Damit und somit kann ich 'meine' Idee wohl vergessen! Die LED bzw. ihre Kapazität kann so nicht entladen werden...

Viele Grüße,

Radio Eriwan


' '
$regfile = "2343DEF.dat"
$crystal = 1000000
'
Config Portb = &B00011000
Portb = &B11100111
'
Dim A As Bit
'
Do
'
Gosub Led_1
Portb.4 = 0
Wait 5
Gosub Led_2
Portb.4 = 1
Wait 5
Gosub Led_3
Config Portb.4 = Input
A = Pinb.4
Wait 5
Gosub Led_4
Config Portb.4 = Output
Wait 5
'
Loop
'
Led_1:
Portb.3 = 1
Waitms 50
Portb.3 = 0
Return
'
Led_2:
Portb.3 = 1
Waitms 50
Portb.3 = 0
Waitms 50
Portb.3 = 1
Waitms 50
Portb.3 = 0
Return
'
Led_3:
Portb.3 = 1
Waitms 50
Portb.3 = 0
Waitms 50
Portb.3 = 1
Waitms 50
Portb.3 = 0
Waitms 50
Portb.3 = 1
Waitms 50
Portb.3 = 0
Return
'
Led_4:
Portb.3 = 1
Waitms 50
Portb.3 = 0
Waitms 50
Portb.3 = 1
Waitms 50
Portb.3 = 0
Waitms 50
Portb.3 = 1
Waitms 50
Portb.3 = 0
Waitms 50
Portb.3 = 1
Waitms 50
Portb.3 = 0
Return
'
End

SprinterSB
09.11.2005, 12:30
Daß die LED glimmt mit pullup aktiv ist doch ok, oder?


When switching between tri-state ({DDxn, PORTxn} = 0b00) and output high ({DDxn,
PORTxn} = 0b11), an intermediate state with either pull-up enabled ({DDxn, PORTxn} =
0b01) or output low ({DDxn, PORTxn} = 0b10) must occur. Normally, the pull-up
enabled state is fully acceptable, as a high-impedant environment will not notice the difference
between a strong high driver and a pull-up. If this is not the case, the PUD bit in
the SFIOR Register can be set to disable all pull-ups in all ports.

Switching between input with pull-up and output low generates the same problem. The
user must use either the tri-state ({DDxn, PORTxn} = 0b00) or the output high state
({DDxn, PORTxn} = 0b11) as an intermediate step.

Radio Eriwan
09.11.2005, 13:17
Hallo Sprinter,

vielen Dank für Deinen heißen Tip!!!

Während Du das geschrieben hast, hatte ich im Programm zeitgleich schon ausprobiert, den Pullup nach Umschalten auf Eingang nochmals abzuschalten! Man, was für ein Zufall! :-) Das mit den Zwischenzuständen beim Umschalten ist ja fast wie Fahren bzw. Schalten mit 'Zwischengas'...

Ich dachte, die Pullup's am Programmanfang einmal zu aktiveren/deaktivieren reicht.

Mal testen...

Es grüßt...

...Radio Eriwan

Radio Eriwan
11.11.2005, 18:10
Hi alle,

so, fertig, es ist geschafft!

Ein dickes 'Danke schön!' an Dich, Sprinter!

Meine Schaltung besteht nun aus einem AT90S2343, einem Widerstand und einer LED. Wird die LED angestrahlt, quittiert sie dies mit 10 kurzen Blinkimpulsen. Die Reichweitenmessung mußte ich nach 9 m abbrechen; länger war der Flur nicht.

Mein Fehler (neben dem mit den Pullup's): Die Eingänge sind dermaßen hochohmig, daß meine Zeitschleife 'Entladen' einfach viel zu kurz war... ;-)

Jetzt löppt das alles und ich freue mich einfach!

Viele Grüße,

Radio Eriwan

SprinterSB
11.11.2005, 19:16
Hi Eriwan,

Glückwunsch!

Verrätst du auch, wie du das geschaltet hast?
Einfache die LED zwischen 2 Ports?
Was ist das für eine LED ist es?
Und mit welchen Zeiten muss man da rechnen?

Radio Eriwan
11.11.2005, 19:37
Hallo Sprinter,

klar 'verrate' ich es (ein Schaltplan sagt mehr als tausend Worte ;-) ):

http://img390.imageshack.us/img390/5295/reaktiveslicht3hm.gif

Die LED ist eine ultra-helle rote 5 mm in transparentem Gehäuse. Es funktioniert jedoch auch mit jeder (!) anderen LED (grün, gelb); am schlechtesten bzw. unempfindlichsten haben sich allerdings rote LED's in rotem Gehäuse herausgestellt.

Zum Programm:

- LED wird für 1 ms 'geladen' (kann ggf. noch drastisch verkürzt werden)
- 1 ms (Entlade-)Wartezeit (diese Zeit bestimmt die Ansprechempfindlichkeit)
- danach Abfrage, ob Eingang '0' (hell) oder '1' (dunkel)

Das ist schon fast 'erschreckend' simpel! Wie gesagt, Reichweitenversuch mußte ich bei 9 m wegen Platzmangel abbrechen... ;-)

Ich hoffe, das hilft Dir und anderen weiter!?

Viele Grüße,

Radio Eriwan

SprinterSB
11.11.2005, 20:05
Ja,
die Ladezeit kann IMHO deutlich gesenkt werden. 1µs ist da nicht zu kurz.

Der externe INT sollte gute Dienste zur Zeitmessung leisten in Zusammenarbeit mit einem Timer.

Nochwas: Welche Lichtquelle verwendest du?

Bei mir wird's leider nicht so einfach 8-[
Mit einer LED im Multiplex-Betrieb will ich die Umgebungshelligkeit bei normalem Umgebungs- und Dämmerungslicht bestimmen. Die LED soll also quasi gleichzeitig leuchten und die Helligkeit messen, damit ich ihre Helligkeit an die Umgebungshelligkeit anpassen kann. Erschwert wird das dadurch, daß die LEDs in diffusem Gehäuse stecken (weiß-diffuse Flächen-LEDs)

Radio Eriwan
12.11.2005, 07:02
Moin,

stimmt, die Ladezeit kann man ja deshalb noch stark verkürzen, weil die Kapazität der LED ja nur über den Vorwiderstand allein geladen wird.

Eine Zeitmessung mache ich übrigens nicht, da ich die Kapazität selbst nicht messen möchte; weder relativ noch absolut. Ich gebe eine Fixzeit vor, nach der ich einfach nur schaue, ob die Kapazität noch ge- oder schon entladen ist. Für mich bzw. meine Schaltung reicht das im Moment so aus.

Als Lichtquelle habe ich einfach eine Taschenlampe verwendet. Den Nahversuch auf dem Steckbrett habe ich mit einer 1-LED-Lampe (5 mm, weiß) mit kleiner Leistung gemacht, den 9 m-Versuch mit einer Dorcy 1 W-LED-Lampe (weiß). Auch das Licht normaler Glühlampen funktioniert einwandfrei.

Faszinierend dabei ist für mich die Empfindlichkeit einer LED; ihr Vorteil als Sensor ist der recht schmale Ein- und Austrittswinkel für das Licht. So kann man Störeinflüsse durch Seitenlicht, wie z.B. bei einem LDR, vermeiden.

Die Sache mit dem 'gleichzeitigen' Leuchten dürfte doch aber kein Problem sein, da Du ja per Programm recht schnell zwischen 'Messen' und 'Ausgeben' umschalten kannst. Und LED's im weiß-diffusen Gehäuse sollten als Sensor auch gut funktionieren. Allerdings müßtest Du dabei dann tatsächlich die Kapazität 'messen', zumindest relativ, da Du ja nicht nur zwei Zustände (hell - dunkel) wie ich unterscheiden möchtest.

Du solltest das auf jeden Fall mal ausprobieren, das funktioniert wirklich gut. Und in welchem Zeitraum (Laden, Entladen) sich das ganze abspielt, weißt Du ja jetzt ungefähr.

Ich habe mir gestern bei Reichelt noch ein paar unterschiedliche AVR's bestellt, weil ich nun noch den Strom-'Verbrauch' der Schaltung drastisch senken möchte. Ein Sleepmode kommt bei dieser Umsetzung ja leider nicht in Frage, deshalb möchte ich das nun mit einem ATtiny13 realisieren. Den schalte ich dann auf den internen 128kHz-Oszillator, so daß er bei 3 V dann nur noch 50 µA zieht; Ladung der LED ausgenommen. Wenn ich dann noch den Widerstand per PWM eleminieren würde, gäbe es für meinen Zweck keine einfachere Schaltung mehr. Mal schauen...

Viele Grüße,

Radio Eriwan

super_castle
12.11.2005, 10:23
Gibt es ein Programmablauf für den Schaltplan und die vorgeschlagenen "1ms" in Bascom und mit beispiel des Datenrichtungsregister:
- LED wird für 1 ms 'geladen' (kann ggf. noch drastisch verkürzt werden)
- 1 ms (Entlade-)Wartezeit (diese Zeit bestimmt die Ansprechempfindlichkeit)
- danach Abfrage, ob Eingang '0' (hell) oder '1' (dunkel)

Danke.

Castle

SprinterSB
12.11.2005, 11:31
Die Sache mit dem 'gleichzeitigen' Leuchten dürfte doch aber kein Problem sein, da Du ja per Programm recht schnell zwischen 'Messen' und 'Ausgeben' umschalten kannst.
Leider nein. Die LED häng mit einigen anderen LEDs in einer Matrix mit Anoden und Kathodentreibern, und das Signal von der LED ist sehr stark verrauscht. Über R-C-Filter oder so kann ich nicht gehen, weil das die Messung zu langsam macht und die LED schon wieder leuchten soll. Meine bisherigen Erfahrunge ist, daß es im Schummerlicht-Bereich seht schwer ist, da was zu erkennen. Softwaremässig zu filtern hilft etwas, aber das Signal ist eben sehr stark verrauscht.

Ich hatte geplant, die LED als Stromquelle zu verwenden und den Strom über einen Transimpedanzwandler zu messen.

IMHO wird bei deiner Schaltung auch nicht die Kapazitätsänderung der LED gemessen -- man belehre mich da eines besseren ;-)

Die LED ist ein C, der aufgeladen wird. Ok. Durch die Beleuchtung wird die LED dann unterschiedlich schnell entladen, weil sie unter Beleuchtung eine kleine Stromquelle ist, deren Größe von der Lichtstärke abhängt. Dadurch pumpt sie ihre Kapazität unterscheidlich schnell leer. Mit C-Änderung hat das wohl nix zu tun denk ich...

Jedenfalls ein spannendes Thema.

Radio Eriwan
12.11.2005, 13:28
Hi Sprinter,

ja, in einer solchen Matrix, wie geschildert, dürfte das wirklich schwierig werden!

Zu meiner Schaltung: Die LED hat tatsächlich eine lichtabhängige Kapazität. Diese wird nicht vom Licht entladen, sondern vom µC. In der Funktechnik nimmt man für einen VCO z.B. normale Gleichrichterdioden (1N4001), deren Kapazität spannungsabhängig ist. Jede Art der Energiezuführung (Licht, Spannung, Wärme) verändert die Kapazität eines PN-Überganges.

Aber wie gesagt: Ich 'messe' in meiner Schaltung nicht die Kapazität, ich benutze eine Fixzeit. Der Ri des µC ist nahezu konstant; verändern tut sich nur die Kapazität der LED mit dem Lichteinfall. Das zusammen ergibt unterschiedliche Entladezeiten, die ich dann mit meinem Programm auswerte.

An Castle:
Soll ich mein Programm mal hier rein stellen?

Es grüßt...

...Radio Eriwan

super_castle
12.11.2005, 14:15
Joop, mach das mal.

Gruß Castle

Radio Eriwan
12.11.2005, 14:57
Ok, bitte sehr (ist aber noch nicht optimiert ;-) ):


'
$regfile = "2343DEF.dat"
$crystal = 1000000
'
Config Portb = &B00011000 'Pinb.3 und .4 auf 'Ausgang', Rest auf 'Eingang' schalten
Portb = &B11100111 'Pullups zuschalten, außer für Pinb.3 und .4
'
Dim A As Byte
Dim Hell_dunkel As Bit
'
Do
'
Portb.3 = 0 'Portb.3 auf Masse schalten
Portb.4 = 1 'Portb.4 auf +Ub schalten, um die LED zu 'laden'
Waitms 1 'Ladezeit 1 ms
Config Portb.4 = Input 'Portb.4 nun zwecks Abfrage der LED-Ladung auf 'Eingang' schalten
Portb.4 = 0 'Pullup abschalten, sonst geht's nicht!
Waitms 1 'Entladezeit 1 ms - je kleiner, je unempfindlicher
Hell_dunkel = Pinb.4 'Ladezustand einlesen
Config Portb.4 = Output 'Portb.4 wieder auf Ausgang schalten
Portb.4 = 0 'Portb.4 auf Masse schalten
'
If Hell_dunkel = 0 Then
For A = 1 To 10
Portb.3 = 1
Waitms 50
Portb.3 = 0
Waitms 500
Next A
End If
'
Loop
'
End

Wird die LED kurz angeleuchtet, dann blinkt sie mit 10 gut sichtbaren Impulsen zurück.

Es grüßt...

...Radio Eriwan

super_castle
12.11.2005, 21:33
Hallo, ich habe eine LD 274-Ir-Diode angeschlossen.
Geht wunderbar bis auf 10m mit einer normalen Taschenlampe.
Wenn die Diode zu schräg noch oben steht, reicht auch zum Auslösen
schon die Deckenlampe.
Mit meiner IR-Fernsehfernbedienung geht es bis auf 4m, danach nicht mehr, weil man nicht mehr so genau die Empfangsdiode trifft.

Lösung : Es werden in der Diode die Gasteilchen durch das Licht leitend
gemacht, dann kann der Strom fliessen. Hat nichts mit kondensatorähnlichen Aufladungen zu tun.
Bei der Leuchtdiode leuchtet das Gas noch zusätzlich und bei der IR-Diode nicht.

Gruss Castle

super_castle
12.11.2005, 23:19
Geht wunderbar als Liniensensor.
Habe bei 2 Ir-Dioden eine kleine helle Leuchtdiode als Bodenbeleuchtung in der Mitte angebracht. Alles 3cm vom Boden entfernt, bei weissen Papierstreifen gibt es ein Impuls und bei den anderen Farben (Parkett, Teppich) kein Impuls. Der Robby folgt schön der weissen Linie, die auch gleichmässig von der Leuchdiode ausgeleuchtet wird.

Castle

SprinterSB
13.11.2005, 00:44
Es werden in der Diode die Gasteilchen durch das Licht leitend gemacht, dann kann der Strom fliessen. Hat nichts mit kondensatorähnlichen Aufladungen zu tun.
Bei der Leuchtdiode leuchtet das Gas noch zusätzlich und bei der IR-Diode nicht.

Gruss Castle

*kopfkratz* :-k

super_castle
13.11.2005, 08:10
Ich habe den Pinb.3 jetzt auf gnd gelegt und funktioniert genauso.
Man kann einen Pinanschluss am AVR sparen.
Zum senden(ausleuchten) nehme ich auch eine LD 274. Mit einem Poti bestimme ich die Sendeleistung, sozusagen eine Abstimmung für den Untergrund.
Der Robby folgt einer Linie, die ich vorher mit dem Poti für die Sendediode kalibriert habe.

Fazit: Es geht auch im Infrarotbereich, ohne störenden Lichteinwirkungen für andere und auch nur mit einem Pin vom AVR zur Masse, bei der Sendediode und beim Empfangsdiode.

Castle

super_castle
13.11.2005, 08:16
Jetzt ist die nächste Leistung, wie kann man die Ir-Dioden in dieser Bauweise zum Senden/Empfangen von Daten benutzen.

Auf gehts.....Senden...Empfangen von Daten mit dieser Schaltung.

Castle

super_castle
13.11.2005, 08:51
Habe den Code geändert.
Zeit ist Waitus 20, entspricht etwa 190us in der Realzeit.
Diode Leuchtet jetzt nur, wenn der Ir-Empfänger was empfängt.
Bei mir ist Pinb.0=empfangen und Pinb.7 leuchten.
Wichtig ist die Zeit von ca 190us(real) damit die Gase in der Diode leitfähig werden.
ich habe je 100ohm an den leitungen der dioden.



Do

PORTB.0 = 1
DDRB.0 = 0
PORTB.0 = 0

WaitUs 20

Hell_dunkel = PINB.0

DDRB.0 = 1
PORTB.0 = 0

If Hell_dunkel = 0 Then
PORTB.7 = 1
Else
PORTB.7=0
End If

Loop



Castle

Radio Eriwan
13.11.2005, 10:34
Moin Castle,

freut mich, daß der Nachbau auch bei Dir funktioniert hat!

Eines muß ich aber noch loswerden:

In einer LED, ob nun IR oder normaler sichtbarer Lichtbereich, gibt es kein Gas!

Es existiert nur ein sog. PN-Übergang (Diode) aus unterschiedlich dotierten Halbleitermaterialien. Ein weiterer zugesetzter chemischer Stoff an der Berührungsfläche (Sperrschicht) beider Stoffe, z.B. Gallium-Arsenid (GaAs), sorgt dann erst für das Leuchten (normale Dioden setzen das übrigens in Wärme um).

Wird die LED nun mit Licht bestrahlt (Photonen), dann setzen diese in der o.a. Sperrschicht zusätzliche Elektronen frei. Einige davon sorgen für eine Verkleinerung der Sperrschicht, andere bleiben als freie Ladungsträger erhalten ('potentieller Strom'), die aber normalerweise nicht abfließen können. Sie bleiben erhalten (gespeichert), wie bei einem Kondensator. Diese Kapazität eines PN-Überganges kann man nun entladen und wieder laden.

Die Größe und die Ladung dieser Sperrschicht, und damit die Kapazität unseres 'LED-Kondensators', hängen also direkt vom Licht ab.

Wenn Du das ganz genau wissen möchtest, hier mal ein Link dazu:

Klick mich! (http://de.wikipedia.org/wiki/LED)

In meiner Schaltung lade ich diese Kapazität übrigens deshalb zusätzlich auf, weil die lichtabhängige Aufladung im Verhältnis sehr klein ist.

EDIT:
Vergrößerung -> Verkleinerung

Es grüßt...

...Radio Eriwan

SprinterSB
13.11.2005, 10:46
Demnach sinkt die Kapazität der LED mit der Lichtstärke?
Gleiches sollte für die Temperatur zutreffen? Weil der pn-Sperrschicht dann dünner wird. Mit der Spannung müsste die Kapazität hingegen steigen...

Radio Eriwan
13.11.2005, 10:57
Demnach sinkt die Kapazität der LED mit der Lichtstärke?

Jupp! Mehr Licht: C kleiner und damit bei gleicher Ladung schneller alle... ;-) Durch vermehrte Elektronenfreisetzung bei Licht können mehr Elektronen in der Sperrschicht rekombinieren; sie wird kleiner. Sieht man übrigens auch gut in dem einen Entladezeitdiagramm des in diesem Thread am Anfang schon erwähnten PDF-Dokumentes.


Gleiches sollte für die Temperatur zutreffen? Weil der pn-Sperrschicht dann dünner wird. Mit der Spannung müsste die Kapazität hingegen steigen...

Auch korrekt! Jede Form externer Energiezuführung hat diesen Effekt: Mehr Elektronen -> erhöhte Rekombination -> dünnere Sperrschicht -> kleineres C. Einzig die Spannung: Sie wirkt gegenteilig, da sie bei Zunahme in Sperrichtung (!) die Sperrschicht vergrößert (C wird größer).

Es grüßt...

...Radio Eriwan

super_castle
13.11.2005, 16:50
Auf jedenfall verhält sich eine normale Leuchtdiode beim Empfang genauso wie eine Ir-Diode, also keine besondere Sache hinsichtlich der Technik und der Funktion, man hat sich nur keine Gedanken vorher darüber gemacht. Jetzt geht es nur darum, damit auch Daten zu verschicken, ob mit Gas oder ohne Gas.
Auch der Anschluss hat sich in deinem verbesserten Progamm von mir vereinfacht, man spart jetzt ein Pin am AVR.
Die optimale Zeit liegt nach meinem ergebnissen bei ca 190us um sicher zu Empfangen.
Für einen Liniensenor eine gute günstige Angelegenheit.
Für Datenübermittlung wird man sehen.

Castle

Radio Eriwan
14.11.2005, 07:56
Moin Castle,

klar verhalten sich normale LED und Ir-LED beim Empfang gleich. Wäre schon komisch, wenn nicht... ;-)

Bei meiner Anwendung brauche ich übrigens zwei Pins, da ich die selbe LED zum Empfangen und Senden von Licht brauche. Das geht nicht, wenn ich nur einen Pin benutze.

Datenübertragung soll damit auch sehr gut funktionieren; die Ingenieure von Mitsubishi sprechen von einer sicheren Reichweite von ca. 3 cm bei einem Datenduchsatz von ungefähr 200 Bytes/s.

Es grüßt...

...Radio Eriwan

super_castle
14.11.2005, 14:15
Ähm....
Ich komme mit meiner Irdiode zur anderen Irdiode auf über 100cm mit den Daten und auch sicher. Nur weiss ich noch nicht, wie man die daten als Bit und Byte zusammenstricken tut.

Schick die Ingenieure-Japse mal zu mir , oder hast du dich verschrieben mit 3cm.

Castle

Radio Eriwan
14.11.2005, 16:52
Hallo Castle,

nein, ich habe mich nicht verschrieben...


Nur weiss ich noch nicht, wie man die daten als Bit und Byte zusammenstricken tut.

Dann sag' doch einfach mal bescheid hier, wenn Du eine funktionierende Datenübertragung von zumindest auch 200 Bytes/s hinbekommen hast. Dann schicke ich diese japanesischen Dilettanten sofort zu Dir! Da könnten die sich dann aber bestimmt noch 'ne Menge von Dir abgucken! ;-)

Meine Schaltung spricht übrigens noch auf 50 m sicher an; gemessen hier im Park mit einer 4D-MagLite...

Es grüßt...

...Radio Eriwan

SprinterSB
14.11.2005, 17:00
Meine Schaltung spricht übrigens noch auf 50 m sicher an; gemessen hier im Park mit einer 4D-MagLite...

Das wird ja immer besser.
Sag Bescheid, wenn du es schaffst über den grossen Teich zu blinken!

super_castle
14.11.2005, 17:08
Wenn ich meine Zeit nehme von 200µs pro Dateneinheit, dann komme ich auf 5000Bit/Sec und wenn ich pro Übertragung mit 11 Bit rechne, komme ich immer noch auf 454 Datenbytes.

Castle
ps: Ich kann nur die Datenbits nicht in Bytes umsetzen. Vielleicht kann einer mal ein Übertragungsprotokoll dafür schreiben.

super_castle
14.11.2005, 17:22
Ein interessantes Thema.
Viele suchen günstige Übertragungsmedien...
Warum meldet sich kein anderer.....
Und dieses Medium hier ist sehr gut.

Castle

Radio Eriwan
14.11.2005, 17:52
Sag Bescheid, wenn du es schaffst über den grossen Teich zu blinken!
Mach ich!

Ich schraube gerade an meinem ersten Satelliten...

;-)

Radio Eriwan

super_castle
15.11.2005, 17:49
Ich habe die SLH 56 WS Leuchdioden(ultra Hell) getestet, eine zum Senden eine zum Empfangen, geht nicht. Leuchte eine Ultra 274 an mit der SLH 56 , geht auch nicht, leuchte eine Ultra 274 mit Taschenlampe an, geht.
Ultra zu Ultra, geht wieder hervorragend.
Also die Ultra ist bestens geeignet für die Datenübertragung.

Castle

oberallgeier
07.09.2010, 13:01
... so, fertig, es ist geschafft ...
... wie du das geschaltet hast? Einfache die LED zwischen 2 Ports ...2005: Radio Eriwan hats geschafft. 2010: oberallgeier schaffts nicht und schaffts nicht und . . . .

...
#define gLED 4 // Grüne LED, Anode nach/von PB 4
// LED grün, klar, 25-3120050 von CSD
#define kLED 3 // LED grün, Kathode+1k nach PB 3
...


// ================================================== ==============================
// ### Laden, Entladen und Zeitmessung bis "low" der LED für Touchsensor
void BL_test1 (void) //
{ //
// - - DDRB3+4 und PORTB3+4 bzw. gLED schalten - - - - - - - - - - - - - - - - -
//DDRB = 0b0001 1000; // DDRB3+4 = 11 <=> beide als Ausgang
//PORTB = 0b0000 0000; // ..und PortB3+4 auf null
DDRB |= ((1<<kLED) | (1<<gLED)); // Datenrichtungsbits als Ausgang
SetBit (PB, gLED); // mal die LED gaaaanz kurz anwerfen
waitms ( 1); // und ein kurzer Blitz
PORTB &= ~(1<<gLED); // Portpin Anode löschen =>
// PB4 ist jetzt mit Anode auf Gnd = laden vorbereiten
SetBit (PB, kLED); // PB3 mit Kathode+1k auf Vcc => Laden LED-Kondensator
waitms ( 1); // und kurz warten zum "aufladen"
// - - Interrupt ausschalten, Werte setzen - - - - - - - - - - - - - - - - - - -
cli(); //
Izeit_2 = 0; // Zeit zurücksetzen auf Null
sei(); //
// - - Interrupt ist an - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - Jetzt kLED auf "Eingang" - - - - - - - - - - - - - - - - - - - - - - - - -
// ClrBit (PB, kLED); // LED auf high prüfen = messen/discharge
DDRB &= ~(1<<kLED); // Kathodenpin als Eingang definieren
ClrBit (PB, kLED); // Pullup löschen (war ein wegen Vcc auf Ausgangspin)
while (1) //
{
if(IsBitClr (PB, kLED)) break; // Schleifenende, wenn Kathode auf low
} // Ende while (1)
cli();
mess = Izeit_2;
sei();
//
info02_mess( mess );
waitms ( 500); // 2 Messungen pro Minute wegen Ausgabe
//
DDRB |= ((1<<kLED) | (1<<gLED)); // Datenrichtungsbits als Ausgang
PORTB &= ~((1<<kLED) | (1<<gLED)); // Beide Portpins löschen
return; //
}
// ================================================== ==============================
Würde sich bitte jemand die Mühe machen und überlegen und schreiben, wo ich den Fehler mache? Danke im Voraus.

Schaltung genau wie oben bereits vorgestellt. Ich verwende einen mega168, 20 MHz, LE D wie dargestellt, R = 1k:

............http://img330.imageshack.us/img330/6749/led3kr.gif
............© MITSUBISHI RESEARCH, P. Dietz, W. Yerazunis, D. Leigh (http://www.merl.com/reports/docs/TR2003-35.pdf)

Nachtrag das Messergebnis. Messzeit unter 50 µs (Wert = 0) heißt hier, dass die Kapazität in weniger als 50 µs entladen ist. Das ist doch viel zu kurz !? Das müsste doch deutlich länger dauern, oder nicht?

............http://oberallgeier.ob.funpic.de/touch_x02.jpg