Forum: Mikrocontroller und Digitale Elektronik IRMP-Problem


von Christian O. (hightec)


Angehängte Dateien:

Lesenswert?

Hallo Leute da bin ich mal wieder.

Ich habe aktuell das Problem mit IRMP. Und zwar reagiert mein uC einfach 
nicht.

Ich habe mal ein Paar Bilder angehängt.

Hardwaretechnisch habe ich bereits alles überprüft. (Bild OSZI) Das Bild 
zeigt das Signal das direkt an dem Pin PA4 anliegt wenn ich meinen 
IR-Empfänger (TSOP31256) mit der Fernbedienung befeuer. Das sagt mir 
soweit dass das Signal erstmal am uC ankommt und grenzt meinen Fehler 
auf die Software ein.

Es handelt sich bei dem uC um einen Atmega 32, der IR-Empfänger liegt an 
PA4.

Die Fuses hab ich wie oben eingestelt (Bild Fuses) auch da kann ich 
nicht erkennen ob ich da einen Fehler gemacht habe.

Meine main.c sieht wie folgt aus:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <avr/pgmspace.h>
4
#include <avr/interrupt.h>
5
#include <stdlib.h>
6
#include <inttypes.h>
7
8
#include "lcd.h"
9
#include "beep.h"
10
#include "irmp.h"
11
#include "main.h"
12
13
14
ISR(TIMER0_COMP_vect)                        
15
{  
16
  
17
  (void) irmp_ISR(); 
18
  (void)encoderinterrupt();
19
  
20
}
21
22
ISR(INT0_vect)                        
23
{
24
    
25
  
26
}
27
28
29
int main (void)
30
{  
31
  
32
  irmp_init();
33
  timer0_init();
34
  timer2_init();
35
  lcd_init();
36
  sei();
37
  
38
  IRMP_DATA irmp_data;
39
  
40
   while(1){
41
    
42
    if (irmp_get_data (&irmp_data))
43
                 {
44
       beep_att();
45
     }
46
    
47
     if (encode_read())
48
     {
49
       beep_att();
50
     }
51
    
52
   }
53
  
54
  
55
return 0;
56
}
Zur Erklärung: die Funktion beep_att(); ist eine akustische Ausgabe 
mittels eines Piezosummers. Dies funktioniert einwandfrei.


In der main.h werden die Funktionen der Timer initialisierungen 
beschrieben:
1
#ifndef MAIN_H
2
#define MAIN_H
3
4
#ifndef MAINPINS
5
#define MAINPINS
6
7
#define ENCODER_A      (1<<PA6)
8
#define ENCODER_B      (1<<PA7)
9
#define ENCODER_TASTER    (1<<PA5)
10
#define LCD_LED        (1<<PD7)
11
#define BEEP_PIN_1  PD5
12
#define BEEP_PIN_2  PD6
13
#define F_INTERRUPTS         15000      // interrupts per second
14
15
#endif
16
17
#ifndef MAINFUNC
18
#define MAINFUNC
19
/******************************************************/
20
/*Eingänge und Ausgänge deklarieren*/
21
/******************************************************/
22
void pin_input_init(void){
23
  DDRA &= ~(ENCODER_A | ENCODER_B);       //Als Eingang deklarieren
24
  PORTA |= ENCODER_A | ENCODER_B;        //Pull-Up einschalten
25
  DDRD &= ~ENCODER_TASTER ;          //Als Eingang deklarieren
26
  PORTD |= ENCODER_TASTER  ;          //Pull-Up einschalten
27
}
28
void pin_output_init(void){
29
  DDRD |= (1<<BEEP_PIN_1) | (1<<BEEP_PIN_2) | LCD_LED | (1<<PD2);  //Als Ausgang deklarieren
30
  DDRB |= (1<<PB4);
31
  
32
}
33
/******************************************************/
34
/*Timer0 (Compare-Match-Interrupt) für IR-Sensor & Drehgeber*/
35
/******************************************************/
36
void timer0_init(void){
37
  OCR0   =  ((F_CPU / F_INTERRUPTS)/8) - 1+0.5;  //Compare Register beschreiben         
38
  TCCR0  = (1 << WGM01) | (1 << CS01);       //CTC Mode an, prescaler = 8
39
  TIMSK  = 1 << OCIE0;              //Compare Match Interrupt Enable
40
  
41
}
42
43
44
45
/*************************************************************/
46
/*Timer 2 (LCD-Backlight-PWM)*/
47
/*************************************************************/
48
void timer2_init(void){
49
    TCCR2 = (1<< WGM21) | (1<< WGM20) | (1<< CS20); //Fast-PWM, Prescaler 1 
50
}
51
52
53
void lcd_led_pwm_onoff(int status){
54
  if(status == 1){
55
    TCCR2 |= (1<< COM21);          //OC2-Pin auf PWM schalten (PWM an)
56
  }else{
57
    TCCR2 &= ~(1<< COM21);          //OC2-Pin von PWM abschalten (PWM aus)
58
  }
59
}
60
61
void lcd_led_onoff(int status){
62
  if (status == 0){
63
    PORTD |= LCD_LED;
64
  }else{
65
    PORTD &= ~LCD_LED;
66
  }
67
}
68
69
void lcd_fadeto(int ocr){
70
  OCR2 = ocr;
71
  
72
  }
