Forum: Mikrocontroller und Digitale Elektronik IRMP + IRSND --> Empf. OK, Senden zu schnell


von Sebastian E. (s-engel)


Angehängte Dateien:

Lesenswert?

Hallo,

ich teste hier gerade die IRMP und IRSND Bibliotheken für ein 
zukünftiges Projekt.

Das ganze übersetze ich mit AVR Studio 6.2 für einen ATMega 328P.
F_CPU ist global in den Projekteinstellungen auf 16000000UL eingestellt.
In den Config-Files habe ich nur die Pins angepasst und RC5 hinzugefügt.

Die Empfangsroutinen laufen einwandfrei.

Wenn ich allerdings den empfangenen Code mit Hilfe der IRSND-Bib 
zurücksenden möchte, ist das Sendesignal doppelt so schnell.
Im Oszillogramm ist in Gelb das Empfangene Signal direkt am 
IR-Empfangs-IC dargestellt und in Blau das ausgesendete Signal am Pin 
des Mikrocontrollers.

Um die Routinen auszuprobieren habe ich mich an die Beispiele aus dem 
Artikel zum IRMP gehalten.

Der Timer:
1
void timer1_init (void)
2
{
3
  OCR1A   =  (F_CPU / F_INTERRUPTS) - 1;      // compare value: 1/15000 of CPU frequency
4
  TCCR1B  = (1 << WGM12) | (1 << CS10);       // switch CTC Mode on, set prescaler to 1
5
  TIMSK1  = 1 << OCIE1A;                      // OCIE1A: Interrupt by timer compare
6
}
7
8
ISR(TIMER1_COMPA_vect)
9
{
10
  if (! irsnd_ISR())          // call irsnd ISR
11
  {                           // if not busy...
12
    irmp_ISR();             // call irmp ISR
13
  }
14
  irsnd_ISR();
15
}

Die Hauptschleife:
1
  IRMP_DATA irmp_data;
2
3
  mcu_init();
4
  uart_init();
5
  irmp_init();
6
  irsnd_init();
7
  timer1_init();
8
9
  sei();
10
11
  while(1)
12
  {
13
    if (irmp_get_data (&irmp_data))
14
    {
15
      irmp_data.flags = 0;    // reset flags!
16
      irsnd_send_data (&irmp_data, 0);
17
    }
18
  }

Ich finde jetzt leider meinen Fehler nicht.
Hat jemand einen Rat wo ich suchen könnte?

Gruß!
Sebastian

von Wolfgang S. (ws01)


Lesenswert?

Sebastian E. schrieb:

> Wenn ich allerdings den empfangenen Code mit Hilfe der IRSND-Bib
> zurücksenden möchte, ist das Sendesignal doppelt so schnell.

...

> Ich finde jetzt leider meinen Fehler nicht.
> Hat jemand einen Rat wo ich suchen könnte?

Deine Interruptroutine ruft den Interrupthandler für IRSND zwei mal auf, 
dadurch wird dessen Output aufs Doppelte beschleunigt. Er wird 30.000 
mal in der Sekunde aufgerufen, nicht wie vorgesehen 15.000 mal in der 
Sekunde.

Enferne einfach in
1
ISR(TIMER1_COMPA_vect)
2
{
3
  if (! irsnd_ISR())          // call irsnd ISR
4
  {                           // if not busy...
5
    irmp_ISR();             // call irmp ISR
6
  }
7
  irsnd_ISR();
8
}
den überflüssigen Aufruf vonirsnd_ISR() und die Sache wird 
funktionieren.

In meinem funktionierenden Beispiel (mit dem PIC12F1840, nicht einem 
AVR, aber das ist auf der Ebene egal), das auch im SVN-Repository zu 
finden ist, sieht das so aus:
1
void interrupt isr(void)
2
{
3
    TMR1=0xffff-_XTAL_FREQ/F_INTERRUPTS; 
4
    TMR1IF=0; // clear timer 1 interrupt
5
 
6
    if (!irsnd_ISR())
7
    {
8
        irmp_ISR();
9
    }
10
}

Quelle: 
https://www.mikrocontroller.net/svnbrowser/irmp/pic/main_pic12f1840.c?revision=143&view=markup

von Sebastian E. (s-engel)


Lesenswert?

Guten Morgen.

Danke Wolfgang. Das wars.
Hatte gestern wohl Tomaten auf den Augen...

Nun läufts auch wie erwartet.

Danke und Gruß!
Sebastian

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.