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.
Glorb schrieb: > DDRC &= ~(1<<(PC0)); > if((PORTC&(1<<PC0))) count++; PINC, nicht PORTC Den Rest muss ich jetzt mal selber recherchieren.
Hmm Das hier
1 | 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.
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 } nochmal angepasst.
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!
d.h. ich habe etwa folgendes modell: Timer_ISR() { if((PINC&(1<<PC0))) count++; } void main() { timer_setup(); DDRC |= (1<<(PC0)); DDRC |= (1<<(PC1)); while(1) { cli(); PORTC |= (1<<(PC0)); // Phase Reverse Bias PORTC &= ~(1<<(PC1)); asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop"); DDRC &= ~(1<<(PC0)); sei(); } } ich stehe noch etwas auf dem schlauch wie man sieht, pseudocode zum ablauf ist willkommen.
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!
oh danke, das hätte etwas zeit erspart :). Allerdings muss ich das ganze sowieso Interrupt gesteuert bauen, von daher.
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 ++++++++++++++++++++++++++++++++++++++++++++++
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.