Forum: Projekte & Code IR Arduino Remote Receiver für TSOP7000 und Beo4


von Peter S. (petersieg)


Lesenswert?

Moin.
Hatte lange gegoogeln aber nichts wirklich fertiges gefunden.
Einzig ein Hinweis auf die Adafruit IR-Raw Lib/Code brachte dann den 
Erfolg:

https://learn.adafruit.com/ir-sensor/reading-ir-commands
https://github.com/adafruit/Raw-IR-decoder-for-Arduino
https://github.com/adafruit/Adafruit_Learning_System_Guides/tree/main/IR_Sensor/Arduino

Mit IR-Raw den Code als C Array ausgeben lassen.
1
/* Raw IR decoder sketch!
2
 
3
 This sketch/program uses the Arduno and a PNA4602 to 
4
 decode IR received. This can be used to make a IR receiver
5
 (by looking for a particular code)
6
 or transmitter (by pulsing an IR LED at ~38KHz for the
7
 durations detected 
8
 
9
 Code is public domain, check out www.ladyada.net and adafruit.com
10
 for more tutorials! 
11
 */
12
 
13
// We need to use the 'raw' pin reading methods
14
// because timing is very important here and the digitalRead()
15
// procedure is slower!
16
//uint8_t IRpin = 2;
17
// Digital pin #2 is the same as Pin D2 see
18
// http://arduino.cc/en/Hacking/PinMapping168 for the 'raw' pin mapping
19
#define IRpin_PIN      PIND
20
#define IRpin          2
21
 
22
// the maximum pulse we'll listen for - 65 milliseconds is a long time
23
#define MAXPULSE 65000
24
 
25
// what our timing resolution should be, larger is better
26
// as its more 'precise' - but too large and you wont get
27
// accurate timing
28
#define RESOLUTION 20 
29
 
30
// we will store up to 100 pulse pairs (this is -a lot-)
31
uint16_t pulses[100][2];  // pair is high and low pulse 
32
uint8_t currentpulse = 0; // index for pulses we're storing
33
 
34
void setup(void) {
35
  Serial.begin(115200);
36
  Serial.println("Ready to decode IR!");
37
}
38
 
39
void loop(void) {
40
  uint16_t highpulse, lowpulse;  // temporary storage timing
41
  highpulse = lowpulse = 0; // start out with no pulse length
42
  
43
  
44
//  while (digitalRead(IRpin)) { // this is too slow!
45
    while (IRpin_PIN & (1 << IRpin)) {
46
     // pin is still HIGH
47
 
48
     // count off another few microseconds
49
     highpulse++;
50
     delayMicroseconds(RESOLUTION);
51
 
52
     // If the pulse is too long, we 'timed out' - either nothing
53
     // was received or the code is finished, so print what
54
     // we've grabbed so far, and then reset
55
     if ((highpulse >= MAXPULSE) && (currentpulse != 0)) {
56
       printpulses();
57
       currentpulse=0;
58
       return;
59
     }
60
  }
61
  // we didn't time out so lets stash the reading
62
  pulses[currentpulse][0] = highpulse;
63
  
64
  // same as above
65
  while (! (IRpin_PIN & _BV(IRpin))) {
66
     // pin is still LOW
67
     lowpulse++;
68
     delayMicroseconds(RESOLUTION);
69
     if ((lowpulse >= MAXPULSE)  && (currentpulse != 0)) {
70
       printpulses();
71
       currentpulse=0;
72
       return;
73
     }
74
  }
75
  pulses[currentpulse][1] = lowpulse;
76
 
77
  // we read one high-low pulse successfully, continue!
78
  currentpulse++;
79
}
80
 
81
void printpulses(void) {
82
  Serial.println("\n\r\n\rReceived: \n\rOFF \tON");
83
  for (uint8_t i = 0; i < currentpulse; i++) {
84
    Serial.print(pulses[i][0] * RESOLUTION, DEC);
85
    Serial.print(" usec, ");
86
    Serial.print(pulses[i][1] * RESOLUTION, DEC);
87
    Serial.println(" usec");
88
  }
89
 
90
  // print it in a 'array' format
91
  Serial.println("int IRsignal[] = {");
92
  Serial.println("// ON, OFF (in 10's of microseconds)");
93
  for (uint8_t i = 0; i < currentpulse-1; i++) {
94
    Serial.print("\t"); // tab
95
    Serial.print(pulses[i][1] * RESOLUTION / 10, DEC);
96
    Serial.print(", ");
97
    Serial.print(pulses[i+1][0] * RESOLUTION / 10, DEC);
98
    Serial.println(",");
99
  }
100
  Serial.print("\t"); // tab
101
  Serial.print(pulses[currentpulse-1][1] * RESOLUTION / 10, DEC);
102
  Serial.print(", 0};");
103
}