73
#endif
74
75
76
77
#endif

In der irmpcomfig.h habe ich den Pin PA4 eingestellt und nahezu alle 
IR-Protokolle aktiviert.

Nun ist es so, dass einfach nichts passiert wenn ich auf die 
Fernbedienung drücke. Mein uC erkennt einfach kein IR-Signal.

Kann mir um diese Uhrezit jemand helfen mein Problem zu lösen? Ich freue 
mich auf eure Antworten.

Gruß

Christian

von public (Gast)


Lesenswert?

Servus,

kannst du uns mit deinen IRMP-Routinen vertraut machen? Hey und um die 
Uhrzeit arbeiten nur noch workaholics...

Ich sehe hier keinen Code der auf die Initialisierung oder Verwendung 
des PA4 schließen lassen.

Ist das korrekt das du bei deinem Timer erst das OCR register und 
anschließend das TCCR register initialisierst? Ich bin mir da nicht 
sicher ob es da nicht eine Abhängigkeit gibt.

Was passiert mit deinem Timer0-Interrupt-Flag, das muss doch 
gelöscht/gesetzt werden?

Hast du mal versucht dir einen Brechpunkt in die ISR zu setzen und dann 
den debugger laufen zu lassen, ob es jemals zu dem Interrupt kommt?

beste grüße
public

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Christian O. schrieb:
> Die Fuses hab ich wie oben eingestelt (Bild Fuses) auch da kann ich
> nicht erkennen ob ich da einen Fehler gemacht habe.

F_CPU steht im Projekt auf 8000000?

> ISR(TIMER0_COMP_vect)
> {
>   (void) irmp_ISR();
>   (void)encoderinterrupt();
>
> }

Hast Du mal versuchsweise den Aufruf von encoderinterrupt() 
auskommentiert, um auszuschließen, dass diese Funktion die IR-Messung 
beeinflusst?

Ebenso würde ich mal den Aufruf von timer2_init() auskommentieren, um da 
eine Beeinflussung auszuschließen.

> In der main.h werden die Funktionen der Timer initialisierungen
> beschrieben:

Anmerkung: Funktionen in Header-Files sind unschön. Funktioniert nur 
korrekt, wenn das Include-File (main.h) ausschlielich von einem C-Modul 
(main.c) aufgerufen wird. Wenn eine H-Datei aber ausschließlich von 
einem C-Modul genutzt wird, ist der Sinn der H-Datei nicht gegeben. 
H-Dateien sollen Interfaces zwischen C-Modulen beschreiben.

> #define F_INTERRUPTS         15000      // interrupts per second

Das gehört in irmpconfig.h. Warum hast Du das hier nochmal definiert? 
Nimm das hier raus.

Am besten hängst Du mal Deine irmpconfig.h an.


> /******************************************************/
> /*Timer0 (Compare-Match-Interrupt) für IR-Sensor & Drehgeber*/
> /******************************************************/
> void timer0_init(void){
>   OCR0   =  ((F_CPU / F_INTERRUPTS)/8) - 1+0.5;  //Compare Register
> beschreiben
>   TCCR0  = (1 << WGM01) | (1 << CS01);       //CTC Mode an, prescaler =
> 8
>   TIMSK  = 1 << OCIE0;              //Compare Match Interrupt Enable
>
> }

Sauberer wäre:

OCR0   =  (uint8_t) (((F_CPU / F_INTERRUPTS)/8) - 1+0.5);

> In der irmpcomfig.h habe ich den Pin PA4 eingestellt und nahezu alle
> IR-Protokolle aktiviert.

Bitte als Anhang zeigen.

> Nun ist es so, dass einfach nichts passiert wenn ich auf die
> Fernbedienung drücke. Mein uC erkennt einfach kein IR-Signal.

