Hallo zusammen, ich bin vor kurzem neu in die Mikrocontroller-Programmierung eingestiegen und hätte da eine, vermutlich recht banale Frage: und zwar versuche ich eine Fernbedienung zu programmieren. Ich habe die Trägerfrequenz und das Timing der einzelnen Tasten herausgefunden und versuche dieses nun in einen Controller zu programmieren. Leider scheitere ich schon an der ersten Hürde: wie kann ich die Trägerfrequenz von 38kHz mit einem Controller erzeugen? Geht das überhaupt? Beim googeln habe ich so gut wie nichts gefunden. :-( Alles was ich herausgefunden habe ist, dass ich mit Hilfe der Pulsweitenmodulation und einem D/A-Wandler evtl. die Trägerfrequenz erzeugen kann. Stimmt das oder gibt es vielleicht noch eine einfachere Möglichkeit? Ich programmiere die Atmel ATMega-AVR-Controller mit dem von Atmel angebotenen Entwicklerboard und der dazugehörigen Software. Vielen Dank und Gruß Markus
Wenn Du einen Timer nimmst, diesen im CTC-Mode betreibst und den Timer mit dem Output-Compare-Register auf den richtigen Teilerfaktor begrenzt und bei jedem Output-Compare-Event den entsprechenden OCx-Pin wackeln läßt, kannst Du nahezu jede Frequenz mit einem Tastverhältnis 50:50 erzeugen. Und dies geht alles in Hardware, ohne zusätliche Rechenzeit. Lies mal im Datenblatt zu Deinem Controller die Sektion "Timer" durch. Nun mußt Du nur noch eine IR-LED an diesen wackelnden Pin und mit einem Widerstand an einen anderen Pin anschließen, an dem Du die Codes sendest. Ohne weitere Außenbeschaltung hast Du so genau das, was Du brauchst. Die Anschluß-Polarität der LED richtet sich danach, ob Dein zu sendendes Signal High- oder Low-Aktiv ist. Der wackelnde Pin wird in jedem Fall die LED für 50: der Zeit ein- und wieder ausschalten, wenn der passende Gegenpegel an dem Sendepin anliegt.
Ersteinmal vielen Dank für die super schnelle Anwort und wie es aussieht recht einfach Lösung des Problems. :-) Was ich aber dabei nicht verstehe ist die Reihenschaltung von PinX -IR-Led - Widerstand - PinY. An PinX lege ich das Trägersignal und an PinY z.B. 110011100 an. Dann soll ja das Trägersignal genau dann gesendet werden, wenn eine 1 an PinY anliegt. Ich verstehe aber nicht, wie die Reihenschaltung genau dieses Verhalten zeigen soll? Wäre über eine kurze Erklärung echt dankbar.
Du brauchst doch keinen 2. Pin. Du kannst einfach im Compare-interrupt die Anzahl der Perioden mitzählen (z.B. 20) und dann ab dem nächsten Compare die Pinaktion auf dauernd High umstellen. Dann die Pause zählen, Pinaktion wieder auf Toggle usw. Damit hast Du immer glatte Impulse ohne Spikes. Peter
@Peter: Wenn man einen USART-Pin und den OCx-Pin benutzt, kann man ziemlich einfach ein serielles Signal moduliert übertragen...
@Rahul ??? Welche FBs haben denn so einen Code ? Ich kenne nur die mit unterschiedlichen Puls-/Pausezeiten oder Manchester und das geht definitiv nicht per USART. Peter
Das ist schon klar, nur kann man damit eigene Übertragungen auf kurze Distanz machen, wenn nicht sogar über Glasfaser (nicht ausprobiert). Deine Variante ist universell...
@Peter: Den 2. Pin brauchst Du, um die Daten auf die LED zu bringen. Der erste Pin (OCx) toggelt immer fleißig den Träger, über Hardware-Timer ohne Rechenzeit. Wenn der Pegel vom DatenPin (2) dem Träger-Pin (1) gegenüber ein in Flußrichtung der LED passendes gegensätzliches Potential hat, leuchtet die LED für diese Zeit, geht aus wenn der Träger-Pin wieder umtoggelt und dann wieder an und so fort. Somit hast Du den aus Pin 2 laufenden Daten entsprechende Trägerpakete, ohne zusätzlichen Programmieraufwand. Pin 2 kann ein UART-Ausgang sein oder eben derjenige, an dem die Ferbedienungsdaten repliziert werden (in diesem Falle). Natürlich kann man einen Pin sparen, braucht dann aber eine zusätzliche ISR, die ständig mitlaufen muß.
das ganze macht aber wirklich nur SInn, wenn du mit der UART-Hardware die Daten senden willst - in allen anderen Fällen werden die Daten per Software bereitgestellt. Und dann macht dein Verfahren keinen Sinn mehr. Statt per Software einen weiteren Pin mit den Daten zu schalten, kann man doch lieber gleich den Timer beeinflussen.
KISS!!! Die led an den OC und an VCC oder Masse (natürlich mit Vorwiederstand) und dann in der Software den Timer an und ausschalten. bei fclk = 8 MHz ist der teiler 210. also genügend zeit den timer an und aus zu schalten. und wenn du es in hardware zählen willst, dann verbindest du den Timer-clock pin mit dem OC-Pin und stellts dann im 2. Timer die Anzahl der Impulse ein
@crazy horse: >>...Statt per Software einen weiteren Pin mit den Daten zu schalten, >>kann man doch lieber gleich den Timer beeinflussen. Keinen WEITEREN Pin schalte ich per Software, sondern nur den Datenpin, der Timer wird nur einmal initialisiert und klappert dann mit 38kHz los, um den kümmere ich mich dann gar nicht mehr. Lediglich die Datenbereistellungsroutine läuft immer wieder durch, für meinen Zweck freilich über UART. Die Datenbereitstellungsroutine kann natürlich auch die OCx-Pin-Bits im Timerregister löschen und setzen, so daß der Pin beim Abklemmen vom Timer auf das zuvor festgelegte Potential zurückkippt. Dann spart man sich den anderen Pin - das ist wohl korrekt.
Vielen Dank für die vielen Vorschläge. :-) Ich werde mal in nächster Zeit schauen, welche Lösung für mich die beste ist. Danke + Gruß Markus
@travelrec: ich habe schon verstanden, was du meinst, du aber wohl nicht, was ich gesagt habe. Variante 1: Daten kommen per Hardware-UART, dann macht deine Vorgehensweise Sinn, steht auch oben. Variante 2: Daten kommen in irgendeiner Art anders kodiert, also Bit für Bit per Software - dann macht es keinen Sinn. Zum Zeitpunkt, wenn die Software den Datenpin schaltet, kann die Software genausogut den Modus des 38kHz-Timers ändern, von toggle auf clear und zurück beispielsweise. Der Softwareaufwand ist gleich, den zus. Pin braucht man dann nicht.
Hmm, weiß nicht, warum nimmst Du nicht einfach den dafür direkt vorgesehenen ATTiny28L? Der einzige nachteil von dem Ding ist, das er nur HV parallel Programming versteht, man braucht also ein STK500 oder so. Di Software für RC5 gibt es fix und fertig als Appnote auf Atmels Webseite inclusive der Assebmlersourcen. Sowas liegt fertig zusammengelötet hier, im Wesentlichen braucht man noch einen Schalttransistor, eine IR LED und einen 455 oder besser 432 Khz Resonator. Gruß, Holm
Die Fernbedienung ist von Sony und benutzt leider nicht den RC5 Code. Ich habe bisher nur die Signale analysieren können, habe aber bisher nicht rausfinden können, welcher Code diese Fernbedienung verwendet. Ich habe auch schon den Sony-Code (Bezeichnung finde ich gerade nicht) verglichen, aber der passt auch nicht. Wer sich das Signal mal anschauen möchte findet es hier: http://home.arcor.de/mareichert/Signal1.jpg
@ Crazy horse: Alles klar, danke für den Hinweis, hatte ja schon laut drüber nachgedacht ;-).
@markus: Wer mißt, mißt Mist. Dir wurde doch schon gesagt, daß die Grenzfrequenz Deiner Soundkarte um mindestens eine Größenordnung unter dem liegt, was Du brauchst um das Signal richtig darstellen zu können? Wenn Sony dann ist das mit höchster Warscheinlichkeit SIRCS... Gruß, Holm
Das weiss ich... meine Soundkarte hat eine Samplingrate von 44100Hz. Das Signal wo abgebildet ist hat ca. 6200 Hz. Dann bleibt ein Aliassiganl nach Shannon von 38kHz übrig. Ich dachte auch es wäre SIRCS, aber soweit ich rausgefunden habe hat SIRCS eine Trägerfrequenz von 40kHz. Das passt nicht. Bei meinen Messungen ist halt das Problem, dass ich kein Speicher-Oszi habe und nicht weiss, wie ich ansonsten dieses kurze Signal messen soll bzw. kann.
Sorry, verschrieben... das Aliassignal sind natürlich die 6,2kHz. Dann bleibt eine Trägerfrequenz von 38kHz übrig.
Sieh das mit der Trägerfrequenz mal nicht so verbissen, die filtert der Empfänger eh wieder raus. Das was interessant ist, ist das Protokoll was übrig bleibt. Die Trägerfrequenz enthält keinerlei interessante Information, sondern dient dem Infrarotempfänger dazu, sein Signal aus dem Sumpf herausfiltern zu können. So lange Dein Träger also durch den Filter im Empfänger paßt, hast Du mit einer anderen Trägerfrequenz kein Problem. Gruß, Holm
das Problem bei mir ist nur, dass der Empfänger fest vorgegeben ist und ich deswegen die Signale der Fernbedienung herausfinden muss. Aber im Prinzip ist es ja kein Problem die Trägerfrequenz so lange zu verändern, bis der Empfänger sie erkennt. Ich habe ja nur den Bereich zwischen 38 und 40 kHz. Nachher im Programm dürfte das ja bei entsprechender Programmierung nur das Ändern einer Konstanten ausmachen.
@Markus ich weiss ja nicht mit welcher Hardware gemessen wird, aber z.B. mit einer Photodiode und einem Onboard Soundchip kann man bei 44KHz Samplerate diese Signale ganz gut analysieren (s. Bild, Pulse ca. 0,6ms, Pausen je nachdem 0,6ms oder 1,2ms). Gruss Frank
@frankieboy genau so habe ich es auch gemacht. (vgl. weiter oben im Thread) Daher kommen auch meine 38kHz für die Trägerfrequenz und mein Timing der einzelnen Tasten.
@Markus was mich nur wundert, wenn ich das aus der Vergrößerung richtig sehe, die Punkte für je eine Abtastung stehen. Eine Periode wird dann mit ca. 10 bis 20 Samples erfasst. Bei 44,1 Khz hat man aber eine Sampleperiode von ca. 23 us und bei der vergrößerten Darstellung (s. Bild) kann man die Daten eigentlich recht gut ausmessen. Eine symmetrisches Signal (je 0,6ms) würde dann mit mehr als 50 Samples erfasst. Ist das Signal hinter dem Empfänger gemessen oder ist es das Sendesignal der Led? Gruss Frank
@frankieboy Das Signal ist das Sendesignal der LED. Ich verstehe aber ganz ehrlich gesagt nicht, auf was du hinaus möchtest. Habe ich falsch gerechnet?
Ich weiss nicht ob das schon erwähnt wurde (hab den thread nicht durchgelesen) aber du kannst einfach einen externen 38kHz oszilator nehmen und den über einen port pin schalten dann hasst du immer deine 38kHz
@ Marius: Du weißt doch - so wenig externe Bauteile, wie möglich. Man hat doch einen Controller. Ich mach den ganzen Kram in einem Tiny2313 mit 15% Flash-Speicherauslastung und vielleicht 5% Rechenlast und eben einem Widerstand und einer LED und einem 4MHz-Schwinger...
den swinger kannst du dir eigentlich auch sparen oder? da kann man doch den internen rc-oszi nehmen (dann bekommt man zwar nicht genau 38khz aber das macht meistens nichts)
@Markus Es geht nicht um das Rechnen, sondern um das Messergebnis. Ich denke, das die Amplitude viel zu gering ist, um etwas erkennbar zu messen. Stelle mal im Aufnahmemixer der Soundkarte den Eingangsregler so ein, das möglichst die Soundkarte zu 50% oder mehr ausgesteuert wird (siehe mein Bild SONY_HR.GIF weiter oben) oder benutze nicht den Line-In sondern den MIC-Eingang. Sample dann noch einmal und schneide alles überflüssige weg, so das nur ein Tastendruck übrigbleibt. Gruss Frank
Soviele unqualifizierte Aussagen habe ich ja schon lange nicht mehr gehöhrt.
ich hatte mal schnell ein kleines einfaches demo geschrieben für avr16 8mhz. die irdiode geht bei mir vom pinb0 (kann beliebig sein) über einen 100ohm widerstand an +5volt. der code kann mit dem rc5-programm aus diesem forum empfangen werden. muss noch so angepasst werden, das noch andere mhz genommen werden können. ich kann alle rc5-code zahlen senden. der code: #include <avr/io.h> #include <avr/interrupt.h> #include <avr/signal.h> #include <string.h> #include <stdint.h> #define IR_LED_PORT PORTB #define IR_LED_PIN PB0 #define IR_LED_DDR DDRB #define IR_LED_ON IR_LED_PORT |= (1<<IR_LED_PIN) #define IR_LED_OFF IR_LED_PORT &= ~(1<<IR_LED_PIN) //89ms pause void ms_89(void) { uint32_t zaehler; for (zaehler=0; zaehler<118666; zaehler++) asm volatile("nop"); } void halbbit_high(void) { uint8_t i,zaehler; //890us Impuls mit 36kHz senden //Bei 28us Periodendauer ergibt das 32 Impulse for(i=0; i<32; i++) { IR_LED_ON; for (zaehler=0; zaehler<18; zaehler++) asm volatile("nop"); IR_LED_OFF; for (zaehler=0; zaehler<18; zaehler++) asm volatile("nop"); } } void halbbit_low(void) { uint16_t zaehler; //890us Pause for (zaehler=0; zaehler<1186; zaehler++) asm volatile("nop"); } //Eine 0 oder 1 senden void Send_Bit(uint8_t code) { if (code==0) { halbbit_high(); halbbit_low(); } else { halbbit_low(); halbbit_high(); } } void send_code(uint8_t toggle, uint8_t address, uint8_t command) { uint8_t mask,i; Send_Bit(1); //Erstes Startbit=1 Send_Bit(1); //Zweites Startbit=1 //Togglebit if(toggle==0) { Send_Bit(0); } else { Send_Bit(1); } //5 Bit Addresscode mask=0x10; //Beginn bei MSB for(i=0; i<5; i++) { if(address&mask) //Send 1 { Send_Bit(1); } else //Send 0 { Send_Bit(0); } mask>>=1; //Nächstes Bit } //6 Bit Kommandocode mask=0x20; //Beginn bei MSB for(i=0; i<6; i++) { if(command&mask) //Send 1 { Send_Bit(1); } else //Send 0 { Send_Bit(0); } mask>>=1; //Nächstes Bit } //Übertragung komplett PORTB=0; //IR-LED abschalten ms_89(); // warte 89ms } int main(void) { IR_LED_DDR|=(1<<IR_LED_PIN); uint8_t command,i; command=32; for (i = 14; i < command; i++) { send_code(1,7,i); // toggle, addresse, commando } }
@frankieboy vielen Dank für Deinen Vorschlag, aber ich komme in den Genuß eines Speicheroszis. Damit sollte es dann doch möglich sein, das Signal ganz genau inkl. Amplitude zu messen. @Osterhase wenn du so davon überzeugt bist, dass das alles unqualifizierte Kommentare sind - dann mach doch mal einen besseren. Andere angreifen kann jeder. Und die restlichen, die sich an diesem Thread beteiligen versuchen mir wenigsten zu helfen!!! @pebisoft Vielen Dank für die Bereitstellung deines Codes. Ich werde ihn mir mal die nächsten Tage genauer anschauen. Eigentlich hatte ich ja vor in Assembler zu programmieren. Aber man ist ja flexibel. :-)
ich kann dir auch eine assembler-source-datei von fastavr-basic erstellen für den rc5-code. die kannst du dann mal anschauen. die dann auch mit dem assembler avrasm32 von avrstudio verarbeitet werden kann. meine mail : pebisoft@arcoer.de
verbesserung meienr mail: pebisoft@arcor.de mfg pebisoft
Weil wir grad beim Thema sind - gibts irgendeine Software, die mir FB-Signale aufzeichnen kann (möglichst als Bitmuster, nicht die Soundkarten-Variante)? Ich habe hier einen simplen selbstgebauten Empfänger, der z.B. mit LIRC wunderbar zusammenspielt - ich kann toll meinen PC fernbedienen. Aber jetzt hätte ich gern die Codes, die der Empfänger sieht - gibts da auch irgendwie eine Möglichkeit mit LIRC? Das Problem besteht darin, dass ich irgendwann mal einen Beamer anschaffen möchte und diesen von einem Mikrocontroller per Infrarot fernbedienen will. Ich weiss aber nicht, was für ein Protokoll das sein wird - gibts eine Möglichkeit ein FB-Signal "aufzuzeichnen" und das dann als Bitmuster auf den µC zu übertragen? Lernbare Fernbedienungen müssen das ja auch irgendwie können...
wenn du LIRC unter linux benutzt dann gibt es dazu eine Erweiterung, schau dich einfach mal auf der Seite um. Ich habe auch mal danach gesucht, aber nix gefunden. Ich habe erst versucht ein einfaches empfänger-programm selbst zu schreiben aber das ging nicht (ich glaub ich konnte die zeitabstände nicht genau genug messen). Ich habe schließlich die soundkarten-variante benutzt.
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.