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 | }
|