Hast Du nur diese eine Fernbedienung ausprobiert? Oder auch andere? Was 
ist das für eine Fernbedienung? Wenn Du Pech hast, ist das so ein 
exotisches Ding, welches nicht von IRMP unterstützt wird.

Also: Sammle mal alle FBs in Deinem Haushalt ein und teste das Ganze mal 
systematisch.

> Kann mir um diese Uhrezit jemand helfen mein Problem zu lösen? Ich freue
> mich auf eure Antworten.

Sorry, da habe ich schon geschlafen ;-)

Bekommst Du irgendwelche Warnungen beim Compilieren?

Ich würde Dir empfehlen, Deine "Module" IRMP, Encoder, LCD incl. Fading 
erstmal getrennt zu testen und nicht sofort alles auf einmal in einen 
Topf zu werfen. Also: Mini-Projekt, darin erstmal nur IRMP. Wenn das 
läuft, ein weiteres Mini-Projekt mit Deinen Encoder-Routinen, als 
letztes dann ein Mini-Projekt mit LCD.

Wenn alles für sich läuft, dann kann man im zweiten Schritt IRMP + LCD 
zum Laufen bekommen. Als letztes dann noch Deinen Dreh-Encoder.

P.S.
Dein Oszi-Bild sieht für ein FB-Signal etwas "merkwürdig" aus. Es gibt 
mehr als 2 verschiedene Pausenlängen. Das ist auf jeden Fall kein 
Pulse-Distance- oder Bi-Phase-Encoding (Manchester). Das sieht nach 
einem seriellen Format aus - für IR-Fernbedienungen sehr ungewöhnlich. 
Ist der IR-Frame im Bild vollständig?

Daher nochmal die Frage: Was ist das für eine FB? Vielleicht Dreambox? 
Die wird von IRMP nicht unterstützt. Umso wichtiger, erstmal ein paar 
gewöhnliche FBs zu testen. Piept dann Deine Schaltung, liegts nicht an 
der SW, sondern an der FB. Hier helfen dann nur IRMP-Scans weiter.

Wie ist denn da die Zeitskala?

: Bearbeitet durch Moderator
von Christian O. (hightec)


Angehängte Dateien:

Lesenswert?

Frank M. schrieb:
> Hast Du mal versuchsweise den Aufruf von encoderinterrupt()
> auskommentiert, um auszuschließen, dass diese Funktion die IR-Messung
> beeinflusst?
>
> Ebenso würde ich mal den Aufruf von timer2_init() auskommentieren, um da
> eine Beeinflussung auszuschließen.

Habe ich soeben ausprobiert.. habe jetzt alles auskommentiert was nicht 
direkt mit IRMP und dem Signalton zu tun hat. Kein Erfolg.

Frank M. schrieb:
> F_CPU steht im Projekt auf 8000000?

Ja F_CPU ist im Makefile auf 8000000 definiert

Frank M. schrieb:
> Anmerkung: Funktionen in Header-Files sind unschön.

Ok ich werde dann alles aufräumen wenn ich fertig bin. Ich fand es halt 
praktisch gewisse Funktionen in die Header-Datei zu verlagern, der 
Übersichtlichkeit halber. Inwiefern kann so eine Headerdatei denn als 
Interface fungieren? Ist es da besser alle Funktionen in die C-Datei zu 
schreiben?

Frank M. schrieb:
> Bekommst Du irgendwelche Warnungen beim Compilieren?

Ja bekomme ich.. allerdings nur aus der irmp.h und zwar dass ein paar 
Protokolle wegen kompitiblität wieder deaktiviert wurden. Aufgrund 
dessen dass ich einfach alle Protokolle eingeschaltet habe.

Hier die Warnungen:
1
irmp.h:65:4: warning: #warning DENON protocol conflicts wih RUWIDO, please enable only one of both protocols
2
irmp.h:66:4: warning: #warning RUWIDO protocol disabled
3
irmp.h:72:4: warning: #warning RC6 protocol conflicts wih ROOMBA, please enable only one of both protocols
4
irmp.h:73:4: warning: #warning ROOMBA protocol disabled
5
irmp.h:79:4: warning: #warning RC5 protocol conflicts wih ORTEK, please enable only one of both protocols
6
irmp.h:80:4: warning: #warning ORTEK protocol disabled
7
irmp.h:124:4: warning: #warning F_INTERRUPTS too low, LEGO protocol disabled (should be at least 20000)
8
irmp.h:160:4: warning: #warning F_INTERRUPTS too low, RCMM protocol disabled (should be at least 20000)

