Hallo, ich bin gerade dabei eine RC5 Modulation auf die Beine zu stellen. Leider haut es noch nicht mit der Modulation hin. Das "HALF_BIT" Timing haut soweit hin. Komme dort auf ca. 880µs. Leider mache ich irgendwas gravierends falsch was die 36kHz Modulation angeht. Bei der Modulation bin ich mir sicher, dass ich dort "alles" falsch gemacht habe. Würde mich über hilfe freuen.
Hallo Profis, ich bekomme es leider nicht hin auf meinem RC5 - Decoder anständige Signal zu senden. Fernbedienung vom TV klappt wunderbar. Mein eigener "Kram" hingegen nicht. Könnte es an meinem Quellcode liegen? Würde mich freuen, wenn mal jemand drüber schauen könnte, der mehr Ahnung von C hat als ich laie...
1 | /*
|
2 | * Send_RC5.c
|
3 | *
|
4 | * Created: 24.06.2015 16:58:52
|
5 | * Author: Jan
|
6 | */
|
7 | |
8 | |
9 | #define F_CPU 16000000
|
10 | |
11 | #define RC5_HALF_BIT_TIME 8 // 8 * 110µs = 880µs
|
12 | |
13 | #define RC5_SEND_ON PORTD |= (1<<PD1)
|
14 | #define RC5_SEND_OFF PORTD &= ~(1<<PD1)
|
15 | #define RC5_SEND_TOGGLE PORTD ^= (1<<PD1)
|
16 | |
17 | #define RC5_SHOOT 890
|
18 | |
19 | #include <avr/io.h> |
20 | #include <avr/interrupt.h> |
21 | #include <util/delay.h> |
22 | #include <stdbool.h> |
23 | |
24 | |
25 | void rc5_send_command(uint16_t command); |
26 | void rc5_send_one(void); |
27 | void rc5_send_zero(void); |
28 | void delay_880(void); |
29 | void rc5_modulation(void); |
30 | |
31 | volatile static uint8_t rc5_half_bit_cnt, rc5_state; |
32 | uint16_t rc5_byte = 0x00; |
33 | |
34 | int main(void) |
35 | {
|
36 | DDRB |= (1<<PB7); |
37 | DDRD |= (1<<PD1); |
38 | |
39 | // TCCR0A = (1<<WGM01); // CTC TIMER0
|
40 | TCCR1B |= (1<<WGM12); // CTC TIMER1 |
41 | |
42 | // TCCR0B = (1<<CS01); // 8 ( ca. 110µs @ 16 MHz )
|
43 | TCCR1B |= (1<<CS10); // 1 ( ca. 72 kHz @ 16 MHz ) |
44 | |
45 | // TIMSK0 = (1<<OCIE0A); // OutputCompare0A
|
46 | TIMSK1 = (1<<OCIE1A); // OutputCompare1A |
47 | |
48 | // OCR0A = 0xE8;
|
49 | OCR1A = 221; // habe ein wenig mit den Werten gespielt |
50 | |
51 | sei(); |
52 | |
53 | |
54 | while(1) |
55 | {
|
56 | rc5_send_command(0b11000000001100); // switch tv on |
57 | }
|
58 | }
|
59 | |
60 | /* send a 14 bit command to the IR - Receiver */
|
61 | void rc5_send_command(uint16_t command) |
62 | {
|
63 | uint16_t send_byte = command; |
64 | |
65 | for (uint16_t x = 0 ; x < 14 ; x++) |
66 | {
|
67 | if (send_byte & 0x2000) |
68 | {
|
69 | rc5_send_one(); |
70 | }
|
71 | else
|
72 | {
|
73 | rc5_send_zero(); |
74 | }
|
75 | |
76 | send_byte <<= 0x0001; |
77 | }
|
78 | rc5_state &= ~(0x80); |
79 | }
|
80 | |
81 | /* send a logical one to the Receiver ( 1 --> 0 ) */
|
82 | void rc5_send_one(void) |
83 | {
|
84 | rc5_state |= 0x80; |
85 | RC5_SEND_ON; |
86 | _delay_us(RC5_SHOOT); |
87 | rc5_state &= ~0x80; |
88 | RC5_SEND_OFF; |
89 | _delay_us(RC5_SHOOT); |
90 | }
|
91 | |
92 | /* send a logical zero to the Receiver ( 0 --> 1 ) */
|
93 | void rc5_send_zero(void) |
94 | {
|
95 | rc5_state &= ~0x80; |
96 | RC5_SEND_OFF; |
97 | _delay_us(RC5_SHOOT); |
98 | rc5_state |= 0x80; |
99 | RC5_SEND_ON; |
100 | _delay_us(RC5_SHOOT); |
101 | }
|
102 | |
103 | void delay_880(void) |
104 | {
|
105 | while(1) |
106 | {
|
107 | if ((rc5_state & 0x01) == 0x01) |
108 | {
|
109 | rc5_half_bit_cnt = 0x00; |
110 | rc5_state &= ~(0x01); |
111 | break; |
112 | }
|
113 | }
|
114 | }
|
115 | |
116 | /* called every 110 µs */
|
117 | ISR(TIMER0_COMPA_vect) |
118 | {
|
119 | rc5_half_bit_cnt++; |
120 | |
121 | if (rc5_half_bit_cnt >= RC5_HALF_BIT_TIME) |
122 | {
|
123 | rc5_half_bit_cnt = 0x00; |
124 | rc5_state |= 0x01; |
125 | }
|
126 | }
|
127 | |
128 | /* 72kHz */
|
129 | ISR(TIMER1_COMPA_vect) |
130 | {
|
131 | if ((rc5_state & 0x80) == 0x80) |
132 | {
|
133 | RC5_SEND_TOGGLE; |
134 | }
|
135 | else
|
136 | {
|
137 | RC5_SEND_OFF; |
138 | }
|
139 | |
140 | |
141 | }
|
erste Frage: die 16Mhz sind gesichert? zweite Frage: mit einer Handy Kamera kannst du die LED flackern sehen? Der Vergleich mit deiner Fernbedienung zeigt, dass das Flackern beim Drücken einer Taste ungefähr gleich lang ist? (Ein Kommando dauert ca. 25ms, also grob 2 Zehntel Sekunden. Das kann man auch optisch durch hinsehen noch ganz gut abschätzen, ob das hinkommt)
Ja meine 16MHz stehen, aber nur der Interne RC Oszillator! Benutzen tue ich folgendes : Diode : TSAL6100 Empfänger : TSOP34538 Ich habe das Datenpaket mit dem Oszi nachgemessen, dass kommt soweit hin. Was mir aufgefallen ist, dass meine Schaltung (Sender) nicht wirklich eine große Weitreiche erreicht, hingegen meiner Fernbedienung. Als Vorwiderstand habe ich ~30Ohm gewählt bei 5VDC.
Jan H. schrieb: > Ja meine 16MHz stehen, aber nur der Interne RC Oszillator! Was benutzt du denn für einen MC? Der interne RC Oszillator liefert nur 8 MHz und müsste mittels PLL, die es aber nur in wenigen Tinys gibt, multipliziert werden. Ein Ansprechen der PLL sehe ich aber bei dir nicht. Interne 16MHz ohne solche Klimmzüge gibt es nicht. > Als Vorwiderstand habe ich ~30Ohm gewählt bei 5VDC. Das ist auch sehr wenig LED Strom. Fernbedienungen peitschen da bis zu 100mA im Pulsbetrieb in die IR LED. > eine große Weitreiche Das finde ich super - erinnert mich an die Nabelschweden - äh, Nebelschwaden.
:
Bearbeitet durch User
Matthias S. schrieb: > Jan H. schrieb: >> Ja meine 16MHz stehen, aber nur der Interne RC Oszillator! > > Was benutzt du denn für einen MC? Der interne RC Oszillator liefert nur > 8 MHz und müsste mittels PLL, die es aber nur in wenigen Tinys gibt, > multipliziert werden. Ein Ansprechen der PLL sehe ich aber bei dir > nicht. > Interne 16MHz ohne solche Klimmzüge gibt es nicht. > >> Als Vorwiderstand habe ich ~30Ohm gewählt bei 5VDC. > > Das ist auch sehr wenig LED Strom. Fernbedienungen peitschen da bis zu > 100mA im Pulsbetrieb in die IR LED. > >> eine große Weitreiche > > Das finde ich super - erinnert mich an die Nabelschweden - äh, > Nebelschwaden. Benutze einen MEGA2560. Meine UART habe ich auch auf 16000000MHz ausgelegt, klappt auch damit. Der Puls liegt bei ca. 100mA
Jan H. schrieb: > Benutze einen MEGA2560. Nö, damit hast du die internen 8MHz des RC Oszillators. Lies mal bitte 10.7 im Datenblatt. Es gibt 2 interne Oszillatoren, den 8MHz RC Oszillator und den 128kHz Watchdog. Das dein UART mit '16Mhz' Einstellung funktioniert, wundert mich nicht, denn wenn du ihn z.B. auf 19200 Baud konfigurierst und dann mit 9600 Baud benutzt, klappt das natürlich.
Matthias S. schrieb: > Jan H. schrieb: >> Benutze einen MEGA2560. > > Nö, damit hast du die internen 8MHz des RC Oszillators. Lies mal bitte > 10.7 im Datenblatt. > Es gibt 2 interne Oszillatoren, den 8MHz RC Oszillator und den 128kHz > Watchdog. > > Das dein UART mit '16Mhz' Einstellung funktioniert, wundert mich nicht, > denn wenn du ihn z.B. auf 19200 Baud konfigurierst und dann mit 9600 > Baud benutzt, klappt das natürlich. Wieso komme ich dann mit meinen 16MHz auf meine genau errechnete ISR Überläufe?
Immer schwierig, zwei Teller gleichzeitig in der Luft zu halten... http://www.makerconnect.de/index.php?threads/rc5-sende-routine.3729/
Genau, ich dachte ich mache einfach noch mal hier einen Theard auf (hätte ich drauf hinweisen sollen, sorry!) und jemand sieht vill. Einen Fehler direkt auf anhieb als Tagelang rum zu schreiben.
Jan H. schrieb: > habe das Datenpaket mit dem Oszi nachgemessen, dass kommt soweit hin. Wie weit ist "so"? Kannst du einfach mal ein paar Screenshots eines Pakets zeigen? > Was mir aufgefallen ist, dass meine Schaltung (Sender) nicht wirklich > eine große Weitreiche erreicht, hingegen meiner Fernbedienung. Wie ist dir das aufgefallen? Ich denke der tut noch gar nicht?
Die Diode sendet schon was. Ca. 40cm Reichweite danach geht nichts mehr. Aber es kommt nur Müll an.
Jan H. schrieb: > Die Diode sendet schon was. Ca. 40cm Reichweite danach geht nichts mehr. Habs nicht nachgerechnet: Du sendest mit 36kHz Modulation? Abweichungen nach oben/unten äußern sich in geringerer Reichweite. > Aber es kommt nur Müll an. Für mich sieht das Encoding auch ziemlich kompliziert aus. Das geht einfacher. Zum Oszi-Bild: Der letzte Puls ist auf jeden Fall zu lang. Bei Biphase-Kodierung (Manchester) kann es prinzipbedingt nur Pulslängen mit 1- oder 2-facher Länge geben. Warum ist das Signal auf dem Oszi invertiert (zu dem FB-Signal)?
Frank M. schrieb: > Für mich sieht das Encoding auch ziemlich kompliziert aus. Das geht > einfacher. Zum Oszi-Bild: Der letzte Puls ist auf jeden Fall zu lang. > Bei Biphase-Kodierung (Manchester) kann es prinzipbedingt nur Pulslängen > mit 1- oder 2-facher Länge geben. > > Warum ist das Signal auf dem Oszi invertiert (zu dem FB-Signal)? Encoding? Ich Codiere wenn nur was.
Frank M. schrieb: > Für mich sieht das Encoding auch ziemlich kompliziert aus. Im Programm ist noch jede Menge Müll von früheren Versuchen. So wie das bei Neulingen eben ist: eine einmal geschriebene Code Zeile wird auf keinen Fall gelöscht. Auch wenn sie keiner mehr braucht. Drum sieht der Code so groß aus.
Karl H. schrieb: > Frank M. schrieb: > >> Für mich sieht das Encoding auch ziemlich kompliziert aus. > > Im Programm ist noch jede Menge Müll von früheren Versuchen. So wie das > bei Neulingen eben ist: eine einmal geschriebene Code Zeile wird auf > keinen Fall gelöscht. Auch wenn sie keiner mehr braucht. > Drum sieht der Code so groß aus. Was genau meinst du ???
Jan H. schrieb: > Ja meine 16MHz stehen, aber nur der Interne RC Oszillator! Das kann doch der Mega2560 gar nicht. Mehr als 8Mhz sind mit dem internen Oszillator nicht drinn. Miss halt mal die Zeiten mit einem _delay_ms nach! Das ist nun wirkich nicht schwer. Häng eine normale LED an einen Pin an und lass sie mittels _delay_ms 1000 Millisekunden ein und 1000 Millisekunden aus blinken. Bei welchem F_CPU ergeben sich die 1 Sekunden korrekt?
1 | #define F_CPU 8000000UL
|
oder
1 | #define F_CPU 16000000UL
|
letzteres ist mit dem internen Oszillator nicht möglich.
:
Bearbeitet durch User
Matthias S. schrieb: > Wo hast du denn da gemessen? Ja, das wäre sehr interessant. Ohne Angabe der Messpunkte sind das nur Pixelhaufen. Das vierte Bit im "Meine_Sendung" sieht zudem schon recht seltsam aus. Zudem auch die Ruhepegel. Ich würde einfach sagen: solange das eine Bild nicht wie das andere aussieht, ist die Marschrichtung klar: Angleichen. Frank M. schrieb: > Du sendest mit 36kHz Modulation? Da ist keinerlei Modulation zu erkennen. Das was da zu sehen ist, ist ein rein digitales unmoduliertes Signal...
Jan H. schrieb: > Encoding? > > Ich Codiere wenn nur was. Wenn Du das Signal einer Fernbedienung aufzeichnest und dann entschlüsselst, dann decodierst Du das Signal. Das macht zum Beispiel IRMP. Wenn Du das Signal aufbereitest, um es zu senden, dann encodierst Du etwas. Das macht übrigens IRSND - zu finden hier: https://www.mikrocontroller.net/articles/IRMP#IRSND_-_Infrarot-Multiprotokoll-Encoder Lothar M. schrieb: > Da ist keinerlei Modulation zu erkennen. Das was da zu sehen ist, ist > ein rein digitales unmoduliertes Signal... Naja, wenn er einen TSOP zur Aufzeichnung verwendet, dann ist die Modulation bereits rausgefiltert. Dagegen spricht jedoch das invertierte Oszi-Bild. Leider hat er weder zur Modulation noch zur Aufzeichnung per Oszi etwas geschrieben, sondern meine Fragen geflissentlich ignoriert. Sein Problem, nicht meins.
:
Bearbeitet durch Moderator
Ich hätt halt mal einen Stufenplan gemacht * abklären der µC Frequenz. Vorher ist alles andere Makulatur. Darüber darf es keine Unklarheiten geben * dann bau ich mir den 38Khz Oszillator auf. Und den teste ich auch! Der TO hat ein Oszi. Anstatt da rumzuhampeln, mach ich mir ein Programm, dass mit der Timer-Einstellung ein Dauersignal auf den Ausgang ausgibt. Da häng ich das Oszi an, und da sehe ich nach, ob die gewollten 38kHz auch wirklich 38kHz sind. * und erst dann fange ich an, die Modulation des Trägers im Datentakt durchzuführen. WObei ich mir zuerst einfach mal eine Serie von logischen 1-en auf den Ausgang lege und mit dem Oszi nachmesse, ob die Burstlänge stimmt. Danach dasselbe mit lauter 0-en. Aus Spass an der Freude leg ich dann vielleicht auch mal abwechselnd eine logische 1 gefolgt von einer logischen 0 auf den Ausgang um zu sehen, wie die bei Manchestercoding zusammenlaufen. Aber das ist Kür, rein zur Erbauung. * und erst dann fang ich an mir darüber Gedanken zu machen, wie das 14 Bit Datenwort aufgebaut sein muss Klingt nach einem komplizierten Vorgehen? Mag sein. Ich weiss aber eines: wenn ich so vorgehen würde, dann würde das alles schon längst laufen. IMHO ist der Hauptfehler von Neulingen, dass sie nicht schrittweise geplant und gezielt vorgehen, sondern zu viel auf einmal wollen. Manchmal geht das gut, aber öfter als einem lieb ist landet man genau in der Situation des TO: nichts geht und keiner hat eine Ahnung warum nicht. Bei schrittweisen Vorgehen kann mir das nicht passieren. Jeder SChritt wird getestet und solange ich mich nicht davon überzeugt habe, dass alles in Ordnung ist, wird der nächste Schritt nicht begonnen. Und ja: die SChritte fangen bei den ganz einfachen Dingen an. Wenn mir wer erzählt, dass sein µC etwas kann, was laut Datenblatt vollkommen unmöglich ist, dann denk ich mir meinen Teil, was er im Vorfeld alles geprüft hat.
:
Bearbeitet durch User
Habe mich damit auch schon beschäftigt und habe eine Fernbedienung für meinen philips-tv gebaut... beim Code habe ich mir [[sprut.de]] zur Hilfe genommen. Wenn du möchtest kann ich dir diesen Code gerne zukommen lassen, allerdings in Assembler. Gruß MC Supergeilermegaherrscher
Karl H. schrieb: > Ich hätt halt mal einen Stufenplan gemacht Ja, auf jeden Fall. > * dann bau ich mir den 38Khz Oszillator auf. [Korinthe] RC5 verwendet 36kHz [/Korinthe]
Frank M. schrieb: > Karl H. schrieb: >> Ich hätt halt mal einen Stufenplan gemacht > > Ja, auf jeden Fall. > >> * dann bau ich mir den 38Khz Oszillator auf. > > [Korinthe] RC5 verwendet 36kHz [/Korinthe] :-) Mag sein. Aber der von ihm verwendete TSOP ist ganz wild auf 38 Nicht das es jetzt eine grosse Rolle spielen würde. So eng sind die Filter auch wieder nicht.
Karl H. schrieb: > Bei schrittweisen Vorgehen kann mir das nicht passieren. Jeder SChritt > wird getestet und solange ich mich nicht davon überzeugt habe, dass > alles in Ordnung ist, wird der nächste Schritt nicht begonnen. Ein solches Vorgehen war schon immer das eines guten Entwicklers. Weit vor der Erfindung des Mikroprozessors
So, ich habe den PIN mal Togglen lassen. Wenn ich meinen Timer1 (CTC) laufen habe, komme ich auf ca. 600ms bei einem _delay_ms(500); und ohne Timer auf 504ms... Ist wohl eine blöde Idee diese Verfahren mit dem externen RC Oszillator zu erledigen?
:
Bearbeitet durch User
Jan H. schrieb: > Ist wohl eine blöde Idee diese Verfahren mit dem internen RC Oszillator > zu erledigen? Nein, das geht durchaus. Es gibt zwar manche Geräte der Unterhaltungsindustrie, die vom Timing her ziemlich pingelig sind, aber meist kommt man mit dem internen RC-Oszillator bei 8MHz aus. Was brauchst Du: 1. Timer für Modulation, PWM mit 36 bzw. 38 kHz 2. Timer für die Datenbits Dann ist der verbleibende Code minimal und muss sich nur noch um das Herausschieben der Bits zu kümmern. Delays brauchst Du dann auch nicht mehr, das erledigen die beiden Hardware-Timer. Geh einfach so vor, wie Karl Heinz es skizziert hat. Mit der Brechstangen-Methode, alles auf einen Schlag zu erledigen, kommst Du nicht weiter. Dafür fehlt es Dir einfach an Know How.
:
Bearbeitet durch Moderator
Jan H. schrieb: > Frank M. schrieb: >> 2. Timer für die Datenbits > > Du meinst, für die Zeitbasis von 889µs? Ja, genau. Ein Overflow-Interrupt bietet sich dafür an.
Karl H. schrieb: > Aber der von ihm verwendete TSOP ist ganz wild auf 38 Sooh wild nun auch wieder nicht. Die Empfindlichkeit sinkt beim 0.95-fachen der Nennfrequenz auf 70% und das würde die Reichweite mal gerade auf 84% schrumpfen lassen. Das merkt man fast gar nicht.
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.