Hallo, ich habe einen ATmega8, der über eine IR-LED Daten verschicken soll. Diese Daten werden von einem TSOP an einem anderen Mikrocontroller empfangen. Meine Frage ist jetzt, wie ich, möglichst sparsam 38kHz für die LED erzeugen kann. Timer2 ist bereits belegt, Timer0 und Timer1 sind noch frei. Es wäre schön, wenn die Modulationsroutine "von alleine" läuft, ich also zwischen Senden/nicht Senden einfach durch Ein-/Ausschalten des Timers umschalten könnte. Wenn der Timer selbstständig den Ausgang togglet, dann würde das ja nicht einmal Rechenzeit in Anspruch nehmen. Ich freue mich auf die Lösung von Euch Profis! :-)
Hallo, wo ist jetzt die Frage? Welcher Timer CTC kann und welche Pins er toggeln kann steht im Datenblatt. Wie man ihn programmiert auch. Wolltest Du jetzt die Init für einen der Timer haben? Hngt zumindest teilweise davon ab, mit welchen Takt der AVR überhaupt läuft... Gruß aus Berlin Michael
Da Timer 0 keine PWM kann, bleibt nur Timer 1. Was hier sinnvoll wäre, ist Modus 14: Damit kann man eine PWM mit frei einstellbarer Frequenz erzeugen. ICR1 wird daher auf F_CPU/38kHz-1 eingestellt. OCR1A auf etwa 1/4 davon für 25% Tastverhältnis, was bei IR Übertragungen üblich ist. Wenn du nun das COM1A1 Bit setzt, ist das 38kHz Signal am OCR1A Ausgang zu sehen, wenn du das Bit löschst, wird der normale Portwert an dem Ausgang ausgegeben.
Hi Benedikt,
>OCR1A auf etwa 1/4 davon für 25% Tastverhältnis, was für IR Übertragungen >üblich
ist.
Das Verstehe ich nicht. Müssen High- und Low-Pegel gleich lang sein und
zwar genau 1/(2 * 38kHz) ?
Nein, üblicherweise wählt man bei Infrarotübertragungen die Einschaltzeit deutlich kürzer als die Ausschaltzeit, so dass man den entweder Strom spart, oder den Spitzenstrom höher wählen kann, um eine höhere Reichweite zu erzielen.
Ok, irgendwie habe ich noch nicht alles verstanden. Wenn ich ICR1 auf F_CPU/38000 - 1 setze, muss der Timer dann mit Prescaler 1 laufen? Kannst Du mir vielleicht die Timer-Initialisierungszeilen kurz aufschreiben?
Anja schrieb: > Wenn ich ICR1 auf F_CPU/38000 - 1 setze, muss der Timer dann mit > Prescaler 1 laufen? Ja. > Kannst Du mir vielleicht die Timer-Initialisierungszeilen kurz > aufschreiben? Schau mal ins Datenblatt unter Mode 14, da siehst du alle Bits die du setzen musst.
Belastet ein Timer ohne Prescaler die CPU stärker, als einer, der mit Prescaler läuft?
>Belastet ein Timer ohne Prescaler die CPU stärker, als einer, der mit >Prescaler läuft? Nur, wenn das Programm dann dauernd in eine ISR springt. Dann wird zwar immer noch nicht der Controller belastet, aber der Programmablauf wird sehr zähflüssig.
Ok, danke. Wenn ich jetzt alles richtig verstanden habe, dann müsste folgender Code:
1 | TCCR1A |= (1 << WGM12) | (1 << WGM11); |
2 | TCCR1B |= (1 << WGM13) | (1 << CS10); |
3 | ICR1 = 14745600 / 38000 - 1; |
4 | OCR1A = (1475600 / 38000 - 1) / 4; |
den Pin OC1A (alias PB1) togglen. Und zwar zu 1/3 auf High und 3/4 auf Low. Stimmt das so?
Ja, und wenn du jetzt das COM1A1 Bit setzt, kommt das Signal an OC1A raus.
Hi, habe mir auch schon gedanken gemacht. Werde wohl ein Timer IC 555 zur 38kHz Takt Erzeugung benutzen. Damit sind die Timer weiterhin frei für andere Dinge. Im Internet gibts ein Programm, mit dem man die nötigen Bauteilwerte berechnen kann. Muss nur noch sehen wie ich den Takt am besten per ATmega ein und ausschalten kann. Vielleicht ist es auch für dich einen Alternative.
>den Pin OC1A (alias PB1) togglen. Und zwar zu 1/3 auf High und 3/4 auf >Low. Wenn du im TCCR1A noch COM1A1 setzt, dann brauchst du dich nicht per Hand um das Togglen kümmern.
Irgendwie klappt es nicht. Hier der komplette Code
1 | TCCR1A |= (1 << WGM12) | (1 << WGM11) | (1 << COM1A1); |
2 | TCCR1B |= (1 << WGM13) | (1 << CS10); |
3 | ICR1 = 14745600 / 38000 - 1; |
4 | OCR1A = (1475600 / 38000 - 1) / 4; |
5 | |
6 | sei(); // habe ich nicht vergessen ! |
Muss ich den Pin als Ausgang konfigurieren?
Ok, es funktioniert doch. Allerdings ist die Reichweite sehr bescheiden. Meine 5mm-IR-LED betreibe ich ohne Vorwiderstand. Gespeist wird der ATmega8L von einer CR2032. Warum ist die Reichweite so gering (10cm)?
Hier ist mein Code:
1 | char i; |
2 | while(1) |
3 | {
|
4 | for (i = 0; i < 20; i++) |
5 | {
|
6 | TCCR1A |= (1 << COM1A1); |
7 | _delay_us(500); |
8 | TCCR1A &=~(1 << COM1A1); |
9 | _delay_us(500); |
10 | }
|
11 | _delay_ms(10); |
12 | }
|
Der Empfänger schaltet immer, wenn der TSOP auf LOW geht eine LED an. Mit einer Fernseher-Fernbedienung ist die Reichweite gigantisch und auf die Reflexe von weit entfernten Wänden werden noch wahrgenommen. Mit dem µC allerdings erreiche ich gerade mal lächerliche 10cm...
In einer "normalen" Fernbedienung wird die LED mitunter auch mit einem deutlich höheren Strom gepulst. Ich meine, dort schon mal etwas von bis zu 1A gelesen zu haben! Allerdings hast du dort auch gerne 2-3 LEDs in parallel. _.-=: MFG :=-._
Eine CR2032 ist etwas schwach. Hast du einen großen Elko dran, der die kurzen Stromimpulse puffert? Hast du die LED direkt am AVR? Der kann bei 3V recht wenig Strom liefern. Rund 100mA Spitzenstrom über einen Transistor sollte man der LED schon gönnen.
Ok, jetzt hab ichs mal drauf ankommen lassen und hab anstelle der CR2032 zwei CR2016 genommen. Leider ist die Reichweite nicht wirklich gestiegen... Die Fernbedienung läuft doch auch mit 3V... wie schafft die das?
Hast du den Transistor eingebaut? Passt die LED auch zum Empfänger (Wellenlänge) und ist ausreichend gebündelt? Meine Fernbedienung mit AVR und einer CR2032 geht etwa 5-10m weit.
Wie schon gesagt: Mit mehr Strom! Schau mal ins Datenblatt was die LED bei kurzen Impulsen verkraftet und schalte sie mit einem Transistor und einem passenden Vorwiderstand. Portpins des AVRs schaffen nicht viel mehr als 20 mAh und das ist definitiv zu wenig. 100 mAh wären für den Anfang nicht schlecht. Evt auch mehr wenn du die Impulse noch kürzer machst (dann aber im Datenblatt nachsehen ob die LED das mitmacht).
Ok, dann baue ich jetzt so einen Transistor ein: Vcc o-------------+ | _ IR-Diode V -> - -> | An: Vcc _ |/ o---|___|----| NPN Aus: GND |> | GND o-------------+ Doch wie berechne ich den Vorwiderstand für die Basis? Ich verwende eine SFH4605 und möchte meine Schaltung mit ~5V (2*CR2016) betreiben. Dem Datenblatt entnehme ich, dass die LED bei 5V abraucht... http://catalog.osram-os.com/catalogue/catalogue.do;jsessionid=55A3A26878DBA85CC7146286618599F9?act=downloadFile&favOid=020000030000eb8b000100b6 Also wie muss ich den Basiswiderstand dimensionieren?
Anja schrieb: > Doch wie berechne ich den Vorwiderstand für die Basis? Rund 1k Ohm sind ok. Das ergibt etwa 4mA Basisstrom, was bei einer Stromverstärkung von >100 bei den typischen kleinen Transistoren wie BC337 ausreichend ist. > Ich verwende eine SFH4605 und möchte meine Schaltung mit ~5V (2*CR2016) > betreiben. Die SFH460x ist sehr gut, die habe ich auch verbaut. Gegenüber einer LED aus einer alten Fernbedienung hat sich die Reichweite mehr als verdoppelt. > Dem Datenblatt entnehme ich, dass die LED bei 5V abraucht... Die LED hält dauerhaft 100mA aus, kurzzeitig 1A. Da du rund 12% Tastverhältnis in der Sendeschleife verwendest, könntest du fast die 1A ausnutzen, so dass der mittlere Strom nur rund 100mA beträgt, aber das schafft die Batterie sowieso nicht. Daher würde ich den Strom auf 100-200mA auslegen. Etwa 22 Ohm als Vorwiderstand sollten rund 100-200mA fließen lassen.
Als Basiswiderstand dimensionierst du so dass der Transistor etwa den 5 bis 10-fachen Basisstrom bekommt, der nötig wäre um bei seiner Verstärkung den gewünschten Strom zwischen C und E fließen zu lassen. Beispiel: I_CE=300 mA, Verstärkung=100 -> Basisstrom = 3 mA * 10 = 30 mA. Bei 3 V macht das 3 V / 30 mA = 100 Ohm. Schau dir mal das letzte Diagramm von Seite 5 an. Dem kannst du den Impulsstrom bei vorgegebenen Pulszeiten und Tastverhältnis entnehmen.
Also mit Transistor und mehr Strom gehts jetzt wunderbar auch über 5m! Vielen Dank. Allerdings ist der 100µF-Tantal jetzt auch bitter nötig: Ohne stürzt der µC ab.
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.