Frank M. schrieb:
> Daher nochmal die Frage: Was ist das für eine FB?

Es ist keine wirkliche FB sondern eine App auf meinem Smartphone (IR 
Remote). Eine auf dem Stekbrett aufgebaute IRMP-Schaltung habe ich damit 
bereits bedient.

Frank M. schrieb:
> Wie ist denn da die Zeitskala?

Meinst du die Zeitskala auf dem Oszi-Bild? Die ist bei 10ms/DIV 
eingestellt.

Frank M. schrieb:
> Bitte als Anhang zeigen.

Ich habe die Irmpconfig.h als Anhang mit dabei.

Frank M. schrieb:
> Sorry, da habe ich schon geschlafen ;-)

:-D Ja inicht schlimm.. ich habe momentan Nachtschicht und bin damit 
eher nachts an dem Kram beschäftigt ;-)

Schonmal vielen vielen Dank für deine Antworten

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Christian O. schrieb:

> Inwiefern kann so eine Headerdatei denn als
> Interface fungieren? Ist es da besser alle Funktionen in die
> C-Datei zu schreiben?

Eine Headerdatei beschreibt das Interface eines C-Moduls. Ein Beispiel:

print.c:

#include "print.h"
void print (char * text)
{
   printf ("%s", text);
}

main.c:

#include "print.h"
int main ()
{
   print ("Hello, world\n");
}

print.h:
extern void print (char *);

Das print.h verbindet beide C-Module. Beim Übersetzen von main.c weiß 
dann der Compiler: "Es gibt eine externe Funktion print(), die void ist 
und einen char * als Typ für das Argument akzeptiert."

Es ist auch sinnvoll, das include in print.c reinzuschreiben, damit der 
Compiler prüfen kann, ob Deine extern-Deklarationen auch tatsächlich 
Deinen C-Funkktions-Definitionen entspricht. Bei einer Abweichung des 
Call-Interfaces meckert er dann.

Das ist aber nur eine Aufgabe von Header-Dateien: Die Interfaces eines 
externen C-Moduls zu definieren. Aber es gibt noch andere, nämlich zum 
Beispiel Konstanten, die das aufrufende C-Modul verwenden möchte. Ein 
Beispiel kennst Du bestimmt aus stdio.h, nämlich die Definition der 
Konstanten EOF.

Konkret für IRMP:

irmp.h deklariert zum Beispiel den neuen Typ IRMP_DATA, aber auch den 
korrekten Aufruf von irmp_get_data().

Weitere Erklärungen zum Sinn einer Header-Datei gibt Dir ein gutes 
C-Buch.

> Hier die Warnungen:

Die sind normal, wenn Du soviele Protokolle eingeschaltet hast.

> Es ist keine wirkliche FB sondern eine App auf meinem Smartphone (IR
> Remote).

Die kenne ich nicht.

> Eine auf dem Stekbrett aufgebaute IRMP-Schaltung habe ich damit
> bereits bedient.

Es lief also schon mal mit IRMP?

Du kennst also das Protokoll, die Adresse und die Kommando-Codes? Warum 
schaltest Du dann jetzt alle Protokolle ein, wenn die App doch ein Dir 
bekanntes Protokoll nutzt?

Muss es ausgerechnet diese App sein? Wenn nicht, schau Dir mal diese an:

  Beitrag "Re: IRMP - Infrared Multi Protocol Decoder"

Die arbeitet direkt mit IRMP-Codes. Du kannst Deine Tasten selbst 
definieren und mit einem IRMP-Code versehen. Die App ist zwar noch Beta, 
aber z.B. das Protokoll NEC funktioniert hervorragend. Nimm als Adresse 
zum Beispiel die 1 und als Kommando-Code irgendeine Zahl zwischen 1 und 
255. Dann kannst Du Dir bis zu 24 Universal-Fernbedienungen 
zusammenklicken.

Zwei Postings tiefer findest Du die aktuelle Version.

> Meinst du die Zeitskala auf dem Oszi-Bild? Die ist bei 10ms/DIV
> eingestellt.

Ok. Ich kann mir aber immer noch nicht vorstellen, dass die App genau so 
ein Bild erzeugt.

> Ich habe die Irmpconfig.h als Anhang mit dabei.

Sieht gut aus. Ich habe leider keine Ahnung, warum es bei Dir nicht 
läuft. Vielleicht nimmst Du Dir den Rat zu Herzen, Deine Aufgaben 
erstmal zu modularisieren und jede für sich einzeln auszutesten.

: Bearbeitet durch Moderator
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.