Diesen in ircommander.h erfassen.
1
/******************* our codes ************/
2
3
int Beo4_TV_0[] = {
4
// ON, OFF (in 10's of microseconds)
5
  22, 298,
6
  24, 298,
7
  22, 1582,
8
  24, 296,
9
  24, 618,
10
  22, 620,
11
  24, 618,
12
  22, 620,
13
  24, 618,
14
  22, 620,
15
  22, 618,
16
  22, 620,
17
  24, 618,
18
  22, 620,
19
  24, 618,
20
  22, 620,
21
  24, 618,
22
  22, 620,
23
  24, 618,
24
  22, 620,
25
  22, 1260,
26
  24, 0};
27
28
int Beo4_TV_1[] = {
29
// ON, OFF (in 10's of microseconds)
30
  24, 296,
31
  22, 298,
32
  24, 1582,
33
  22, 298,
34
  22, 620,
35
  24, 618,
36
  22, 620,
37
  24, 618,
38
  22, 620,
39
  22, 618,
40
  24, 618,
41
  24, 618,
42
  22, 620,
43
  24, 618,
44
  22, 620,
45
  24, 618,
46
  22, 620,
47
  22, 620,
48
  22, 618,
49
  24, 940,
50
  22, 1262,
51
  22, 0};
52
53
int Beo4_TV_2[] = {
54
// ON, OFF (in 10's of microseconds)
55
  24, 298,
56
  22, 298,
57
  24, 1580,
58
  24, 298,
59
  22, 620,
60
  22, 620,
61
  20, 620,
62
  24, 618,
63
  22, 620,
64
  24, 618,
65
  22, 620,
66
  24, 618,
67
  22, 620,
68
  22, 618,
69
  24, 618,
70
  24, 618,
71
  22, 620,
72
  24, 618,
73
  22, 940,
74
  24, 298,
75
  22, 1260,
76
  24, 0};
77
78
int Beo4_TV_3[] = {
79
// ON, OFF (in 10's of microseconds)
80
  24, 296,
81
  22, 298,
82
  24, 1582,
83
  22, 298,
84
  22, 620,
85
  24, 618,
86
  22, 620,
87
  24, 618,
88
  22, 620,
89
  22, 620,
90
  20, 620,
91
  24, 618,
92
  22, 620,
93
  24, 618,
94
  22, 620,
95
  24, 618,
96
  22, 620,
97
  22, 618,
98
  24, 940,
99
  22, 620,
100
  22, 1260,
101
  24, 0};
102
103
int Beo4_TV_4[] = {
104
// ON, OFF (in 10's of microseconds)
105
  24, 298,
106
  22, 298,
107
  24, 1580,
108
  24, 298,
109
  22, 620,
110
  22, 620,
111
  20, 620,
112
  24, 618,
113
  22, 620,
114
  24, 618,
115
  22, 620,
116
  24, 618,
117
  22, 618,
118
  24, 618,
119
  24, 618,
120
  24, 618,
121
  22, 620,
122
  24, 938,
123
  24, 298,
124
  22, 618,
125
  24, 1260,
126
  24, 0};
127
128
int Beo4_TV_5[] = {
129
// ON, OFF (in 10's of microseconds)
130
  22, 300,
131
  22, 298,
132
  22, 1582,
133
  24, 296,
134
  24, 618,
135
  24, 618,
136
  24, 618,
137
  22, 620,
138
  24, 618,
139
  22, 620,
140
  22, 620,
141
  22, 620,
142
  22, 618,
143
  22, 620,
144
  24, 618,
145
  22, 620,
146
  24, 618,
147
  22, 940,
148
  24, 298,
149
  22, 940,
150
  22, 1262,
151
  22, 0};
152
  
153
int Beo4_TV_6[] = {
154
// ON, OFF (in 10's of microseconds)
155
  22, 298,
156
  24, 296,
157
  22, 1584,
158
  22, 298,
159
  24, 618,
160
  22, 620,
161
  22, 618,
162
  24, 618,
163
  24, 618,
164
  22, 620,
165
  24, 618,
166
  22, 620,
167
  24, 618,
168
  22, 620,
169
  22, 620,
170
  20, 620,
171
  24, 618,
172
  22, 940,
173
  24, 618,
174
  24, 298,
175
  22, 1262,
176
  22, 0};
177
  
