Forum: Mikrocontroller und Digitale Elektronik TSOP1736 - Auslesefrage.


von Draco (Gast)


Lesenswert?

Hiho,

ich habe hier einen TSOP1736 an einem Atmega8 (8 Mhz, kein Teiler für 
Int!) mit einem 10k PullUp Wiederstand gegen VCC stehen.

Mit meiner kleinen Routine:
1
 void Timer2verflow_ISR() org IVT_ADDR_TIMER2_OVF
2
 {  
3
    if(PINB.B3 == 0) {runner++;Ok = 1;}
4
    
5
    if(PINB.B3 == 1 && Ok == 1)
6
    {
7
               itoa(text,runner);
8
               UART1_Write_Text(text);UART1_Write_Text(" ");
9
               runner = 0;
10
               OK=0;
11
    }
12
 }
13
14
15
...
16
17
     SREG_I_bit = 1;
18
     TOIE2_bit  = 1;                                     
19
     TCCR2      = 1;
20
...

messe ich die Laufzeit des TSOP Signales, jedoch habe ich so meine 
kleinen Probleme damit. Als Ausgabe bekomme ich folgendes.:
1
85 16 19 16 38 16 16 6 2 16 18 11 30 6 30 15 16 6 2 16 5 29 16 16 7

Bei vielen verschiedenen Fernbedienungen bekomme ich immer andere Signal 
rein. Was mich nun stutzig macht ist die erste Laufzeit (oben die 85) 
diese ändert sich sehr starkt zu anderen Fernbedienung, mal mehr (bis zu 
270) mal garnicht da. Desweiteren dachte ich das die Daten aus 14 
Halb-Bit bestehen, jedoch sie sind aber um einiges länger?! Kann ich mir 
irgendwie die Laufzeit errechnen?!

Viele Fragen, für viele ist die Lösung auch selbstverständlich, ich 
jedoch blicke gegen einen Uhrwald :/ Das Datenblatt hilft mir leider 
auch nicht weiter.

von Matthias L. (Gast)


Lesenswert?

1
itoa(text,runner);
2
3
UART1_Write_Text(text);UART1_Write_Text(" ");

itoa braucht sehr viel Zeit. Ich würde das nicht in einem Interrupt 
machen.

Und die UaRT-Funktion, was macht die? Wartet die intern auf das 
Rx-data-reg-empty-flag? Oder schreibst du das in einen Puffer, der per 
Int abgearbeitet wird? Falls ersteres, dann wartest du bis der komplette 
String versendet ist, bevor du weitere Flanken beachtest!

von Volker S. (volkerschulz)


Lesenswert?

Abgesehen davon ist das Ausgangssignal des TSOP active low, oder nicht? 
Da muss der UART-Puffer doch schon ueberlaufen bevor ueberhaupt das 
Startbit empfangen wurde.

Welches IR-Protokoll benutzt Du?

Willst Du wirklich ueber die Laufzeit gehen, dann setz die UART auf 
115200bps, bau Dir einen Timer mit 36kHz-Interrupt-Frequenz und schieb 
bei jedem Interrupt den Portstatus in ein Byte-Register. Ist ein Byte 
voll, schick es ueber die UART raus und fang von vorne an.


Volker

von Draco (Gast)


Lesenswert?

Matthias Lipinsky schrieb:
> itoa braucht sehr viel Zeit. Ich würde das nicht in einem Interrupt
> machen.

Jep, klingt logisch, das erklärt auch den ersten hohen Wert und die 
anderen tiefen.

Volker Schulz schrieb:
> Abgesehen davon ist das Ausgangssignal des TSOP active low, oder nicht?

Richtig, deswegen lese ich ja auch die LowBits (if(PINB.B3 == 0)) aus.

Volker Schulz schrieb:
> Welches IR-Protokoll benutzt Du?

Es "sollte" eigentlich RC5 sein, jedoch habe ich... wie gesagt... bei 
jeglicher Fernbedienung andere Zeitwerte.

Volker Schulz schrieb:
> bau Dir einen Timer mit 36kHz-Interrupt-Frequenz und schieb
> bei jedem Interrupt den Portstatus in ein Byte-Register

Das ist ja das Problem, da RC5 mit einem Manchestercode arbeitet 
(Halbits) das is ä weng komplizierter.

von Volker S. (volkerschulz)


Lesenswert?

Draco schrieb:
> Volker Schulz schrieb:
>> Abgesehen davon ist das Ausgangssignal des TSOP active low, oder nicht?
>
> Richtig, deswegen lese ich ja auch die LowBits (if(PINB.B3 == 0)) aus.

