Forum: Mikrocontroller und Digitale Elektronik RC5 Modulation


von Jan H. (janiiix3)


Angehängte Dateien:

Lesenswert?

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.

von Jan H. (janiiix3)


Lesenswert?

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
}

von Karl H. (kbuchegg)


Lesenswert?

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)

von Jan H. (janiiix3)


Lesenswert?

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.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

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
von Jan H. (janiiix3)


Lesenswert?

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

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

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.

von Jan H. (janiiix3)


Lesenswert?

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?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Immer schwierig, zwei Teller gleichzeitig in der Luft zu halten...
http://www.makerconnect.de/index.php?threads/rc5-sende-routine.3729/

von Jan H. (janiiix3)


Lesenswert?

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.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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?

von Jan H. (janiiix3)


Angehängte Dateien:

Lesenswert?

Die Diode sendet schon was. Ca. 40cm Reichweite danach geht nichts mehr.
Aber es kommt nur Müll an.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Wo hast du denn da gemessen? Eine 36kHz oder 38kHz Modulation sehe ich 
da nicht.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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)?

von Jan H. (janiiix3)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Jan H. (janiiix3)


Lesenswert?

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 ???

von Karl H. (kbuchegg)


Lesenswert?

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
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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...

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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
von Karl H. (kbuchegg)


Lesenswert?

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
von #schlau #meier (Gast)


Lesenswert?

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

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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]

von Karl H. (kbuchegg)


Lesenswert?

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.

von Harald W. (wilhelms)


Lesenswert?

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

von Jan H. (janiiix3)


Lesenswert?

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
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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
von Jan H. (janiiix3)


Lesenswert?

Frank M. schrieb:
> 2. Timer für die Datenbits

Du meinst, für die Zeitbasis von 889µs?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von Wolfgang (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.