178
int Beo4_TV_7[] = {
179
// ON, OFF (in 10's of microseconds)
180
  24, 298,
181
  20, 300,
182
  24, 1580,
183
  24, 298,
184
  22, 618,
185
  24, 618,
186
  22, 620,
187
  24, 618,
188
  22, 620,
189
  24, 618,
190
  22, 620,
191
  22, 620,
192
  20, 620,
193
  24, 618,
194
  22, 620,
195
  24, 618,
196
  22, 620,
197
  24, 938,
198
  22, 620,
199
  24, 618,
200
  22, 1262,
201
  22, 0};
202
  
203
int Beo4_TV_8[] = {
204
// ON, OFF (in 10's of microseconds)
205
  24, 296,
206
  22, 300,
207
  24, 1580,
208
  24, 298,
209
  22, 618,
210
  24, 618,
211
  22, 620,
212
  24, 618,
213
  22, 620,
214
  24, 618,
215
  22, 618,
216
  24, 618,
217
  22, 620,
218
  24, 618,
219
  22, 620,
220
  24, 618,
221
  22, 940,
222
  24, 298,
223
  22, 620,
224
  20, 620,
225
  24, 1260,
226
  24, 0};
227
  
228
int Beo4_TV_9[] = {
229
// ON, OFF (in 10's of microseconds)
230
  22, 300,
231
  22, 298,
232
  22, 1582,
233
  24, 298,
234
  24, 618,
235
  22, 620,
236
  22, 618,
237
  24, 618,
238
  24, 618,
239
  22, 620,
240
  24, 618,
241
  22, 620,
242
  22, 618,
243
  24, 618,
244
  24, 618,
245
  22, 620,
246
  24, 938,
247
  24, 298,
248
  22, 620,
249
  24, 938,
250
  22, 1262,
251
  22, 0};

Beispielverarbeitung siehe: IR_Commander.ino.
1
/* Raw IR commander
2
 
3
 This sketch/program uses the Arduno and a PNA4602 to 
4
 decode IR received.  It then attempts to match it to a previously
5
 recorded IR signal.  Limor Fried, Adafruit Industries
6
 
7
 MIT License, please attribute
8
 check out learn.adafruit.com  for more tutorials!  
9
 
10
 2021-06-25 - P. Sieg: used with TSOP7000 ir receiver to decode Beo4 B&O ir remote control
11
 */