Ich meinte ja das if, in dem Du was ueber die UART sendest, Du schickst 
also immer etwas raus, wenn du einen Pegel von 0 auf 1 hast. Ist das so 
beabsichtigt?


> Volker Schulz schrieb:
>> Welches IR-Protokoll benutzt Du?
>
> Es "sollte" eigentlich RC5 sein, jedoch habe ich... wie gesagt... bei
> jeglicher Fernbedienung andere Zeitwerte.

Leichte Abweichungen bei verschiedenen Fernbedienungen sind normal, da 
insbesondere die billigen Universalfernbedienungen nur einen Grundtakt 
haben um alle Protokolle zu emulieren. Bei RC5 unterscheiden sich die 
Zeitwerte natuerlich auch durch die Uebertragenen Daten. Je nach 
Toggle-Bit solltest Du sogar bei zwei gleuchen Tastendruecken einer FB 
unterschiedliche Signale bekommen. Unterschiedliche Fernbedienungen 
nutzen velleicht unterschiedliche Geraete-Codes.


> Volker Schulz schrieb:
>> bau Dir einen Timer mit 36kHz-Interrupt-Frequenz und schieb
>> bei jedem Interrupt den Portstatus in ein Byte-Register
>
> Das ist ja das Problem, da RC5 mit einem Manchestercode arbeitet
> (Halbits) das is ä weng komplizierter.

Den Manchester-Code musst Du natuerlich danach noch decodieren. Du 
kannst Dir aber aus den Uebertragenen Bytes einen Graphen zeichnen um 
das Signal zu visualisieren. Spaeter kannst Du dann den Code direkt im 
Mikrocontroller auswerten (und brauchst dann auch keine 36kHz Takt 
mehr). RC5 ist eigentlich ziemich einfach zu benutzen:

Auf Startbit warten
Nach 400µs Timer mit 889µs starten
Halbbits auswerten bis beide gleich
Fertig


Volker

von Draco (Gast)


Lesenswert?

Volker Schulz schrieb:
> Ich meinte ja das if, in dem Du was ueber die UART sendest, Du schickst
> also immer etwas raus, wenn du einen Pegel von 0 auf 1 hast. Ist das so
> beabsichtigt?

Richtig war so beabsichtigt, um die Zeiten zwischen low und high zu 
messen.

Volker Schulz schrieb:
> Auf Startbit warten
> Nach 400µs Timer mit 889µs starten
> Halbbits auswerten bis beide gleich
> Fertig

Das ist ja mein Problem, wie bekomme ich genau diesen Timer zustande :/

von Volker S. (volkerschulz)


Lesenswert?

Draco schrieb:
> Volker Schulz schrieb:
>> Auf Startbit warten
>> Nach 400µs Timer mit 889µs starten
>> Halbbits auswerten bis beide gleich
>> Fertig
>
> Das ist ja mein Problem, wie bekomme ich genau diesen Timer zustande :/

Also ich hab meinen ATMEGA8535 auf 3.6864 MHz laufen und zaehle einen 
8-Bit Timer 29 mal bis 112. ;)

Du solltest aber hier im Forum auch fertige RC5-Codeschnipsel finden. 
Sowohl in ASM wie auch in GCC. Da musst Du dann nur noch die 
Taktfrequenz einstellen.


Volker

von Draco (Gast)


Lesenswert?

Also ich habe es momentan so laufen:
1
void Timer0Overflow_ISR() org IVT_ADDR_TIMER0_OVF
2
{
3
    if(Pinb.B3 == 0)
4
    {
5
       runner++;
6
       ok = 1;
7
    }
8
9
    if(Pinb.B3 == 1 && ok == 1)
10
    {
11
    
12
          for(i=0;i<28;i++)
13
          {
14
            for(j=0;j<256;j++)
15
            {
16
              asm nop;
17
            }
18
            //text1[i] = PinB.B3;
19
            if(PinB.B3) test |= ((unsigned long)1 << i);
20
          }
21
          write = 1;
22
          runner = 0;
23
          ok = 0;
24
    }
25
}

Es kommen nun endlich einmal gescheite Werte raus, was mir dann im 
Nachhinein aufgefallen ist, das mein Quarz ja einen super 8er Teiler bei 
seinen 4.194304 Mhz bietet (128x nop, 256x nop,... je nach teiler des 
Overflow Interrupts.

:D Danke euch!

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.