Forum: Mikrocontroller und Digitale Elektronik Infrarot Signal dekodieren, Code nicht erkannt?


von A. F. (elagil)


Lesenswert?

Hallo,

ich möchte den Infrarot-Code einer Samsung Fernbedienung erkennen (nur 
eine spezielle Taste) und damit einen Schalter (Relais) betätigen. So 
sieht das Samsung Protokoll aus (ich habe eine Samsung Fernbedienung..):

http://www.techdesign.be/projects/011/tt_011_8-samsung.gif

Folgendes Programm habe ich dazu geschrieben, leider erkennt es 
scheinbar nicht das von mir vorgegebene Signal (ich habe nach dem Signal 
für "1" gesucht und es eingegeben. Ich habe es auch schon einmal 
rückwärts eingegeben)

Ich denke, es ist im groben selbsterklärend, mein IR empfänger 
(demodulator) ist LOW-active. Der Interrupt prüft auf 
absteigende/aufsteigende Eingangsflanken (umgekehrt für den Ausgang des 
Empfängers) und misst die Zeit einer Pause (zwischen High-Low und 
Low-High). Dazu wird der Timer bei absteigender Flanke zurückgesetzt und 
bei aufsteigender ausgelesen.

Hier mal der Code:
1
#include <avr/io.h>
2
#include <avr/interrupt.h> 
3
#include <stdint.h>
4
5
#define irsens PB4
6
#define relais PB2
7
#define ledge PB1
8
#define ledgr PB0
9
#define micros TCNT0*32   // returns microseconds passed (prec. 32us)
10
#define reset_counter TCNT0=0
11
12
const unsigned long code = 0xFB040707;
13
volatile unsigned long reccode=0;
14
volatile unsigned int start=0;
15
volatile unsigned int pos=0;
16
17
void init (void) {
18
  cli();
19
  DDRB = 0xFF;
20
  DDRB &= ~(1<<irsens);
21
  PORTB = 0;
22
  PORTB |= (1<<ledgr);
23
  
24
  
25
  GIMSK |= (1<<PCIE);   // enable pin change interrupts
26
  PCMSK |= (1<<PCINT4);  // on pcint4
27
28
  TCNT0 = 0;        // counter
29
  TCCR0B |= (1<<CS02);  // 256er prescaler --> 32us intervalle
30
  sei();
31
}
32
33
void wechsel (void) {
34
  PORTB ^= 1<<relais;
35
  PORTB ^= 1<<ledgr;
36
  PORTB ^= 1<<ledge;
37
}
38
39
int main (void) {
40
  init();
41
  while (1) {
42
  }
43
  return 0;
44
}
45
46
ISR (PCINT0_vect) {     // PCINT0 Vector: PCINT pins 0..7
47
int down = PINB & (1 << irsens); // active LOW input!
48
unsigned int downtime=0;
49
50
  if(down) {
51
    reset_counter;
52
  }
53
  if(~down) {
54
    downtime = micros;
55
  }
56
  if(downtime > 4000) {
57
    pos=0;
58
    start = 1;
59
  }
60
  if(downtime > 450 && downtime < 750 && start == 1) {
61
    pos++;
62
    // reccode gleich
63
  }
64
  if(downtime > 1300 && start == 1) {
65
    reccode |= (1<<pos);
66
    pos++;
67
  }
68
  if(pos >= 31) {
69
    start = 0;
70
    if(reccode == code) {wechsel();}
71
  }
72
}

von W.S. (Gast)


Lesenswert?

Ähem.. du erwartest, daß dein Code auf Fehler durchgesehen wird?

Mein Rat erstmal: Nimm dir deinen Oszillografen und guck dir die Signale 
aus dem IR-Empfänger an. Ein einfacher Bastel-Logikanalysator tut's 
auch. Manche FB senden nämlich so schnell, daß man mit einem 
gewöhnlichen IR-Empfänger nicht zurande kommt. Z.B. die Ruwido Merlin.

W.S.

von troll (Gast)


Lesenswert?

IRMP kennst du?

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.