IRremote
ir_BangOlufsen.hpp
Go to the documentation of this file.
1 /*
2  * ir_BangOlufsen.hpp
3  *
4  * Contains functions for receiving and sending Bang & Olufsen IR and Datalink '86 protocols
5  * To receive B&O and ENABLE_BEO_WITHOUT_FRAME_GAP is NOT defined, you must set RECORD_GAP_MICROS to
6  * at least 16000 to accommodate the unusually long 3. start space.
7  *
8  * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.
9  *
10  ************************************************************************************
11  * MIT License
12  *
13  * Copyright (c) 2022 Daniel Wallner
14  *
15  * Permission is hereby granted, free of charge, to any person obtaining a copy
16  * of this software and associated documentation files (the "Software"), to deal
17  * in the Software without restriction, including without limitation the rights
18  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19  * copies of the Software, and to permit persons to whom the Software is furnished
20  * to do so, subject to the following conditions:
21  *
22  * The above copyright notice and this permission notice shall be included in all
23  * copies or substantial portions of the Software.
24  *
25  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
26  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
27  * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
28  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
29  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
30  * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31  *
32  ************************************************************************************
33  */
34 #ifndef _IR_BANG_OLUFSEN_HPP
35 #define _IR_BANG_OLUFSEN_HPP
36 
37 //==============================================================================
38 //
39 //
40 // Bang & Olufsen
41 //
42 //
43 //==============================================================================
44 // https://www.mikrocontroller.net/attachment/33137/datalink.pdf
45 // https://www.mikrocontroller.net/articles/IRMP_-_english#B&O
46 
47 // This protocol is unusual in two ways:
48 
49 // 1. The carrier frequency is 455 kHz
50 
51 // You can build your own receiver as Bang & Olufsen did (check old schematics) or use a TSOP7000
52 // Vishay stopped producing TSOP7000 since 2009 so you will probably only find counterfeits:
53 // https://www.vishay.com/files/whatsnew/doc/ff_FastFacts_CounterfeitTSOP7000_Dec72018.pdf
54 // It is also likely that you will need an oscilloscope to debug a counterfeit TSOP7000
55 // The specimen used to test this code was very noisy and had a very low output current
56 // A somewhat working fix was to put a 4n7 capacitor across the output and ground followed by a pnp emitter follower
57 // Other examples may require a different treatment
58 // This particular receiver also did receive lower frequencies but rather poorly and with a lower delay than usual
59 // If you need to parallel a receiver with another one you may need to delay the signal to get in phase with the other receiver
60 
61 // 2. A stream of messages can be sent back to back with a new message immediately following the previous stop space
62 
63 // It might be that this only happens over IR and not on the datalink protocol
64 // You can choose to support this or not:
65 
66 // Alt 1: Mode with gaps between frames
67 // Set RECORD_GAP_MICROS to at least 16000 to accommodate the unusually long 3. start space
68 // Can only receive single messages and back to back repeats will result in overflow
69 
70 // Alt 2: Break at start mode
71 // Define ENABLE_BEO_WITHOUT_FRAME_GAP and set RECORD_GAP_MICROS to 13000 to treat the 3. start space as a gap between messages
72 // The start of a transmission will result in a dummy decode with 0 bits data followed by the actual messages
73 // If the receiver is not resumed within a ms or so, partial messages will be decoded
74 // Debug printing in the wrong place is very likely to break reception
75 // Make sure to check the number of bits to filter dummy and incomplete messages
76 
77 // !!! We assume that the real implementations never set the official first header bit to anything other than 0 !!!
78 // !!! We therefore use 4 start bits instead of the specified 3 and in turn ignore the first header bit of the specification !!!
79 
80 // IR messages are 16 bits long and datalink messages have different lengths
81 // This implementation supports up to 40 bits total length split into 8 bit data/command and a header/address of variable length
82 // Header data with more than 16 bits is stored in decodedIRData.extra
83 
84 // B&O is a pulse distance protocol, but it has 3 bit values 0, 1 and (equal/repeat) as well as a special start and trailing bit.
85 // MSB first, 4 start bits + 8 to 16? bit address + 8 bit command + 1 special trailing bit + 1 stop bit.
86 // Address can be longer than 8 bit.
87 
88 /*
89  * Options for this decoder
90  */
91 //#define ENABLE_BEO_WITHOUT_FRAME_GAP // Requires additional 30 bytes program memory.
92 //#define SUPPORT_BEO_DATALINK_TIMING_FOR_DECODE // This also supports headers up to 32 bit. Requires additional 150 bytes program memory.
93 #if defined(DECODE_BEO)
94 # if defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
95 # if RECORD_GAP_MICROS > 13000
96 #warning If defined ENABLE_BEO_WITHOUT_FRAME_GAP, RECORD_GAP_MICROS must be set to 1300 by "#define RECORD_GAP_MICROS 13000"
97 # endif
98 # else
99 # if RECORD_GAP_MICROS < 16000
100 #error If not defined ENABLE_BEO_WITHOUT_FRAME_GAP, RECORD_GAP_MICROS must be set to a value >= 1600 by "#define RECORD_GAP_MICROS 16000"
101 # endif
102 # endif
103 #endif
104 
105 #define BEO_DATA_BITS 8 // Command or character
106 
107 #define BEO_UNIT 3125 // All timings are in microseconds
108 
109 #define BEO_IR_MARK 200 // The length of a mark in the IR protocol
110 #define BEO_DATALINK_MARK (BEO_UNIT / 2) // The length of a mark in the Datalink protocol
111 
112 #define BEO_PULSE_LENGTH_ZERO BEO_UNIT // The length of a one to zero transition
113 #define BEO_PULSE_LENGTH_EQUAL (2 * BEO_UNIT) // 6250 The length of an equal bit
114 #define BEO_PULSE_LENGTH_ONE (3 * BEO_UNIT) // 9375 The length of a zero to one transition
115 #define BEO_PULSE_LENGTH_TRAILING_BIT (4 * BEO_UNIT) // 12500 The length of the stop bit
116 #define BEO_PULSE_LENGTH_START_BIT (5 * BEO_UNIT) // 15625 The length of the start bit
117 // It is not allowed to send two ones or zeros, you must send a one or zero and a equal instead.
118 
119 //#define BEO_LOCAL_DEBUG
120 //#define BEO_LOCAL_TRACE
121 
122 #ifdef BEO_LOCAL_DEBUG
123 # define BEO_DEBUG_PRINT(...) Serial.print(__VA_ARGS__)
124 # define BEO_DEBUG_PRINTLN(...) Serial.println(__VA_ARGS__)
125 #else
126 # define BEO_DEBUG_PRINT(...) void()
127 # define BEO_DEBUG_PRINTLN(...) void()
128 #endif
129 
130 #ifdef BEO_LOCAL_TRACE
131 # undef BEO_TRACE_PRINT
132 # undef BEO_TRACE_PRINTLN
133 # define BEO_TRACE_PRINT(...) Serial.print(__VA_ARGS__)
134 # define BEO_TRACE_PRINTLN(...) Serial.println(__VA_ARGS__)
135 #else
136 # define BEO_TRACE_PRINT(...) void()
137 # define BEO_TRACE_PRINTLN(...) void()
138 #endif
139 
140 /************************************
141  * Start of send and decode functions
142  ************************************/
143 
144 /*
145  * TODO aNumberOfRepeats are handled not correctly if ENABLE_BEO_WITHOUT_FRAME_GAP is defined
146  */
147 void IRsend::sendBangOlufsen(uint16_t aHeader, uint8_t aData, int_fast8_t aNumberOfRepeats, int8_t aNumberOfHeaderBits) {
148  for (int_fast8_t i = 0; i < aNumberOfRepeats + 1; ++i) {
149  sendBangOlufsenRaw((uint32_t(aHeader) << 8) | aData, aNumberOfHeaderBits + 8, i != 0);
150  }
151 }
152 
153 void IRsend::sendBangOlufsenDataLink(uint32_t aHeader, uint8_t aData, int_fast8_t aNumberOfRepeats, int8_t aNumberOfHeaderBits) {
154  for (int_fast8_t i = 0; i < aNumberOfRepeats + 1; ++i) {
155  sendBangOlufsenRawDataLink((uint64_t(aHeader) << 8) | aData, aNumberOfHeaderBits + 8, i != 0, true);
156  }
157 }
158 
159 /*
160  * @param aBackToBack If true send data back to back, which cannot be decoded if ENABLE_BEO_WITHOUT_FRAME_GAP is NOT defined
161  */
162 void IRsend::sendBangOlufsenRaw(uint32_t aRawData, int_fast8_t aBits, bool aBackToBack) {
163 #if defined(USE_NO_SEND_PWM) || BEO_KHZ == 38 // BEO_KHZ == 38 is for unit test which runs the B&O protocol with 38 kHz
164  /*
165  * 455 kHz PWM is currently not supported, maximum is 180 kHz
166  */
168 
169 // AGC / Start - 3 bits + first constant 0 header bit described in the official documentation
170  if (!aBackToBack) {
171  mark(BEO_IR_MARK);
172  }
174  mark(BEO_IR_MARK);
176  mark(BEO_IR_MARK);
178 
179 // First bit of header is assumed to be a constant 0 to have a fixed state to begin with the equal decisions.
180 // So this first 0 is treated as the last bit of AGC
181  mark(BEO_IR_MARK);
183  bool tLastBitValueWasOne = false;
184 
185 // Header / Data
186  uint32_t mask = 1UL << (aBits - 1);
187  for (; mask; mask >>= 1) {
188  if (tLastBitValueWasOne && !(aRawData & mask)) {
189  mark(BEO_IR_MARK);
191  tLastBitValueWasOne = false;
192  } else if (!tLastBitValueWasOne && (aRawData & mask)) {
193  mark(BEO_IR_MARK);
195  tLastBitValueWasOne = true;
196  } else {
197  mark(BEO_IR_MARK);
199  }
200  }
201 
202 // Stop
203  mark(BEO_IR_MARK);
205  mark(BEO_IR_MARK);
206 
207 #if !defined(DISABLE_CODE_FOR_RECEIVER)
209 #endif
210 #else
211  (void) aRawData;
212  (void) aBits;
213  (void) aBackToBack;
214 #endif
215 }
216 
217 /*
218  * Version with 64 bit aRawData, which can send both timings, but costs more program memory
219  * @param aBackToBack If true send data back to back, which cannot be decoded if ENABLE_BEO_WITHOUT_FRAME_GAP is NOT defined
220  * @param aUseDatalinkTiming if false it does the same as sendBangOlufsenRaw()
221  */
222 void IRsend::sendBangOlufsenRawDataLink(uint64_t aRawData, int_fast8_t aBits, bool aBackToBack, bool aUseDatalinkTiming) {
223 #if defined(USE_NO_SEND_PWM) || BEO_KHZ == 38 // BEO_KHZ == 38 is for unit test which runs the B&O protocol with 38 kHz instead 0f 455 kHz
224  uint16_t tSendBEOMarkLength = aUseDatalinkTiming ? BEO_DATALINK_MARK : BEO_IR_MARK;
225 
226  /*
227  * 455 kHz PWM is currently not supported, maximum is 180 kHz
228  */
230 
231 // AGC / Start - 3 bits + first constant 0 header bit described in the official documentation
232  if (!aBackToBack) {
233  mark(tSendBEOMarkLength);
234  }
235  space(BEO_PULSE_LENGTH_ZERO - tSendBEOMarkLength);
236  mark(tSendBEOMarkLength);
237  space(BEO_PULSE_LENGTH_ZERO - tSendBEOMarkLength);
238  mark(tSendBEOMarkLength);
239  space(BEO_PULSE_LENGTH_START_BIT - tSendBEOMarkLength);
240 
241 // First bit of header is assumed to be a constant 0 to have a fixed state to begin with the equal decisions.
242 // So this first 0 is treated as the last bit of AGC
243  mark(tSendBEOMarkLength);
244  space(BEO_PULSE_LENGTH_ZERO - tSendBEOMarkLength);
245  bool tLastBitValueWasOne = false;
246 
247 // Header / Data
248  uint32_t mask = 1UL << (aBits - 1);
249  for (; mask; mask >>= 1) {
250  if (tLastBitValueWasOne && !(aRawData & mask)) {
251  mark(tSendBEOMarkLength);
252  space(BEO_PULSE_LENGTH_ZERO - tSendBEOMarkLength);
253  tLastBitValueWasOne = false;
254  } else if (!tLastBitValueWasOne && (aRawData & mask)) {
255  mark(tSendBEOMarkLength);
256  space(BEO_PULSE_LENGTH_ONE - tSendBEOMarkLength);
257  tLastBitValueWasOne = true;
258  } else {
259  mark(tSendBEOMarkLength);
260  space(BEO_PULSE_LENGTH_EQUAL - tSendBEOMarkLength);
261  }
262  }
263 
264 // Stop
265  mark(tSendBEOMarkLength);
266  space(BEO_PULSE_LENGTH_TRAILING_BIT - tSendBEOMarkLength);
267  mark(tSendBEOMarkLength);
268 
269 #if !defined(DISABLE_CODE_FOR_RECEIVER)
271 #endif
272 #else
273  (void) aRawData;
274  (void) aBits;
275  (void) aUseDatalinkTiming;
276  (void) aBackToBack;
277 #endif
278 }
279 
280 #define BEO_MATCH_DELTA (BEO_UNIT / 2 - MICROS_PER_TICK)
281 static bool matchBeoLength(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros) {
282  const uint16_t tMeasuredMicros = aMeasuredTicks * MICROS_PER_TICK;
283  return aMatchValueMicros - BEO_MATCH_DELTA < tMeasuredMicros && tMeasuredMicros < aMatchValueMicros + BEO_MATCH_DELTA;
284 }
285 
287 #if defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
288  if (decodedIRData.rawDataPtr->rawlen != 6 && decodedIRData.rawDataPtr->rawlen < 36) { // 16 bits minimum
289 #else
290  if (decodedIRData.rawDataPtr->rawlen < 44) { // 16 bits minimum
291 #endif
292  return false;
293  }
294 
295 #if defined(SUPPORT_BEO_DATALINK_TIMING_FOR_DECODE)
296  uint16_t protocolMarkLength = 0; // contains BEO_IR_MARK or BEO_DATALINK_MARK depending of 4. mark received
297  uint64_t tDecodedRawData = 0;
298 #else
299  uint32_t tDecodedRawData = 0;
300 #endif
301  uint8_t tLastDecodedBitValue = 0; // the last start bit is assumed to be zero
302  uint8_t tPulseNumber = 0;
303  uint8_t tBitNumber = 0;
304 
305  BEO_TRACE_PRINT(F("Pre gap: "));
307  BEO_TRACE_PRINT(F(" raw len: "));
309 
310 #if defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
311  /*
312  * Check if we have the AGC part of the first frame in a row
313  */
314  if (decodedIRData.rawDataPtr->rawlen == 6) {
320  BEO_TRACE_PRINTLN(F("B&O: AGC only part detected"));
321  } else {
322  return false; // no B&O protocol
323  }
324  } else {
325  /*
326  * Check if leading gap is trailing bit of first frame
327  */
330  BEO_TRACE_PRINTLN(F(": Leading gap is wrong")); // Leading gap is trailing bit of first frame
331  return false; // no B&O protocol
332  }
333 
335 #if defined(SUPPORT_BEO_DATALINK_TIMING_FOR_DECODE)
336  protocolMarkLength = BEO_IR_MARK;
338  protocolMarkLength = BEO_DATALINK_MARK;
339 #endif
340  } else {
342  BEO_TRACE_PRINTLN(F(": mark length is wrong"));
343  return false;
344  }
345 
346  // skip first zero header bit
347  for (uint8_t tRawBufferMarkIndex = 3; tRawBufferMarkIndex < decodedIRData.rawDataPtr->rawlen; tRawBufferMarkIndex += 2) {
348 #else
349  for (uint8_t tRawBufferMarkIndex = 1; tRawBufferMarkIndex < decodedIRData.rawDataPtr->rawlen; tRawBufferMarkIndex += 2) {
350 #endif
351 
352  uint16_t markLength = decodedIRData.rawDataPtr->rawbuf[tRawBufferMarkIndex];
353  uint16_t spaceLength = decodedIRData.rawDataPtr->rawbuf[tRawBufferMarkIndex + 1];
354 
355  BEO_TRACE_PRINT(tPulseNumber);
356  BEO_TRACE_PRINT(' ');
357  BEO_TRACE_PRINT(markLength * MICROS_PER_TICK);
358  BEO_TRACE_PRINT(' ');
359  BEO_TRACE_PRINT(spaceLength * MICROS_PER_TICK);
360  BEO_TRACE_PRINT(F(" ("));
361  BEO_TRACE_PRINT((markLength + spaceLength) * MICROS_PER_TICK);
362  BEO_TRACE_PRINTLN(F(") "));
363 
364 #if !defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
365  /*
366  * Handle the first 4 start bits
367  * Check if the 3. bit is the long start bit. If we see the long start bit earlier, synchronize bit counter.
368  */
369  if (tPulseNumber < 4) {
370  if (tPulseNumber < 2) {
371  // bit 0 and 1
372  if (matchSpace(spaceLength, BEO_PULSE_LENGTH_START_BIT - BEO_IR_MARK)) {
373  BEO_TRACE_PRINTLN(F(": detected long start bit -> synchronize state now"));
374  tPulseNumber = 2;
375  }
376  } else {
377  if (tPulseNumber == 3) {
378  if (matchMark(markLength, BEO_IR_MARK)) {
379 #if defined(SUPPORT_BEO_DATALINK_TIMING_FOR_DECODE)
380  protocolMarkLength = BEO_IR_MARK;
381  } else if (matchMark(markLength, BEO_DATALINK_MARK)) {
382  protocolMarkLength = BEO_DATALINK_MARK;
383 #endif
384  } else {
386  BEO_DEBUG_PRINTLN(F(": 4. (start) mark length is wrong"));
387  return false;
388  }
389  }
390  // bit 2 and 3
391  if (!matchBeoLength(markLength + spaceLength,
392  (tPulseNumber == 2) ? BEO_PULSE_LENGTH_START_BIT : BEO_PULSE_LENGTH_ZERO)) {
394  BEO_DEBUG_PRINTLN(F(": Start length is wrong"));
395  return false;
396  }
397  }
398  } else {
399 #endif
400 
401  /*
402  * Decode header / data
403  * First check for length of mark
404  */
405 #if defined(SUPPORT_BEO_DATALINK_TIMING_FOR_DECODE)
406  if (!matchMark(markLength, protocolMarkLength)) {
407 #else
408  if (!matchMark(markLength, BEO_IR_MARK)) {
409 #endif
411  BEO_DEBUG_PRINTLN(F(": Mark length is wrong"));
412  return false;
413  }
414 
415  /*
416  * Check for stop after receiving at least 8 bits for data and 4 bits for header
417  */
418  if (tBitNumber > BEO_DATA_BITS + 4) {
419  if (matchBeoLength(markLength + spaceLength, BEO_PULSE_LENGTH_TRAILING_BIT)) {
421  BEO_DEBUG_PRINTLN(F(": Trailing bit detected"));
422  break;
423  }
424 #if !defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
425  if (tRawBufferMarkIndex >= decodedIRData.rawDataPtr->rawlen - 3) { // (rawlen - 3) is index of trailing bit mark
427  BEO_DEBUG_PRINTLN(F(": End of buffer, but no trailing bit detected"));
428  return false;
429  }
430 #endif
431  }
432 
433  /*
434  * Decode bit
435  */
436  if (tLastDecodedBitValue == 0 && matchBeoLength(markLength + spaceLength, BEO_PULSE_LENGTH_ONE)) {
437  tLastDecodedBitValue = 1;
438  } else if (tLastDecodedBitValue == 1 && matchBeoLength(markLength + spaceLength, BEO_PULSE_LENGTH_ZERO)) {
439  tLastDecodedBitValue = 0;
440  } else if (!matchBeoLength(markLength + spaceLength, BEO_PULSE_LENGTH_EQUAL)) {
442  BEO_DEBUG_PRINT(F(": Index="));
443  BEO_DEBUG_PRINT(tRawBufferMarkIndex);
444  BEO_DEBUG_PRINT(F(" Length "));
445  BEO_DEBUG_PRINT((markLength + spaceLength) * MICROS_PER_TICK);
446  BEO_DEBUG_PRINTLN(F(" is wrong"));
447  return false;
448  }
449  tDecodedRawData <<= 1;
450  tDecodedRawData |= tLastDecodedBitValue;
451  ++tBitNumber;
452  BEO_TRACE_PRINT(F("Bits "));
453  BEO_TRACE_PRINT(tBitNumber);
454  BEO_TRACE_PRINT(F(" "));
455  BEO_TRACE_PRINT(uint32_t(tDecodedRawData >> BEO_DATA_BITS), HEX);
456  BEO_TRACE_PRINT(F(" "));
457  BEO_TRACE_PRINTLN(uint8_t(tDecodedRawData & ((1 << BEO_DATA_BITS) - 1)), HEX);
458  // End of bit decode
459 #if !defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
460  }
461 
462 #else
463  /*
464  * Check for last bit after decoding it
465  */
466  if (tRawBufferMarkIndex >= decodedIRData.rawDataPtr->rawlen - 3) { // (rawlen - 3) is index of last bit mark
468  BEO_TRACE_PRINTLN(F(": Last bit reached"));
469  break;
470  }
471 #endif
472 
473  ++tPulseNumber;
474  }
475 #if defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
476  }
477 #endif
478 
480  decodedIRData.address = tDecodedRawData >> BEO_DATA_BITS; // lower header tBitNumber
481  decodedIRData.command = tDecodedRawData & ((1 << BEO_DATA_BITS) - 1); // lower 8 tBitNumber
482  decodedIRData.extra = tDecodedRawData >> (BEO_DATA_BITS + 16); // upper header tBitNumber
483  decodedIRData.numberOfBits = tBitNumber;
485  decodedIRData.decodedRawData = tDecodedRawData;
486 
487  return true;
488 }
489 #endif // _IR_BANG_OLUFSEN_HPP
IRData::address
uint16_t address
Decoded address, Distance protocol (tMarkTicksLong (if tMarkTicksLong == 0, then tMarkTicksShort) << ...
Definition: IRProtocol.h:117
MICROS_PER_TICK
#define MICROS_PER_TICK
microseconds per clock interrupt tick
Definition: IRremote.hpp:258
IRData::numberOfBits
uint16_t numberOfBits
Number of bits received for data (address + command + parity) - to determine protocol length if diffe...
Definition: IRProtocol.h:120
IRsend::aNumberOfRepeats
void uint8_t int_fast8_t aNumberOfRepeats
Definition: IRremoteInt.h:474
IRsend::sendBangOlufsenRaw
void sendBangOlufsenRaw(uint32_t aRawData, int_fast8_t aBits, bool aBackToBack=false)
Definition: ir_BangOlufsen.hpp:162
BEO_DEBUG_PRINT
#define BEO_DEBUG_PRINT(...)
Definition: ir_BangOlufsen.hpp:126
BEO_PULSE_LENGTH_ONE
#define BEO_PULSE_LENGTH_ONE
Definition: ir_BangOlufsen.hpp:114
IRsend::mark
void mark(unsigned int aMarkMicros)
Sends an IR mark for the specified number of microseconds.
Definition: IRSend.hpp:757
BEO_PULSE_LENGTH_TRAILING_BIT
#define BEO_PULSE_LENGTH_TRAILING_BIT
Definition: ir_BangOlufsen.hpp:115
IRrecv::restartAfterSend
void restartAfterSend()
Restarts receiver after send.
Definition: IRReceive.hpp:346
BEO_PULSE_LENGTH_START_BIT
#define BEO_PULSE_LENGTH_START_BIT
Definition: ir_BangOlufsen.hpp:116
IRData::rawDataPtr
irparams_struct * rawDataPtr
Pointer of the raw timing data to be decoded. Mainly the OverflowFlag and the data buffer filled by r...
Definition: IRProtocol.h:126
IRData::decodedRawData
IRRawDataType decodedRawData
Up to 32/64 bit decoded raw data, to be used for send functions.
Definition: IRProtocol.h:122
irparams_struct::rawlen
uint_fast8_t rawlen
counter of entries in rawbuf
Definition: IRremoteInt.h:109
BEO_MATCH_DELTA
#define BEO_MATCH_DELTA
Definition: ir_BangOlufsen.hpp:280
BEO_KHZ
#define BEO_KHZ
Definition: IRProtocol.h:136
IRrecv::decodeBangOlufsen
bool decodeBangOlufsen()
Definition: ir_BangOlufsen.hpp:286
BEO_DATA_BITS
#define BEO_DATA_BITS
Definition: ir_BangOlufsen.hpp:105
IRrecv::decodedIRData
IRData decodedIRData
Definition: IRremoteInt.h:305
matchSpace
bool matchSpace(unsigned int aMeasuredTicks, unsigned int aMatchValueMicros)
Compensate for spaces shortened by demodulator hardware.
Definition: IRReceive.hpp:1033
BEO_IR_MARK
#define BEO_IR_MARK
Definition: ir_BangOlufsen.hpp:109
IRData::flags
uint8_t flags
See IRDATA_FLAGS_* definitions above.
Definition: IRProtocol.h:121
matchBeoLength
static bool matchBeoLength(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros)
Definition: ir_BangOlufsen.hpp:281
IRsend::sendBangOlufsenDataLink
void sendBangOlufsenDataLink(uint32_t aHeader, uint8_t aData, int_fast8_t aNumberOfRepeats=NO_REPEATS, int8_t aNumberOfHeaderBits=8)
Definition: ir_BangOlufsen.hpp:153
irparams_struct::rawbuf
unsigned int rawbuf[RAW_BUFFER_LENGTH]
raw data / tick counts per mark/space, first entry is the length of the gap between previous and curr...
Definition: IRremoteInt.h:113
IRData::command
uint16_t command
Decoded command, Distance protocol (tMarkTicksShort << 8) | tSpaceTicksShort.
Definition: IRProtocol.h:118
BANG_OLUFSEN
@ BANG_OLUFSEN
Definition: IRProtocol.h:66
BEO_PULSE_LENGTH_EQUAL
#define BEO_PULSE_LENGTH_EQUAL
Definition: ir_BangOlufsen.hpp:113
BEO_TRACE_PRINTLN
#define BEO_TRACE_PRINTLN(...)
Definition: ir_BangOlufsen.hpp:137
BEO_PULSE_LENGTH_ZERO
#define BEO_PULSE_LENGTH_ZERO
Definition: ir_BangOlufsen.hpp:112
IRDATA_FLAGS_IS_MSB_FIRST
#define IRDATA_FLAGS_IS_MSB_FIRST
Value is mainly determined by the (known) protocol.
Definition: IRProtocol.h:100
IRsend::space
static void space(unsigned int aSpaceMicros)
Sends an IR space for the specified number of microseconds.
Definition: IRSend.hpp:927
BEO_TRACE_PRINT
#define BEO_TRACE_PRINT(...)
Definition: ir_BangOlufsen.hpp:136
IRData::extra
uint16_t extra
Contains upper 16 bit of Magiquest WandID, Kaseikyo unknown vendor ID and Distance protocol (HeaderMa...
Definition: IRProtocol.h:119
BEO_DATALINK_MARK
#define BEO_DATALINK_MARK
Definition: ir_BangOlufsen.hpp:110
IRsend::sendBangOlufsenRawDataLink
void sendBangOlufsenRawDataLink(uint64_t aRawData, int_fast8_t aBits, bool aBackToBack=false, bool aUseDatalinkTiming=false)
Definition: ir_BangOlufsen.hpp:222
BEO_DEBUG_PRINTLN
#define BEO_DEBUG_PRINTLN(...)
Definition: ir_BangOlufsen.hpp:127
matchMark
bool matchMark(unsigned int aMeasuredTicks, unsigned int aMatchValueMicros)
Compensate for marks exceeded by demodulator hardware.
Definition: IRReceive.hpp:1000
IRData::protocol
decode_type_t protocol
UNKNOWN, NEC, SONY, RC5, PULSE_DISTANCE, ...
Definition: IRProtocol.h:116
IRrecv::getProtocolString
const char * getProtocolString()
Definition: IRReceive.hpp:1593
IRsend::sendBangOlufsen
void sendBangOlufsen(uint16_t aHeader, uint8_t aData, int_fast8_t aNumberOfRepeats=NO_REPEATS, int8_t aNumberOfHeaderBits=8)
Definition: ir_BangOlufsen.hpp:147
IrReceiver
IRrecv IrReceiver
The receiver instance.
Definition: IRReceive.hpp:59
IRsend::enableIROut
void enableIROut(uint_fast8_t aFrequencyKHz)
Enables IR output.
Definition: IRSend.hpp:961