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-2025 Daniel Wallner and Armin Joachimsmeyer
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 // This block must be located after the includes of other *.hpp files
38 //#define LOCAL_DEBUG // This enables debug output only for this file - only for development
39 //#define LOCAL_TRACE // This enables trace output only for this file - only for development
40 #include "LocalDebugLevelStart.h"
41 
46 //==============================================================================
47 //
48 //
49 // Bang & Olufsen
50 //
51 //
52 //==============================================================================
53 // https://www.mikrocontroller.net/attachment/33137/datalink.pdf
54 // https://www.mikrocontroller.net/articles/IRMP_-_english#B&O
55 // BEO is a Pulse Distance Protocol with 200 us pulse
56 // This protocol is unusual in two ways:
57 // 1. The carrier frequency is 455 kHz
58 // You can build your own receiver as Bang & Olufsen did (check old schematics) or use a TSOP7000
59 // Vishay stopped producing TSOP7000 since 2009 so you will probably only find counterfeits:
60 // https://www.vishay.com/files/whatsnew/doc/ff_FastFacts_CounterfeitTSOP7000_Dec72018.pdf
61 // It is also likely that you will need an oscilloscope to debug a counterfeit TSOP7000
62 // The specimen used to test this code was very noisy and had a very low output current
63 // A somewhat working fix was to put a 4n7 capacitor across the output and ground followed by a pnp emitter follower
64 // Other examples may require a different treatment
65 // This particular receiver also did receive lower frequencies but rather poorly and with a lower delay than usual
66 // 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
67 // 2. A stream of messages can be sent back to back with a new message immediately following the previous stop space
68 // It might be that this only happens over IR and not on the datalink protocol
69 // You can choose to support this or not:
70 // Mode 1: Mode with gaps between frames
71 // Do NOT define ENABLE_BEO_WITHOUT_FRAME_GAP and set RECORD_GAP_MICROS to at least 16000 to accept the unusually long 3. start space
72 // Can only receive single messages. Back to back repeats will result in overflow
73 // Mode 2: Break at start mode
74 // Define ENABLE_BEO_WITHOUT_FRAME_GAP and set RECORD_GAP_MICROS to less than 15000
75 // This treats the 3. start space of 15.5 ms as a gap between 2 messages, which makes decoding easier :-).
76 // The receiving of a transmission will then result in a dummy decode of the first 2 start bits with 0 bits data
77 // followed by a 15.5 ms gap and a data frame with one start bit (originally sent as 4. start bit).
78 // If the receiver is not immediately resumed after the 2 start bit frame, partial second frame will be decoded!
79 // Thus debug printing in the wrong place is very likely to break reception!
80 // Make sure to check the number of bits to filter dummy and incomplete messages.
81 // !!! We assume that the real implementations never set the official first header bit to anything other than 0 !!!
82 // !!! We therefore use 4 start bits instead of the specified 3 and in turn ignore the first header bit of the specification !!!
83 // IR messages are 16 bits long. Datalink messages have different lengths.
84 // This implementation supports up to 40 bits total length split into 8 bit data/command and a header/address of variable length
85 // Header data with more than 16 bits is stored in decodedIRData.extra
86 // 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.
87 //
88 // MSB first, 4 start bits + 8 (to 16?) bit address + 8 bit command + 1 special trailing bit + 1 stop bit.
89 // Address can be longer than 8 bit.
90 /*
91  * Options for this decoder
92  *
93  */
94 #define ENABLE_BEO_WITHOUT_FRAME_GAP // Requires additional 30 bytes program memory. Enabled by default, see https://github.com/Arduino-IRremote/Arduino-IRremote/discussions/1181
95 //#define SUPPORT_BEO_DATALINK_TIMING_FOR_DECODE // This also supports headers up to 32 bit. Requires additional 150 bytes program memory.
96 #if defined(DECODE_BEO)
97 # if defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
98 # if RECORD_GAP_MICROS > 15000 && !defined(SUPPRESS_BEO_RECORD_GAP_MICROS_WARNING)
99 #warning If defined ENABLE_BEO_WITHOUT_FRAME_GAP, RECORD_GAP_MICROS must be set to <= 15000 by "#define RECORD_GAP_MICROS 12750"
100 # endif
101 # else
102 # if RECORD_GAP_MICROS < 16000 && !defined(SUPPRESS_BEO_RECORD_GAP_MICROS_WARNING)
103 #error If not defined ENABLE_BEO_WITHOUT_FRAME_GAP, RECORD_GAP_MICROS must be set to a value >= 16000 by "#define RECORD_GAP_MICROS 16000"
104 # endif
105 # endif
106 #endif
107 
108 #define BEO_DATA_BITS 8 // Command or character
109 
110 #define BEO_UNIT 3125 // All timings are in microseconds
111 
112 #define BEO_BIT_MARK 200 // The length of a mark in the IR protocol
113 
114 // With decode we see length from 200 to 300 and the 300 leads to errors, if we use 200 as mark length for decode.
115 // And the space value is at least 3125, so we can do a reluctant test for the mark anyway.
116 #define BEO_BIT_MARK_FOR_DECODE 250
117 #define BEO_DATALINK_BIT_MARK (BEO_UNIT / 2) // The length of a mark in the Datalink protocol
118 
119 /*
120  * For all spaces really sent, the time of one bit mark (200 or 1562) is subtracted before the durations defined below
121  */
122 #define BEO_ZERO_SPACE BEO_UNIT // 3125
123 #define BEO_REPETITION_OF_PREVIOUS_BIT_SPACE (2 * BEO_UNIT) // 6250 The length of an repetition bit
124 #define BEO_ONE_SPACE (3 * BEO_UNIT) // 9375
125 #define BEO_TRAILING_BIT_SPACE (4 * BEO_UNIT) // 12500 The length of the space of stop bit
126 #define BEO_START_BIT_SPACE (5 * BEO_UNIT) // 15625
127 #define BEO_REPEAT_PERIOD 100000 // 100 ms - Not used yet
128 
129 // It is not allowed to send two ones or zeros, you must send a one or zero and a equal instead.
130 
131 /************************************
132  * Start of send and decode functions
133  ************************************/
134 
135 /*
136  * TODO aNumberOfRepeats are handled not correctly if ENABLE_BEO_WITHOUT_FRAME_GAP is defined
137  * By default 16 bits are sent.
138  * @param aNumberOfHeaderBits default is 8, can be 24 at maximum
139  */
140 void IRsend::sendBangOlufsen(uint16_t aHeader, uint8_t aData, int_fast8_t aNumberOfRepeats, int8_t aNumberOfHeaderBits) {
141  for (int_fast8_t i = 0; i < aNumberOfRepeats + 1; ++i) {
142  // send 16 bits by default
143  sendBangOlufsenRaw((uint32_t(aHeader) << aNumberOfHeaderBits) | aData, aNumberOfHeaderBits + BEO_DATA_BITS, i != 0);
144  }
145 }
146 
147 void IRsend::sendBangOlufsenDataLink(uint32_t aHeader, uint8_t aData, int_fast8_t aNumberOfRepeats, int8_t aNumberOfHeaderBits) {
148  for (int_fast8_t i = 0; i < aNumberOfRepeats + 1; ++i) {
149  sendBangOlufsenRawDataLink((uint64_t(aHeader) << aNumberOfHeaderBits) | aData, aNumberOfHeaderBits + BEO_DATA_BITS, i != 0,
150  true);
151  }
152 }
153 
154 /*
155  * @param aBackToBack If true send data back to back, which cannot be decoded if ENABLE_BEO_WITHOUT_FRAME_GAP is NOT defined
156  */
157 void IRsend::sendBangOlufsenRaw(uint32_t aRawData, int_fast8_t aBits, bool aBackToBack) {
158 #if defined(USE_NO_SEND_PWM) || defined(SEND_PWM_BY_TIMER) || BEO_KHZ == 38 // BEO_KHZ == 38 is for unit test which runs the B&O protocol with 38 kHz
159 
160  /*
161  * 455 kHz PWM is currently only supported with SEND_PWM_BY_TIMER defined, otherwise maximum is 180 kHz
162  */
163 # if !defined(USE_NO_SEND_PWM)
164 # if defined(SEND_PWM_BY_TIMER)
165  enableHighFrequencyIROut (BEO_KHZ);
166 # elif (BEO_KHZ == 38)
167  enableIROut (BEO_KHZ); // currently only for unit test
168 # endif
169 # endif
170 
171 // AGC / Start - 3 bits + first constant 0 header bit described in the official documentation
172  if (!aBackToBack) {
174  }
180 
181 // First bit of header is assumed to be a constant 0 to have a fixed state to begin with the equal decisions.
182 // So this first 0 is treated as the last bit of AGC
185  bool tLastBitValueWasOne = false;
186 
187  // Send 8 (default) to 24 bit header and 8 bit data.
188  uint32_t mask = 1UL << (aBits - 1);
189  for (; mask; mask >>= 1) {
190  if (tLastBitValueWasOne && !(aRawData & mask)) {
193  tLastBitValueWasOne = false;
194  } else if (!tLastBitValueWasOne && (aRawData & mask)) {
197  tLastBitValueWasOne = true;
198  } else {
201  }
202  }
203 
204 // Stop
208 
209 #else
210  (void) aRawData;
211  (void) aBits;
212  (void) aBackToBack;
213 #endif
214 }
215 
216 /*
217  * Version with 64 bit aRawData, which can send both timings, but costs more program memory
218  * @param aBackToBack If true send data back to back, which cannot be decoded if ENABLE_BEO_WITHOUT_FRAME_GAP is NOT defined
219  * @param aUseDatalinkTiming if false it does the same as sendBangOlufsenRaw()
220  */
221 void IRsend::sendBangOlufsenRawDataLink(uint64_t aRawData, int_fast8_t aBits, bool aBackToBack, bool aUseDatalinkTiming) {
222 #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
223  uint16_t tSendBEOMarkLength = aUseDatalinkTiming ? BEO_DATALINK_BIT_MARK : BEO_BIT_MARK;
224 
225  /*
226  * 455 kHz PWM is currently not supported, maximum is 180 kHz
227  */
228 #if !defined(USE_NO_SEND_PWM)
230 #endif
231 
232 // AGC / Start - 3 bits + first constant 0 header bit described in the official documentation
233  if (!aBackToBack) {
234  mark(tSendBEOMarkLength);
235  }
236  space(BEO_ZERO_SPACE - tSendBEOMarkLength);
237  mark(tSendBEOMarkLength);
238  space(BEO_ZERO_SPACE - tSendBEOMarkLength);
239  mark(tSendBEOMarkLength);
240  space(BEO_START_BIT_SPACE - tSendBEOMarkLength);
241 
242 // First bit of header is assumed to be a constant 0 to have a fixed state to begin with the equal decisions.
243 // So this first 0 is treated as the last bit of AGC
244  mark(tSendBEOMarkLength);
245  space(BEO_ZERO_SPACE - tSendBEOMarkLength);
246  bool tLastBitValueWasOne = false;
247 
248 // Header / Data
249  uint32_t mask = 1UL << (aBits - 1);
250  for (; mask; mask >>= 1) {
251  if (tLastBitValueWasOne && !(aRawData & mask)) {
252  mark(tSendBEOMarkLength);
253  space(BEO_ZERO_SPACE - tSendBEOMarkLength);
254  tLastBitValueWasOne = false;
255  } else if (!tLastBitValueWasOne && (aRawData & mask)) {
256  mark(tSendBEOMarkLength);
257  space(BEO_ONE_SPACE - tSendBEOMarkLength);
258  tLastBitValueWasOne = true;
259  } else {
260  mark(tSendBEOMarkLength);
261  space(BEO_REPETITION_OF_PREVIOUS_BIT_SPACE - tSendBEOMarkLength);
262  }
263  }
264 
265 // Stop
266  mark(tSendBEOMarkLength);
267  space(BEO_TRAILING_BIT_SPACE - tSendBEOMarkLength);
268  mark(tSendBEOMarkLength);
269 
270 #else
271  (void) aRawData;
272  (void) aBits;
273  (void) aUseDatalinkTiming;
274  (void) aBackToBack;
275 #endif
276 }
277 
278 #define BEO_MATCH_DELTA (BEO_UNIT / 2 - MICROS_PER_TICK) // use a bigger margin for match than regular matching function
279 static bool matchBeoLength(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros) {
280  const uint16_t tMeasuredMicros = aMeasuredTicks * MICROS_PER_TICK;
281  return aMatchValueMicros - BEO_MATCH_DELTA < tMeasuredMicros && tMeasuredMicros < aMatchValueMicros + BEO_MATCH_DELTA;
282 }
283 
285 #if defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
286  if (decodedIRData.rawlen != 6 && decodedIRData.rawlen < 36) { // 16 bits minimum
287  DEBUG_PRINT(F("B&O: Data length="));
289  DEBUG_PRINTLN(F(" is not < 36 or 6"));
290 #else
291  if (decodedIRData.rawlen < 44) { // 16 bits minimum
292  DEBUG_PRINT(F("B&O: Data length="));
294  DEBUG_PRINTLN(F(" is not < 44"));
295 #endif
296  return false;
297  }
298 
299 #if defined(SUPPORT_BEO_DATALINK_TIMING_FOR_DECODE)
300  uint16_t protocolMarkLength = 0; // contains BEO_BIT_MARK or BEO_DATALINK_BIT_MARK depending of 4. mark received
301  uint64_t tDecodedRawData = 0;
302 #else
303  uint32_t tDecodedRawData = 0;
304 #endif
305  uint8_t tLastDecodedBitValue = 0; // the last start bit is assumed to be zero
306  uint8_t tPulseNumber = 0;
307  uint8_t tBitNumber = 0;
308 
309  TRACE_PRINT(F("Pre gap: "));
310  TRACE_PRINT((uint32_t)decodedIRData.initialGapTicks * 50);
311  TRACE_PRINT(F(" raw len: "));
313 
314 #if defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
315  /*
316  * Check if we have the AGC part of the first frame, i.e. start bit 1 and 2.
317  */
318  if (decodedIRData.rawlen == 6) {
322  TRACE_PRINTLN(F("B&O: AGC only part (start bits 1 + 2 of 4) detected"));
323  } else {
324  return false; // no B&O protocol
325  }
326  } else {
327  /*
328  * Check if leading gap is trailing bit of first AGC frame
329  */
331  TRACE_PRINT(F("B&O: Leading gap of ")); // Leading gap is trailing bit of first frame
332  TRACE_PRINT((uint32_t)decodedIRData.initialGapTicks * 50); // Leading gap is trailing bit of first frame
333  TRACE_PRINTLN(F(" us is wrong")); // Leading gap is trailing bit of first frame
334  return false; // no B&O protocol
335  }
336 
338 # if defined(SUPPORT_BEO_DATALINK_TIMING_FOR_DECODE)
339  protocolMarkLength = BEO_BIT_MARK_FOR_DECODE;
341  protocolMarkLength = BEO_DATALINK_BIT_MARK;
342 # endif
343  } else {
344  TRACE_PRINTLN(F("B&O: mark length is wrong"));
345  return false;
346  }
347 
348  // skip first zero header bit
349  for (uint8_t tRawBufferMarkIndex = 3; tRawBufferMarkIndex < decodedIRData.rawlen; tRawBufferMarkIndex += 2) {
350 #else
351  for (uint8_t tRawBufferMarkIndex = 1; tRawBufferMarkIndex < decodedIRData.rawlen; tRawBufferMarkIndex += 2) {
352 #endif // defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
353 
354  uint16_t markLength = irparams.rawbuf[tRawBufferMarkIndex];
355  uint16_t spaceLength = irparams.rawbuf[tRawBufferMarkIndex + 1];
356 
357  TRACE_PRINT(tPulseNumber);
358  TRACE_PRINT(' ');
359  TRACE_PRINT(markLength * MICROS_PER_TICK);
360  TRACE_PRINT(' ');
361  TRACE_PRINT(spaceLength * MICROS_PER_TICK);
362  TRACE_PRINT(F(" ("));
363  TRACE_PRINT((markLength + spaceLength) * MICROS_PER_TICK);
364  TRACE_PRINTLN(F(") "));
365 
366 #if !defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
367  /*
368  * Handle the first 4 start bits
369  * Check if the 3. bit is the long start bit. If we see the long start bit earlier, synchronize bit counter.
370  */
371  if (tPulseNumber < 4) {
372  if (tPulseNumber < 2) {
373  // bit 0 and 1
375  TRACE_PRINTLN(F(": detected long start bit -> synchronize state now"));
376  tPulseNumber = 2;
377  }
378  } else {
379  if (tPulseNumber == 3) {
380  if (matchMark(markLength, BEO_BIT_MARK_FOR_DECODE)) {
381 # if defined(SUPPORT_BEO_DATALINK_TIMING_FOR_DECODE)
382  protocolMarkLength = BEO_BIT_MARK_FOR_DECODE;
383  } else if (matchMark(markLength, BEO_DATALINK_BIT_MARK)) {
384  protocolMarkLength = BEO_DATALINK_BIT_MARK;
385 # endif
386  } else {
387  DEBUG_PRINTLN(F("B&O: 4. (start) mark length is wrong"));
388  return false;
389  }
390  }
391  // bit 2 and 3
392  if (!matchBeoLength(markLength + spaceLength,
393  (tPulseNumber == 2) ? BEO_START_BIT_SPACE : BEO_ZERO_SPACE)) {
394  DEBUG_PRINTLN(F("B&O: Start length is wrong"));
395  return false;
396  }
397  }
398  } else {
399 #endif // !defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
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_BIT_MARK_FOR_DECODE)) {
409 #endif
410  DEBUG_PRINTLN(F("B&O: Mark length is wrong"));
411  return false;
412  }
413 
414  /*
415  * Check for stop after receiving at least 8 bits for data and 4 bits for header
416  */
417  if (tBitNumber > BEO_DATA_BITS + 4) {
418  if (matchBeoLength(markLength + spaceLength, BEO_TRAILING_BIT_SPACE)) {
419  DEBUG_PRINTLN(F("B&O: Trailing bit detected"));
420  break;
421  }
422 #if !defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
423  if (tRawBufferMarkIndex >= decodedIRData.rawlen - 3) { // (rawlen - 3) is index of trailing bit mark
424  DEBUG_PRINTLN(F("B&O: End of buffer, but no trailing bit detected"));
425  return false;
426  }
427 #endif
428  }
429 
430  /*
431  * Decode bit
432  */
433  if (tLastDecodedBitValue == 0 && matchBeoLength(markLength + spaceLength, BEO_ONE_SPACE)) {
434  tLastDecodedBitValue = 1;
435  } else if (tLastDecodedBitValue == 1 && matchBeoLength(markLength + spaceLength, BEO_ZERO_SPACE)) {
436  tLastDecodedBitValue = 0;
437  } else if (!matchBeoLength(markLength + spaceLength, BEO_REPETITION_OF_PREVIOUS_BIT_SPACE)) {
438  DEBUG_PRINT(F("B&O: Index="));
439  DEBUG_PRINT(tRawBufferMarkIndex);
440  DEBUG_PRINT(F(" Length "));
441  DEBUG_PRINT((markLength + spaceLength) * MICROS_PER_TICK);
442  DEBUG_PRINTLN(F(" is wrong"));
443  return false;
444  }
445  tDecodedRawData <<= 1;
446  tDecodedRawData |= tLastDecodedBitValue;
447  ++tBitNumber;
448  TRACE_PRINT(F("Bits "));
449  TRACE_PRINT(tBitNumber);
450  TRACE_PRINT(F(" "));
451  TRACE_PRINT(uint32_t(tDecodedRawData >> BEO_DATA_BITS), HEX);
452  TRACE_PRINT(F(" "));
453  TRACE_PRINTLN(uint8_t(tDecodedRawData & ((1 << BEO_DATA_BITS) - 1)), HEX);
454  // End of bit decode
455 #if !defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
456  }
457 
458 #else
459  /*
460  * Check for last bit after decoding it
461  */
462  if (tRawBufferMarkIndex >= decodedIRData.rawlen - 3) { // (rawlen - 3) is index of last bit mark
463  TRACE_PRINTLN(F("B&O: Last bit reached"));
464  break;
465  }
466 #endif
467 
468  ++tPulseNumber;
469  }
470 #if defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
471  }
472 #endif
473 
474  LongUnion tValue;
475  tValue.ULong = tDecodedRawData;
476  decodedIRData.decodedRawData = tDecodedRawData;
477  decodedIRData.numberOfBits = tBitNumber;
478 
481  tValue.ULong = tValue.ULong >> BEO_DATA_BITS;
483  if (tBitNumber > 24) { // 24 = 8 bit command and 16 bit address
486  } else {
488  }
489 
490  return true;
491 }
492 
494 #include "LocalDebugLevelEnd.h"
495 
496 #endif // _IR_BANG_OLUFSEN_HPP
IRData::address
uint16_t address
Decoded address, Distance protocol (tMarkTicksLong (if tMarkTicksLong == 0, then tMarkTicksShort) << ...
Definition: IRremoteInt.h:164
MICROS_PER_TICK
#define MICROS_PER_TICK
microseconds per clock interrupt tick
Definition: IRremote.hpp:133
LongUnion
Union to specify parts / manifestations of a 32 bit Long without casts and shifts.
Definition: LongUnion.h:59
BEO_ZERO_SPACE
#define BEO_ZERO_SPACE
Definition: ir_BangOlufsen.hpp:122
IRData::numberOfBits
uint16_t numberOfBits
Number of bits received for data (address + command + parity) - to determine protocol length if diffe...
Definition: IRremoteInt.h:173
DEBUG_PRINT
#define DEBUG_PRINT(...)
Definition: LocalDebugLevelStart.h:79
IRsend::aNumberOfRepeats
void int_fast8_t aNumberOfRepeats
Definition: IRremoteInt.h:528
IRsend::sendBangOlufsenRaw
void sendBangOlufsenRaw(uint32_t aRawData, int_fast8_t aBits, bool aBackToBack=false)
Definition: ir_BangOlufsen.hpp:157
BEO_DATALINK_BIT_MARK
#define BEO_DATALINK_BIT_MARK
Definition: ir_BangOlufsen.hpp:117
LongUnion::UByte
struct LongUnion::@4 UByte
TRACE_PRINTLN
#define TRACE_PRINTLN(...)
Definition: LocalDebugLevelStart.h:70
TRACE_PRINT
#define TRACE_PRINT(...)
Definition: LocalDebugLevelStart.h:69
IRsend::mark
void mark(uint16_t aMarkMicros)
Sends an IR mark for the specified number of microseconds.
Definition: IRSend.hpp:1247
BEO_MATCH_DELTA
#define BEO_MATCH_DELTA
Definition: ir_BangOlufsen.hpp:278
IRrecv::decodeBangOlufsen
bool decodeBangOlufsen()
Definition: ir_BangOlufsen.hpp:284
LongUnion::LowByte
uint8_t LowByte
Definition: LongUnion.h:61
BEO_ONE_SPACE
#define BEO_ONE_SPACE
Definition: ir_BangOlufsen.hpp:124
LongUnion::LowWord
uint16_t LowWord
Definition: LongUnion.h:80
matchSpace
bool matchSpace(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros)
Compensate for spaces shortened by demodulator hardware.
Definition: IRReceive.hpp:1375
BEO_KHZ
#define BEO_KHZ
Definition: IRProtocol.h:164
LocalDebugLevelStart.h
BEO_REPETITION_OF_PREVIOUS_BIT_SPACE
#define BEO_REPETITION_OF_PREVIOUS_BIT_SPACE
Definition: ir_BangOlufsen.hpp:123
IRrecv::decodedIRData
IRData decodedIRData
Definition: IRremoteInt.h:401
IRDATA_FLAGS_EXTRA_INFO
#define IRDATA_FLAGS_EXTRA_INFO
There is extra info not contained in address and data (e.g. Kaseikyo unknown vendor ID,...
Definition: IRProtocol.h:130
IRData::flags
uint8_t flags
IRDATA_FLAGS_IS_REPEAT, IRDATA_FLAGS_WAS_OVERFLOW etc. See IRDATA_FLAGS_* definitions above.
Definition: IRremoteInt.h:174
BEO_BIT_MARK_FOR_DECODE
#define BEO_BIT_MARK_FOR_DECODE
Definition: ir_BangOlufsen.hpp:116
IRData::command
uint16_t command
Decoded command, Distance protocol (tMarkTicksShort << 8) | tSpaceTicksShort.
Definition: IRremoteInt.h:165
BANG_OLUFSEN
@ BANG_OLUFSEN
Definition: IRProtocol.h:103
IRData::decodedRawData
IRDecodedRawDataType decodedRawData
Up to 32/64 bit decoded raw data, to be used for send<protocol>Raw functions.
Definition: IRremoteInt.h:167
matchMark
bool matchMark(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros)
Compensate for marks exceeded by demodulator hardware.
Definition: IRReceive.hpp:1327
IRsend::sendBangOlufsen
void sendBangOlufsen(uint16_t aHeader, uint8_t aData, int_fast8_t aNumberOfRepeats=NO_REPEATS, int8_t aNumberOfHeaderBits=8)
Definition: ir_BangOlufsen.hpp:140
irparams_struct::rawbuf
IRRawbufType rawbuf[RAW_BUFFER_LENGTH]
raw data / tick counts per mark/space. With 8 bit we can only store up to 12.7 ms....
Definition: IRremoteInt.h:147
LongUnion::ULong
uint32_t ULong
Definition: LongUnion.h:95
IRrecv::irparams
irparams_struct irparams
Definition: IRremoteInt.h:400
DEBUG_PRINTLN
#define DEBUG_PRINTLN(...)
Definition: LocalDebugLevelStart.h:80
IRDATA_FLAGS_IS_MSB_FIRST
#define IRDATA_FLAGS_IS_MSB_FIRST
Value is mainly determined by the (known) protocol.
Definition: IRProtocol.h:133
BEO_TRAILING_BIT_SPACE
#define BEO_TRAILING_BIT_SPACE
Definition: ir_BangOlufsen.hpp:125
IRData::extra
uint16_t extra
Contains upper 16 bit of Magiquest WandID, Kaseikyo unknown vendor ID and Distance protocol (HeaderMa...
Definition: IRremoteInt.h:166
IRsend::space
static void space(uint16_t aSpaceMicros)
Sends an IR space for the specified number of microseconds.
Definition: IRSend.hpp:1458
IRsend::sendBangOlufsenRawDataLink
void sendBangOlufsenRawDataLink(uint64_t aRawData, int_fast8_t aBits, bool aBackToBack=false, bool aUseDatalinkTiming=false)
Definition: ir_BangOlufsen.hpp:221
BEO_DATA_BITS
#define BEO_DATA_BITS
Definition: ir_BangOlufsen.hpp:108
BEO_BIT_MARK
#define BEO_BIT_MARK
Definition: ir_BangOlufsen.hpp:112
IRData::rawlen
IRRawlenType rawlen
Counter of entries in rawbuf of last received frame.
Definition: IRremoteInt.h:182
LongUnion::MidHighByte
uint8_t MidHighByte
Definition: LongUnion.h:63
LongUnion::UWord
struct LongUnion::@6 UWord
IRData::protocol
decode_type_t protocol
UNKNOWN, NEC, SONY, RC5, PULSE_DISTANCE, ...
Definition: IRremoteInt.h:163
BEO_START_BIT_SPACE
#define BEO_START_BIT_SPACE
Definition: ir_BangOlufsen.hpp:126
IRsend::sendBangOlufsenDataLink
void sendBangOlufsenDataLink(uint32_t aHeader, uint8_t aData, int_fast8_t aNumberOfRepeats=NO_REPEATS, int8_t aNumberOfHeaderBits=8)
Definition: ir_BangOlufsen.hpp:147
IRData::initialGapTicks
uint16_t initialGapTicks
Contains the initial gap (pre 4.4: the value in rawbuf[0]) of the last received frame.
Definition: IRremoteInt.h:183
IRsend::enableIROut
void enableIROut(uint_fast8_t aFrequencyKHz)
Enables IR output.
Definition: IRSend.hpp:1498
LocalDebugLevelEnd.h
matchBeoLength
static bool matchBeoLength(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros)
Definition: ir_BangOlufsen.hpp:279