Forum: Mikrocontroller und Digitale Elektronik RC5 von Danneger auf ATmega8 - seltsames Verhalten


von Martin (Gast)


Lesenswert?

Hallo,

ich habe einen TSOP34838 an PB0 an einem ATmega8L hängen.

Jetzt möchte ich gerne RC5-Signale von einer Fernbedienung auswerten.

Folgende Anpassungen habe ich vorgenommen:

main.h
1
#define  xRC5_IN PINB
2
#define  xRC5    PB0
3
#define  XTAL    1000000   // Interner Oszillator, 1MHz

Der Code läuft soweit, als dass ich
1
RC5-Dekoder:
auf dem Terminal empfange. Allerdings kommt daraufhin beim Drücken der 
Fernbedienungstasten keine weitere Ausgabe. Der OUT-Pin des TSOP34838 
reagiert allerdings auf die Fernbedienung; ich habe das mit dem 
Oszilloskop untersucht.

Daraufhin habe ich folgende Debug-Erweiterung in den Code eingepflegt:

main.c
1
for(;;){        // main loop
2
    cli();
3
    i = rc5_data;      // read two bytes from interrupt !
4
    rc5_data = 0;
5
    sei();
6
    if( i ){
7
      DDRB = i;        // LED output
8
      putchar(( i >> 11 & 1) + '0');  // Toggle Bit
9
      putchar(' ');
10
      itoa( i >> 6 & 0x1F, s, 10);  // Device address
11
      puts( s );
12
      putchar(' ');
13
      itoa((i & 0x3F) | (~i >> 7 & 0x40), s, 10); // Key Code
14
      puts( s );
15
      puts( "\n\r" );
16
    }
17
18
    // -------------- BEGIN: DEBUG -----------------
19
    if (!(xRC5_IN & (1 << xRC5)))
20
    {
21
      puts("a");
22
    }
23
    // -------------- END: DEBUG -------------------
24
  }

Jetzt erscheinen auf dem Terminal beim Drücken einer Taste auf der 
Fernbedienung lauter "a". Der Mikrocontroller kann also Signale 
empfangen. Warum kann er aber nicht den RC5-Code dekodieren und per UART 
raussenden?

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Vielleicht sind die 1 MHz zu knapp bemessen, um die RC5 Auswertung in 
der Interruptroutine zu machen. Du könntest mal versuchen den Atmega8 
mit intern 8 MHz zu takten.

Dazu steht was im Abschnitt Calibrated Internal RC Oscillator mit Table 
9. Internal Calibrated RC Oscillator Operating Modes im Datenblatt.

Mit 8 MHz und einem Attiny2313 funktioniert Peters Code 
(http://www.mikrocontroller.net/articles/Pollin_Funk-AVR-Evaluationsboard#RC5_Empf.C3.A4nger)

von Martin (Gast)


Lesenswert?

Ich habe jetzt per Fuse-Bit den internen Oszillator auf 8MHz gestellt 
und es auch in den defines entsprechend geändert:

main.h
1
#define  XTAL    8000000   // Interner Oszillator, 8MHz

Leider dekodiert er es immernoch nicht...

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Hmm. Bist du sicher, dass die Fernbedienung RC5 sendet? Ich hatte mir 
extra eine Universal-FB beschafft und auf RC5 eingestellt (war einfacher 
als einen RC5-Sender aufzubauen).

Dein Debugcode springt ja bei fast jedem Gezappel an der Datenleitung an 
und der IR-Empfänger bei jedem IR-Lichtblitz mit richtiger 
Grundmodulation (um die 38 KHz). Der RC5 Decodercode in der 
Interruptroutine prüft aber, ob die Lichtblitze auch wie RC5-Kommandos 
aussehen.

Hast du die Möglichkeit die Datenleitung vom Sensor auf ein Oszilloskop 
zu geben und eine Kommandofolge aufzuzeichnen? Dann sieht man rel. 
leicht, ob es RC5 ist (http://www.sbprojects.com)

von Martin (Gast)


Lesenswert?

Ja, es handelt sich defintiv um eine RC5-Fernbedienung!

Es ist die "HQ RC Univers 29", eingestellt auf den Code 335
http://wiki.ctbot.de/index.php/RC_Univers_29

von JojoS (Gast)


Lesenswert?

am Port B soll das IR Bit eingelesen werden und gleichzeitig der Code 
ausgegeben werden?
1
DDRB = i;        // LED output
ist sowieso falsch, für die Ausgabe müsste
1
PORTx = i;
gesetzt werden.

von Martin (Gast)


Lesenswert?

Ich habe die Zeile
1
DDRB = i;        // LED output
gelöscht. Trotzdem klappt das Dekodieren nicht.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Beim Attiny2313 musst ich auch die Initialisierung vom Timer (Register 
für den Vorteiler) ändern (s. Link oben). Möglicherweise musst du 
ähnliches für den Atmega8 machen. Der Code wurde ja ursprünglich nicht 
für den Atmega8 geschrieben...

von Martin (Gast)


Lesenswert?

>Beim Attiny2313 musst ich auch die Initialisierung vom Timer ändern. 
>Möglicherweise musst du ähnliches für den Atmega8 machen.

Habe folgende Zeilen und Register überprüft:

main.c
1
TCCR0 = 1<<CS02;      // auch bei Mega8: Prescaler=256
2
TIMSK = 1<<TOIE0;      // auch bei Mega8: OF-Interrupt

Und für richtig empfunden.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Ich habe auch noch einen Atmega8 zuhause und kann den Code am Wochenende 
darauf ausprobieren (nur wenn es regnet ;-)

von Bohrer (Gast)


Lesenswert?

habe vor kurzem mit dem selben Code und Problem gekämpft.

Ich habe die Compileroptimierung abgeschalten dann gings.

von Oliver (Gast)


Lesenswert?

>Ich habe die Compileroptimierung abgeschalten dann gings.

Das fehlende volatile bei rc5_data hinzuzufügen, wäre auch eine Lösung 
gewesen.

Wie schrieb Peter Danneger selber:

>Versuch mal:

>volatile uint rc5_data;

>Der GCC hat die unangenehme Eigenschaft, Zugriffe auf globale Variablen
>wegzuoptimieren.
>Der Aufruf einer externen Funktion hindert ihn daran, da diese ja die
>Variable ändern könnte.

>Ich falle da auch regelmäßig drauf rein.

Oliver

von Frank L. (franklink)


Lesenswert?

Hallo,
schau mal hier nach, hier verwende ich die Routine von Peter mit einem 
externen 4 Mhz Quarz.

Beitrag "Platine und Software für ALPS-Motorpotentiometer"

Allerdings nutze ich einen TSOP1736.

Gruß
Frank

von JojoS (Gast)


Lesenswert?

bei mir lief es auf einem Mega32 und Optimierung nach size war ein, 
allerdings noch mit einem älteren gcc 3.4.3. Dann habe ich in meinem 
Code noch ein _delay_ms(10.0); in der mainloop drin, weiss aber nicht 
mehr ob das wirklich nötig war.

von Martin (Gast)


Lesenswert?

>volatile bei rc5_data hinzuzufügen
Das war's! Vielen Dank! :-)

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.