Hallo,
ich versuche gerade den in folgendem Paper genannten Aufbau zu
implementieren:
http://www.merl.com/publications/docs/TR2003-35.pdf
Dabei geht es darum eine bidrektionale kommunikation mittels LEDs
aufzubauen. Soweit so gut, ich möchte erstmal eine LED als Empfänger
betreiben.
Hier sieht man noch einmal wie das ganze funktioniert:
http://people.duke.edu/~sd78/projectHub/projects/optoelectronics/principle_clip_image002.jpg
Ich verstehe was dabei passiert nun habe ich folgenden code dazu
geschrieben:
Ein Timer ISR wird alle 100µs ausgelöst und soll dann die genannte
"Entladungsmessung" durchführen, in diesem Beispiel wird ein Zähler
solange erhöht bis die Entladung fertig ist.
ISR(TIMER0_COMPA_vect) {
DDRC |= (1<<(PC1));
PORTC |= (1<<(PC1));
PORTC &= ~(1<<(PC0));
asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
DDRC &= ~(1<<(PC0));
if((PORTC&(1<<PC0))) count++;
}
Die LED hängt mit der Kathode über einen Widerstand an PC0, Anode an
PC1. Das Problem ist nun, der Zähler läuft einfach hoch ohne dass sich
irgendetwas verändert hat. Wenn ich messe liegen an PC0 auch einfach
noch 5V an nachdem die Pinrichtung umgedreht wurde. Vielleicht hat
jemand eine Idee was ich falsch mache.
An inexpensive way to make a photodetector out of an LED is to tie the
2
anode to ground and connect the cathode to a CMOS I/O pin driven high.
3
4
This reverse biases the diode, and charges the capacitance. Next switch
5
the I/O pin to input mode, which allows the photocurrent to discharge
6
the capacitance down to the digital input threshold. By timing how
7
long this takes, we get a measurement of the photocurrent and thus
8
the amount of incident light.
Hmm. das deckt sich aber nicht mit dem was du programmiert hast.
Nimm dir die Bilder her und schreib dir mal deine Pin-Bezeichnungen
dazu. Und dann geh die Bilder (bzw. die Beschreibung) durch und sieh dir
an, in welcher Reihenfolge du welchen Portpin wie beschalten musst. Und
erst dann, wenn du dir 100% sicher bist, dass du die Reihenfolge der
Ereignisse hast, erst dann setzt du dich hin und programmierst das.
Im Idealfall schreibst du dir in Stichworten die korrekte Reihenfolge
tabellenarrtig auf und überprüfst die 3 mal gegen den Text bzw. die
Bilder.
Glorb schrieb:> korrekt da war allerdings noch etwas falsch:> PC0 ---RRRR---]<----- PC1>> ISR(TIMER0_COMPA_vect) {> DDRC |= (1<<(PC0));> DDRC |= (1<<(PC1)); // beide Ausgänge>> PORTC |= (1<<(PC1)); // Phase EMIT> PORTC &= ~(1<<(PC0));>> asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");>> PORTC |= (1<<(PC0)); // Phase Reverse Bias> PORTC &= ~(1<<(PC1));>> asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");> // Phase Discharge> DDRC &= ~(1<<(PC0)); // Eingang> DDRC |= (1<<(PC1)); // Ausgang>> if((PORTC&(1<<PC0))) count++; // PC0 ist noch HIGH dann zählen
PINC
> }
1
Next switch
2
the I/O pin to input mode, which allows the photocurrent to discharge
3
the capacitance down to the digital input threshold. By timing how
4
long this takes,
Also
zuerst auf Input schalten
dann Zeit messen.
Du schaltest auf Input und siehst gleich am Pin nach.
Wie ich schon sagte: Schreib dir doch erst mal in Stichworten zusammen
wie die Reihenfolge der Ereignisse sein muss
Ich verstehe es so wie auf den Bildern gezeigt: Reverse Bias und dann
Input. Mein Fehler ist vielleicht, dass ich das immer wieder im Timer
stattfinden lasse. Was ich eigentlich zum Test erst einmal zeigen will:
Das Programm läuft, die LED ist unbeleuchtet, nichts passiert. Sobald
diese beleuchtet wird soll der Zähler hochzählen bis die LED wieder
unbeleuchtet ist.
Glorb schrieb:> Ich verstehe es so wie auf den Bildern gezeigt: Reverse Bias und dann> Input.
Schau dir nicht nur die Bilder an. Lies auch den Text!
Denn wann gewartet wird, siehst du in den Bildern nicht.
Das steht eindeutig:
zuerst wird auf reverse geschaltet, wodurch die 'Kapazität' geladen
wird. Ok. da wirst du ein bischen warten müssen
Danach auf Input schalten
und jetzt hängt es davon ab, wie lange es dauert bis der Eingangspin
wieder auf 0 gefallen ist, ob man davon ableitet das die LED beleuchtet
ist oder nicht.
Die Zeit NACH dem Umschalten auf Input ist das entscheidende!
ich habe einen Erfolg zu vermelden :).
Meine version ist noch nicht genau das was ich haben will aber es
scheint zu gehen:
void main() {
uart_init();
measure:
count = 0;
DDRC |= (1<<(PC0));
DDRC |= (1<<(PC1)); // beide Ausgänge
PORTC |= (1<<(PC0)); // Phase Reverse Bias
PORTC &= ~(1<<(PC1));
asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
DDRC &= ~(1<<(PC0));
PORTC &= ~(1<<(PC0)); // das war wichtig!
while((PINC&(1<<PC0))) count++;
if(count>5000) goto measure;
{
char buffer[32];
sprintf(buffer,"count: %d",count);
put_stamped(buffer);
}
goto measure;
while(1) {}
return 0;
}
Auf jedenfall kann ich jetzt eine Anzahl sehen wenn die LED entladen
wird, halte ich eine Taschenlampe drauf ist die Zahl klein, im
Tageslicht ist sie groß. Wie es sein sollte. Natürlich muss ich das
ganze nun noch auf den Timer umbauen!
Moin moin...
Hab mal ein paar Versuche dazu gemacht:
(Die Zahlenwerte in Klammern wurden mit untenstehendem, kleinen Prog.
emittelt)
1.)Bestrahlung mit 60W Reflektor-Glühlampe
a) mit roten LEDs ging garnix.
b) gelbe LEDs: gut (dunkel ca. 1640; max. hell: 5)
c) grüne LEDs: gut (dunkel ca. 1640; max. hell: 5)
2.) LED mit LED bestrahlen (Kopf an Kopf)
Vorweg: eine rote LED als Sender, zeigt keine Wirkung bei beliebigen
Empfänger-LEDs.
a) rote LED als Empfänger zeigt auch keine Wirkung, egal womit sie
bestrahlt wird. Selbst mit nem roten Laserpointer bestrahlt, zeigte sie
keine verwertbare Reaktion.
Empf.-LED, bestrahl mit anderer LED:
b) gelb, mit gelb bestrahlt = gut (dunkel ca. 1640; max.hell: ca. 480)
c) grün, mit grün bestrahlt = besser (dunkel ca. 1640; max.hell: ca.
300)
d) gelb, mit grün bestrahlt = beste (dunkel ca. 1640; max.hell: ca. 200)
e) grün, mit gelb bestrahlt = s. schlecht (dunkel ca. 1640; max.hell:
ca. 1610)
Fazit:
2c) grün/grün ist vielversprechend, zumal damit eine bidirektionale
optische Kopplung, durch beidseitige Umpolung der LEDs, möglich wird...
++++++++++++++++++++++++++++++++++++++++++
Das Testprogramm in Bascom, mit Ausgabe auf Terminalprog über
USB/serial(TTL) mit TX an PinB.4..:
$regfile = "attiny85.dat"
$crystal = 1000000
$hwstack = 40
$swstack = 16
$framesize = 32
Ddrb = &B000010
Dim A As Word
Open "ComB.4:1200,8,N,1,inverted" For Output As #1
Do
Set Portb.0
Waitus 40
Reset Portb.0
While Pinb.0 = 1
Incr A
Wend
Print #1 , "Counts: " ; A
A = 0
Loop
Close #1
End
++++++++++++++++++++++++++++++++++++++++++++++