12
13
// We need to use the 'raw' pin reading methods
14
// because timing is very important here and the digitalRead()
15
// procedure is slower!
16
//uint8_t IRpin = 2;
17
// Digital pin #2 is the same as Pin D2 see
18
// http://arduino.cc/en/Hacking/PinMapping168 for the 'raw' pin mapping
19
#define IRpin_PIN      PIND
20
#define IRpin          2
21
22
// the maximum pulse we'll listen for - 65 milliseconds is a long time
23
#define MAXPULSE 65000
24
#define NUMPULSES 50
25
26
// what our timing resolution should be, larger is better
27
// as its more 'precise' - but too large and you wont get
28
// accurate timing
29
#define RESOLUTION 20 
30
31
// What percent we will allow in variation to match the same code
32
#define FUZZINESS 20
33
34
// we will store up to 100 pulse pairs (this is -a lot-)
35
uint16_t pulses[NUMPULSES][2];  // pair is high and low pulse 
36
uint8_t currentpulse = 0; // index for pulses we're storing
37
38
#include "ircommander.h"
39
40
void setup(void) {
41
  Serial.begin(115200);
42
  Serial.println("Ready to decode IR!");
43
}
44
45
void loop(void) {
46
  int numberpulses;
47
  
48
  numberpulses = listenForIR();
49
#ifdef DEBUG   
50
  Serial.print("Heard ");
51
  Serial.print(numberpulses);
52
  Serial.println("-pulse long IR signal");
53
#endif 
54
  if (IRcompare(numberpulses, Beo4_TV_0,sizeof(Beo4_TV_0)/4)) {
55
    Serial.println("Beo4_TV_0");
56
  }
57
  if (IRcompare(numberpulses, Beo4_TV_1,sizeof(Beo4_TV_1)/4)) {
58
    Serial.println("Beo4_TV_1");
59
  }
60
  if (IRcompare(numberpulses, Beo4_TV_2,sizeof(Beo4_TV_2)/4)) {
61
    Serial.println("Beo4_TV_2");
62
  }
63
  if (IRcompare(numberpulses, Beo4_TV_3,sizeof(Beo4_TV_3)/4)) {
64
    Serial.println("Beo4_TV_3");
65
  }
66
  if (IRcompare(numberpulses, Beo4_TV_4,sizeof(Beo4_TV_4)/4)) {
67
    Serial.println("Beo4_TV_4");
68
  }
69
  if (IRcompare(numberpulses, Beo4_TV_5,sizeof(Beo4_TV_5)/4)) {
70
    Serial.println("Beo4_TV_5");
71
  }
72
  if (IRcompare(numberpulses, Beo4_TV_6,sizeof(Beo4_TV_6)/4)) {
73
    Serial.println("Beo4_TV_6");
74
  }
75
  if (IRcompare(numberpulses, Beo4_TV_7,sizeof(Beo4_TV_7)/4)) {
76
    Serial.println("Beo4_TV_7");
77
  }
78
  if (IRcompare(numberpulses, Beo4_TV_8,sizeof(Beo4_TV_8)/4)) {
79
    Serial.println("Beo4_TV_8");
80
  }
81
  if (IRcompare(numberpulses, Beo4_TV_9,sizeof(Beo4_TV_9)/4)) {
82
    Serial.println("Beo4_TV_9");
83
  }
84
  if (IRcompare(numberpulses, ApplePlaySignal,sizeof(ApplePlaySignal)/4)) {
85
    Serial.println("PLAY");
86
  }
87
    if (IRcompare(numberpulses, AppleRewindSignal,sizeof(AppleRewindSignal)/4)) {
88
    Serial.println("REWIND");
89
  }
90
    if (IRcompare(numberpulses, AppleForwardSignal,sizeof(AppleForwardSignal)/4)) {
91
    Serial.println("FORWARD");
92
  }
93
  delay(500);
94
}
95
96
//KGO: added size of compare sample. Only compare the minimum of the two
97
boolean IRcompare(int numpulses, int Signal[], int refsize) {
98
  int count = min(numpulses,refsize);
99
#ifdef DEBUG 
100
  Serial.print("count set to: ");
101
  Serial.println(count);
102
#endif  
103
  for (int i=0; i< count-1; i++) {
104
    int oncode = pulses[i][1] * RESOLUTION / 10;
105
    int offcode = pulses[i+1][0] * RESOLUTION / 10;
106
    
107
#ifdef DEBUG    
108
    Serial.print(oncode); // the ON signal we heard
109
    Serial.print(" - ");
110
    Serial.print(Signal[i*2 + 0]); // the ON signal we want 
111
#endif   
112
    
113
    // check to make sure the error is less than FUZZINESS percent
114
    if ( abs(oncode - Signal[i*2 + 0]) <= (Signal[i*2 + 0] * FUZZINESS / 100)) {
115
#ifdef DEBUG
116
      Serial.print(" (ok)");
117
#endif
118
    } else {
119
#ifdef DEBUG
120
      Serial.print(" (x)");
121
#endif
122
      // we didn't match perfectly, return a false match
123
      return false;
124
    }
125
    
126
    
127
#ifdef DEBUG
128
    Serial.print("  \t"); // tab
129
    Serial.print(offcode); // the OFF signal we heard
130
    Serial.print(" - ");
131
    Serial.print(Signal[i*2 + 1]); // the OFF signal we want 
132
#endif    
133
    
134
    if ( abs(offcode - Signal[i*2 + 1]) <= (Signal[i*2 + 1] * FUZZINESS / 100)) {
135
#ifdef DEBUG
136
      Serial.print(" (ok)");
137
#endif
138
    } else {
139
#ifdef DEBUG
140
      Serial.print(" (x)");
141
#endif
142
      // we didn't match perfectly, return a false match
143
      return false;
144
    }
145
    
146
#ifdef DEBUG
147
    Serial.println();
148
#endif
149
  }
150
  // Everything matched!
151
  return true;
152
}
153
154
int listenForIR(void) {
155
  currentpulse = 0;
156
  
157
  while (1) {
158
    uint16_t highpulse, lowpulse;  // temporary storage timing
159
    highpulse = lowpulse = 0; // start out with no pulse length
160
  
161
//  while (digitalRead(IRpin)) { // this is too slow!
162
    while (IRpin_PIN & (1 << IRpin)) {
163
       // pin is still HIGH
164
165
       // count off another few microseconds
166
       highpulse++;
167
       delayMicroseconds(RESOLUTION);
168
169
       // If the pulse is too long, we 'timed out' - either nothing
170
       // was received or the code is finished, so print what
171
       // we've grabbed so far, and then reset
172
       
173
       // KGO: Added check for end of receive buffer
174
       if (((highpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) {
175
         return currentpulse;
176
       }
177
    }
178
    // we didn't time out so lets stash the reading
179
    pulses[currentpulse][0] = highpulse;
180
  
181
    // same as above
182
    while (! (IRpin_PIN & _BV(IRpin))) {
183
       // pin is still LOW
184
       lowpulse++;
185
       delayMicroseconds(RESOLUTION);
186
        // KGO: Added check for end of receive buffer
187
        if (((lowpulse >= MAXPULSE)  && (currentpulse != 0))|| currentpulse == NUMPULSES) {
188
         return currentpulse;
189
       }
190
    }
191
    pulses[currentpulse][1] = lowpulse;
192
193
    // we read one high-low pulse successfully, continue!
194
    currentpulse++;
195
  }
196
}
197
void printpulses(void) {
198
  Serial.println("\n\r\n\rReceived: \n\rOFF \tON");
199
  for (uint8_t i = 0; i < currentpulse; i++) {
200
    Serial.print(pulses[i][0] * RESOLUTION, DEC);
201
    Serial.print(" usec, ");
202
    Serial.print(pulses[i][1] * RESOLUTION, DEC);
203
    Serial.println(" usec");
204
  }
205
  
206
  // print it in a 'array' format
207
  Serial.println("int IRsignal[] = {");
208
  Serial.println("// ON, OFF (in 10's of microseconds)");
209
  for (uint8_t i = 0; i < currentpulse-1; i++) {
210
    Serial.print("\t"); // tab
211
    Serial.print(pulses[i][1] * RESOLUTION / 10, DEC);
212
    Serial.print(", ");
213
    Serial.print(pulses[i+1][0] * RESOLUTION / 10, DEC);
214
    Serial.println(",");
215
  }
216
  Serial.print("\t"); // tab
217
  Serial.print(pulses[currentpulse-1][1] * RESOLUTION / 10, DEC);
218
  Serial.print(", 0};");
219
}

VG Peter

: Bearbeitet durch User
von Kurt (Gast)


Lesenswert?

Du zeigst da eine langweilige Reihe von (glaube ich) Code-Abläufen von
irgendeiner IR-Fernsteuerung für irgendein Gerät mit 455 kHz 
Trägerfrequenz.
Wonach hast du denn gesucht?

Gibt es da ein zu steuerndes Gerät, das du bedienen willst - oder eine 
Fernsteuerung, die du entschlüsseln willst? Oder wie, oder was?

Rede einfach mal Klartext:

- Es geht um ...
- Ich will ...
- Ich habe schon ...

von Klaus R. (klaus2)


Lesenswert?

Frage schei3e bzw nicht vorhanden, Format ebenso €÷×¥₩%$#@.

Was ist denn daran so schwer sich mal in den Leser rein zu versetzten?

FW, Klaus.

von Peter S. (petersieg)


Lesenswert?

Hmm. Liebe Forumsteilnehmer Kurt und Klaus.

Der Forumsbereich hier heißt "Projekte und Code". Ich habe hier ggf. für 
weitere Interessierte aufgezeigt, wie ich das für mein Projekt gelöst 
hatte, eine Beo4 = Bang & Olufson Beo4 Fernbedienung zu nutzen.

Eine Frage ist darin nicht enthalten ;-)

Details zum Projekt (hier: Fernbedienung der Spiele) - wen es 
interessiert:
https://github.com/petersieg/ScopeClock-alt

Ansonsten aber noch frohe Weihnachtsfesttage.

VG Peter

von Klaus R. (klaus2)


Lesenswert?

Peter S. schrieb:
> Der Forumsbereich hier heißt "Projekte und Code".

Ok, muss man erstmal wissen...etwas mehr prosa schadet nicht. Und irmp 
ist dafür auch geeignet, oder was ist das besondere an deiner Lsg.?

Peter S. schrieb:
> Ansonsten aber noch frohe Weihnachtsfesttage.

Dito!

Klaus.

von Schlaumaier (Gast)


Lesenswert?

Der Thread ist zwar schon 6 Monate alt, die Lösung ist viel einfacher.

Man braucht den Unsinn nicht i.d.R.

Man nehme ein Empfänger (richtige Khz-Zahl sonst ausprobieren, so teuer 
sind die Empfänger nicht) !!!, baue ihn in die Schaltung ein. Nehme 
seine FB und das IR-Scan Prg. (findet man im Netz).  Draufdrücken und 
auf den Serial-Monitor die Zahl ablesen und mit der Taste aufschreiben.

Nun die Zahl an die IR-Send-Diode schicken und das war's.

So habe ich von ALLEN FB's "Backups" gemacht. Und genau so funktioniert 
eine Commando-Steuerung von mir. Die via Tasten-Makros jede Menge 
Befehle an jeden Menge Geräte sendet.

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.