IRremote
ir_DistanceWidthProtocol.hpp
Go to the documentation of this file.
1 /*
2  * ir_DistanceWidthProtocol.hpp
3  *
4  * Contains only the decoder functions for universal pulse width or pulse distance protocols!
5  * The send functions are used by almost all protocols and are therefore located in IRSend.hpp.
6  *
7  * If RAM is not more than 2k, the decoder only accepts mark or space durations up to 50 * 50 (MICROS_PER_TICK) = 2500 microseconds
8  * to save RAM space, otherwise it accepts durations up to 10 ms.
9  *
10  * This decoder tries to decode a pulse distance or pulse distance width with constant period (or pulse width - not enabled yet) protocol.
11  * 1. Analyze all space and mark length
12  * 2. Decide which protocol we have
13  * 3. Try to decode with the mark and space data found in step 1
14  * 4. Assume one start bit / header and one stop bit, since pulse distance data must have a stop bit!
15  * No data and address decoding, only raw data as result.
16  *
17  * Pulse distance data can be sent with the generic function as in SendDemo example line 155:
18  * https://github.com/Arduino-IRremote/Arduino-IRremote/blob/d51b540cb2ddf1424888d2d9e6b62fe1ef46859d/examples/SendDemo/SendDemo.ino#L155
19  * void sendPulseDistanceWidthData(unsigned int aOneMarkMicros, unsigned int aOneSpaceMicros, unsigned int aZeroMarkMicros,
20  * unsigned int aZeroSpaceMicros, uint32_t aData, uint8_t aNumberOfBits, bool aMSBfirst, bool aSendStopBit = false)
21  * The header must be sent manually with:
22  * IrSender.mark(MarkMicros)
23  * IrSender.space(SpaceMicros);
24  *
25  * Or send it by filling a DecodedRawDataArray and with the sendPulseDistanceWidthFromArray() function as in SendDemo example line 175:
26  * https://github.com/Arduino-IRremote/Arduino-IRremote/blob/d51b540cb2ddf1424888d2d9e6b62fe1ef46859d/examples/SendDemo/SendDemo.ino#L175
27  * sendPulseDistanceWidthFromArray(uint_fast8_t aFrequencyKHz, unsigned int aHeaderMarkMicros,
28  * unsigned int aHeaderSpaceMicros, unsigned int aOneMarkMicros, unsigned int aOneSpaceMicros, unsigned int aZeroMarkMicros,
29  * unsigned int aZeroSpaceMicros, uint32_t *aDecodedRawDataArray, unsigned int aNumberOfBits, uint8_t aFlags,
30  * unsigned int aRepeatPeriodMillis, int_fast8_t aNumberOfRepeats)
31  *
32  * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.
33  *
34  ************************************************************************************
35  * MIT License
36  *
37  * Copyright (c) 2022-2024 Armin Joachimsmeyer
38  *
39  * Permission is hereby granted, free of charge, to any person obtaining a copy
40  * of this software and associated documentation files (the "Software"), to deal
41  * in the Software without restriction, including without limitation the rights
42  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
43  * copies of the Software, and to permit persons to whom the Software is furnished
44  * to do so, subject to the following conditions:
45  *
46  * The above copyright notice and this permission notice shall be included in all
47  * copies or substantial portions of the Software.
48  *
49  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
50  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
51  * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
52  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
53  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
54  * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
55  *
56  ************************************************************************************
57  */
58 #ifndef _IR_DISTANCE_WIDTH_HPP
59 #define _IR_DISTANCE_WIDTH_HPP
60 
61 #if !defined(DISTANCE_WIDTH_MAXIMUM_REPEAT_DISTANCE_MICROS)
62 #define DISTANCE_WIDTH_MAXIMUM_REPEAT_DISTANCE_MICROS 100000 // 100 ms, bit it is just a guess
63 #endif
64 
65 #if defined(DEBUG) && !defined(LOCAL_DEBUG)
66 #define LOCAL_DEBUG
67 #else
68 //#define LOCAL_DEBUG // This enables debug output only for this file
69 #endif
70 
71 #if !defined(DISTANCE_WIDTH_DECODER_DURATION_ARRAY_SIZE)
72 # if (defined(RAMEND) && RAMEND <= 0x8FF) || (defined(RAMSIZE) && RAMSIZE < 0x8FF)
73 #define DISTANCE_WIDTH_DECODER_DURATION_ARRAY_SIZE 50 // To save program space, the decoder only accepts mark or space durations up to 50 * 50 (MICROS_PER_TICK) = 2500 microseconds
74 # else
75 #define DISTANCE_WIDTH_DECODER_DURATION_ARRAY_SIZE 200 // The decoder accepts mark or space durations up to 200 * 50 (MICROS_PER_TICK) = 10 milliseconds
76 # endif
77 #endif
78 
79 // Switch the decoding according to your needs
80 //#define USE_MSB_DECODING_FOR_DISTANCE_DECODER // If active, it resembles LG, otherwise LSB first as most other protocols e.g. NEC and Kaseikyo/Panasonic
81 
85 //=====================================================================================
86 // DDD III SSS TTTTTT AA N N CCC EEEE W W III DDD TTTTTT H H
87 // D D I S TT A A NN N C E W W I D D TT H H
88 // D D I SSS TT AAAA N N N C EEE W W W I D D TT HHHH
89 // D D I S TT A A N NN C E W W W I D D TT H H
90 // DDD III SSSS TT A A N N CCC EEEE W W III DDD TT H H
91 //=====================================================================================
92 // see: https://www.mikrocontroller.net/articles/IRMP_-_english#Codings
93 /*
94  Example output of UnitTest.ino for PulseWidth protocol:
95  Protocol=PulseWidth Raw-Data=0x87654321 32 bits LSB first
96  Send on a 8 bit platform with: IrSender.sendPulseDistanceWidth(38, 950, 550, 600, 300, 300, 300, 0x87654321, 32, PROTOCOL_IS_LSB_FIRST, <RepeatPeriodMillis>, <numberOfRepeats>);
97  rawData[66]:
98  -1088600
99  + 950,- 550
100  + 600,- 300 + 300,- 300 + 350,- 250 + 350,- 250
101  + 350,- 300 + 600,- 300 + 300,- 300 + 300,- 300
102  + 650,- 250 + 650,- 250 + 300,- 300 + 350,- 250
103  + 350,- 300 + 300,- 300 + 600,- 300 + 300,- 300
104  + 600,- 300 + 350,- 250 + 600,- 300 + 350,- 250
105  + 350,- 300 + 600,- 300 + 600,- 300 + 300,- 300
106  + 600,- 300 + 600,- 300 + 600,- 300 + 300,- 300
107  + 300,- 300 + 300,- 300 + 350,- 250 + 650
108  Sum: 24500
109 
110  Example output of UnitTest.ino for PulseDistanceWidth protocol:
111  Protocol=PulseDistance Raw-Data=0x76 7 bits LSB first
112  Send on a 8 bit platform with: IrSender.sendPulseDistanceWidth(38, 5950, 500, 550, 1450, 1550, 500, 0x76, 7, PROTOCOL_IS_LSB_FIRST, <RepeatPeriodMillis>, <numberOfRepeats>);
113  rawData[18]:
114  -1092450
115  +5950,- 500
116  +1500,- 500 + 500,-1450 + 550,-1450 +1550,- 450
117  + 550,-1450 + 550,-1450 + 550,-1450 + 550
118  Sum: 20950
119  */
120 
121 #if defined(LOCAL_DEBUG)
122 void printDurations(uint8_t aArray[], uint8_t aMaxIndex) {
123  for (uint_fast8_t i = 0; i <= aMaxIndex; i++) {
124  //Print index at the beginning of a new line
125  if (i % 10 == 0) {
126  if (i == 0) {
127  Serial.print(' '); // indentation for the first index 0
128  } else {
129  Serial.println(); // new line for next indexes 10, 20 etc.
130  }
131  Serial.print(i);
132  Serial.print(F(": "));
133  }
134  // Print number of values in array and duration if != 0
135  Serial.print(aArray[i]);
136  if (aArray[i] != 0) {
137  Serial.print('x');
138  Serial.print(i * (uint16_t) MICROS_PER_TICK);
139  }
140  Serial.print(F(" | "));
141  }
142  Serial.println();
143 }
144 #endif
145 
146 /*
147  * We count all consecutive (allow only one gap between) durations and compute the average.
148  * @return false if more than 2 distinct duration values found
149  */
150 bool aggregateArrayCounts(uint8_t aArray[], uint8_t aMaxIndex, uint8_t *aShortIndex, uint8_t *aLongIndex) {
151  uint8_t tSum = 0;
152  uint16_t tWeightedSum = 0;
153  uint8_t tGapCount = 0;
154  for (uint_fast8_t i = 0; i <= aMaxIndex; i++) {
155  uint8_t tCurrentDurations = aArray[i];
156  if (tCurrentDurations != 0) {
157  // Add it to sum and remove array content
158  tSum += tCurrentDurations;
159  tWeightedSum += (tCurrentDurations * i);
160  aArray[i] = 0;
161  tGapCount = 0;
162  } else {
163  tGapCount++;
164  }
165  if (tSum != 0 && (i == aMaxIndex || tGapCount > 1)) {
166  /*
167  * Here we have a sum AND last element OR more than 1 consecutive gap
168  */
169  uint8_t tAggregateIndex = (tWeightedSum + (tSum / 2)) / tSum; // with rounding
170  aArray[tAggregateIndex] = tSum; // disabling this line increases code size by 2 - unbelievable!
171  // store aggregate for later decoding
172  if (*aShortIndex == 0) {
173  *aShortIndex = tAggregateIndex;
174  } else if (*aLongIndex == 0) {
175  *aLongIndex = tAggregateIndex;
176  } else {
177  // we have 3 bins => this is likely no pulse width or distance protocol. e.g. it can be RC5.
178  return false;
179  }
180  // initialize for next aggregation
181  tSum = 0;
182  tWeightedSum = 0;
183  }
184  }
185  return true;
186 }
187 
188 /*
189  * Try to decode a pulse distance or pulse width protocol.
190  * 1. Analyze all space and mark length
191  * 2. Decide if we have an pulse width or distance protocol
192  * 3. Try to decode with the mark and space data found in step 1
193  * No data and address decoding, only raw data as result.
194  *
195  * calloc() version is 700 bytes larger :-(
196  */
198  /*
199  * Array for up to 49 ticks / 2500 us (or 199 ticks / 10 ms us if RAM > 2k)
200  * 0 tick covers mark or space durations from 0 to 49 us, and 49 ticks from 2450 to 2499 us
201  */
202  uint8_t tDurationArray[DISTANCE_WIDTH_DECODER_DURATION_ARRAY_SIZE];
203 
204  /*
205  * Accept only protocols with at least 7 bits
206  */
207  if (decodedIRData.rawlen < (2 * 7) + 4) {
208  IR_DEBUG_PRINT(F("PULSE_DISTANCE_WIDTH: "));
209  IR_DEBUG_PRINT(F("Data length="));
211  IR_DEBUG_PRINTLN(F(" is less than 18"));
212  return false;
213  }
214 
215  // Reset duration array
216  memset(tDurationArray, 0, DISTANCE_WIDTH_DECODER_DURATION_ARRAY_SIZE);
217 
218  uint8_t tIndexOfMaxDuration = 0;
219  /*
220  * Count number of mark durations. Skip leading start and trailing stop bit.
221  */
222  for (IRRawlenType i = 3; i < decodedIRData.rawlen - 2; i += 2) {
223  auto tDurationTicks = decodedIRData.rawDataPtr->rawbuf[i];
224  if (tDurationTicks < DISTANCE_WIDTH_DECODER_DURATION_ARRAY_SIZE) {
225  tDurationArray[tDurationTicks]++; // count duration if less than DISTANCE_WIDTH_DECODER_DURATION_ARRAY_SIZE
226  if (tIndexOfMaxDuration < tDurationTicks) {
227  tIndexOfMaxDuration = tDurationTicks;
228  }
229  } else {
230 #if defined(LOCAL_DEBUG)
231  Serial.print(F("PULSE_DISTANCE_WIDTH: "));
232  Serial.print(F("Mark "));
233  Serial.print(tDurationTicks * MICROS_PER_TICK);
234  Serial.print(F(" is longer than maximum "));
236  Serial.print(F(" us. Index="));
237  Serial.println(i);
238 #endif
239  return false;
240  }
241  }
242 
243  /*
244  * Aggregate mark counts to one duration bin
245  */
246  uint8_t tMarkTicksShort = 0;
247  uint8_t tMarkTicksLong = 0;
248  bool tSuccess = aggregateArrayCounts(tDurationArray, tIndexOfMaxDuration, &tMarkTicksShort, &tMarkTicksLong);
249 #if defined(LOCAL_DEBUG)
250  Serial.println(F("Mark:"));
251  printDurations(tDurationArray, tIndexOfMaxDuration);
252 #endif
253 
254  if (!tSuccess) {
255 #if defined(LOCAL_DEBUG)
256  Serial.print(F("PULSE_DISTANCE_WIDTH: "));
257  Serial.println(F("Mark aggregation failed, more than 2 distinct mark duration values found"));
258 #endif
259  return false;
260  }
261 
262  // Reset duration array
263  memset(tDurationArray, 0, DISTANCE_WIDTH_DECODER_DURATION_ARRAY_SIZE);
264 
265  /*
266  * Count number of space durations. Skip leading start and trailing stop bit.
267  */
268  tIndexOfMaxDuration = 0;
269  for (IRRawlenType i = 4; i < decodedIRData.rawlen - 2; i += 2) {
270  auto tDurationTicks = decodedIRData.rawDataPtr->rawbuf[i];
271  if (tDurationTicks < DISTANCE_WIDTH_DECODER_DURATION_ARRAY_SIZE) {
272  tDurationArray[tDurationTicks]++;
273  if (tIndexOfMaxDuration < tDurationTicks) {
274  tIndexOfMaxDuration = tDurationTicks;
275  }
276  } else {
277 #if defined(LOCAL_DEBUG)
278  Serial.print(F("PULSE_DISTANCE_WIDTH: "));
279  Serial.print(F("Space "));
280  Serial.print(tDurationTicks * MICROS_PER_TICK);
281  Serial.print(F(" is longer than maximum "));
283  Serial.print(F(" us. Index="));
284  Serial.println(i);
285 #endif
286  return false;
287  }
288  }
289 
290  /*
291  * Aggregate space counts to one duration bin
292  */
293  uint8_t tSpaceTicksShort = 0;
294  uint8_t tSpaceTicksLong = 0;
295  tSuccess = aggregateArrayCounts(tDurationArray, tIndexOfMaxDuration, &tSpaceTicksShort, &tSpaceTicksLong);
296 #if defined(LOCAL_DEBUG)
297  Serial.println(F("Space:"));
298  printDurations(tDurationArray, tIndexOfMaxDuration);
299 #endif
300 
301  if (!tSuccess) {
302 #if defined(LOCAL_DEBUG)
303  Serial.print(F("PULSE_DISTANCE_WIDTH: "));
304  Serial.println(F("Space aggregation failed, more than 2 distinct space duration values found"));
305 #endif
306  return false;
307  }
308 
309  /*
310  * Print characteristics of this protocol. Durations are in (50 us) ticks.
311  * Number of bits, start bit, start pause, long mark, long space, short mark, short space
312  *
313  * NEC: 32, 180, 90, 0, 34, 11, 11
314  * Samsung32: 32, 90, 90, 0, 34, 11, 11
315  * LG: 28, 180, 84, 0, 32, 10, 11
316  * JVC: 16, 168, 84, 0, 32, 10, 10
317  * Kaseikyo: 48. 69, 35, 0, 26, 9, 9
318  * Sony: 12|15|20, 48, 12, 24, 0, 12, 12 // the only known pulse width protocol
319  * Disney monorail
320  * model: 7, 120, 10, 30, 30, 10, 10 // PulseDistanceWidth. Can be seen as direct conversion of a 7 bit serial timing at 250 baud with a 6 ms start bit.
321  */
322 #if defined(LOCAL_DEBUG)
323  Serial.print(F("DistanceWidthTimingInfoStruct: "));
324  Serial.print(decodedIRData.rawDataPtr->rawbuf[1] * MICROS_PER_TICK);
325  Serial.print(F(", "));
326  Serial.print(decodedIRData.rawDataPtr->rawbuf[2] * MICROS_PER_TICK);
327  Serial.print(F(", "));
328  Serial.print(tMarkTicksLong * MICROS_PER_TICK);
329  Serial.print(F(", "));
330  Serial.print(tSpaceTicksLong * MICROS_PER_TICK);
331  Serial.print(F(", "));
332  Serial.print(tMarkTicksShort * MICROS_PER_TICK);
333  Serial.print(F(", "));
334  Serial.println(tSpaceTicksShort * MICROS_PER_TICK);
335 #endif
336 #if RAW_BUFFER_LENGTH <= (512 -4)
337  uint_fast8_t tNumberOfBits;
338 #else
339  uint16_t tNumberOfBits;
340 #endif
341  tNumberOfBits = (decodedIRData.rawlen / 2) - 1;
342  if (tSpaceTicksLong > 0) {
343  // For PULSE_DISTANCE -including PULSE_DISTANCE_WIDTH- a stop bit is mandatory, for PULSE_WIDTH it is not required!
344  tNumberOfBits--; // Correct for stop bit
345  }
346  decodedIRData.numberOfBits = tNumberOfBits;
347  uint8_t tNumberOfAdditionalArrayValues = (tNumberOfBits - 1) / BITS_IN_RAW_DATA_TYPE;
348 
349  /*
350  * We can have the following protocol timings
351  * PULSE_DISTANCE: Pause/spaces have different length and determine the bit value, longer space is 1. Pulses/marks can be constant, like NEC.
352  * PULSE_WIDTH: Pulses/marks have different length and determine the bit value, longer mark is 1. Pause/spaces can be constant, like Sony.
353  * PULSE_DISTANCE_WIDTH: Pulses/marks and pause/spaces have different length, often the bit length is constant, like MagiQuest. Can be decoded by PULSE_DISTANCE decoder.
354  */
355 
356  if (tMarkTicksLong == 0 && tSpaceTicksLong == 0) {
357 #if defined(LOCAL_DEBUG)
358  Serial.print(F("PULSE_DISTANCE: "));
359  Serial.println(F("Only 1 distinct duration value for each space and mark found"));
360 #endif
361  return false;
362  }
363  unsigned int tSpaceMicrosShort;
364 #if defined DECODE_STRICT_CHECKS
365  if(tMarkTicksLong > 0 && tSpaceTicksLong > 0) {
366  // We have different mark and space length here, so signal decodePulseDistanceWidthData() not to check against constant length decodePulseDistanceWidthData
367  tSpaceMicrosShort = 0;
368  }
369 #endif
370  tSpaceMicrosShort = tSpaceTicksShort * MICROS_PER_TICK;
371  unsigned int tMarkMicrosShort = tMarkTicksShort * MICROS_PER_TICK;
372  unsigned int tMarkMicrosLong = tMarkTicksLong * MICROS_PER_TICK;
373  unsigned int tSpaceMicrosLong = tSpaceTicksLong * MICROS_PER_TICK;
374  IRRawlenType tStartIndex = 3; // skip leading start bit for decoding.
375 
376  for (uint_fast8_t i = 0; i <= tNumberOfAdditionalArrayValues; ++i) {
377  uint8_t tNumberOfBitsForOneDecode = tNumberOfBits;
378  /*
379  * Decode in 32/64 bit chunks. Only the last chunk can contain less than 32/64 bits
380  */
381  if (tNumberOfBitsForOneDecode > BITS_IN_RAW_DATA_TYPE) {
382  tNumberOfBitsForOneDecode = BITS_IN_RAW_DATA_TYPE;
383  }
384  bool tResult;
385  if (tSpaceTicksLong > 0) {
386  /*
387  * Here short and long space durations found.
388  * Since parameters aOneMarkMicros and aOneSpaceMicros are equal, we only check tSpaceMicrosLong here.
389  */
390  decodedIRData.protocol = PULSE_DISTANCE; // Sony + PULSE_DISTANCE_WIDTH
391  tResult = decodePulseDistanceWidthData(tNumberOfBitsForOneDecode, tStartIndex, tMarkMicrosShort, tSpaceMicrosLong,
392  tMarkMicrosShort,
393 #if defined(USE_MSB_DECODING_FOR_DISTANCE_DECODER)
394  true
395 #else
396  false
397 #endif
398  );
399  } else {
400  /*
401  * Here no long space duration found. => short and long mark durations found, check tMarkMicrosLong here
402  * This else case will most likely never be used, but it only requires 12 bytes additional programming space :-)
403  */
404  decodedIRData.protocol = PULSE_WIDTH; // NEC etc.
405  tResult = decodePulseDistanceWidthData(tNumberOfBitsForOneDecode, tStartIndex, tMarkMicrosLong, tSpaceMicrosShort,
406  tMarkMicrosShort,
407 #if defined(USE_MSB_DECODING_FOR_DISTANCE_DECODER)
408  true
409 #else
410  false
411 #endif
412  );
413 
414  }
415  if (!tResult) {
416 #if defined(LOCAL_DEBUG)
417  Serial.print(F("PULSE_WIDTH: "));
418  Serial.println(F("Decode failed"));
419 #endif
420  return false;
421  }
422 #if defined(LOCAL_DEBUG)
423  Serial.print(F("PULSE_WIDTH: "));
424  Serial.print(F("decodedRawData=0x"));
425  Serial.println(decodedIRData.decodedRawData, HEX);
426 #endif
427  // fill array with decoded data
428  decodedIRData.decodedRawDataArray[i] = decodedIRData.decodedRawData;
429  tStartIndex += (2 * BITS_IN_RAW_DATA_TYPE);
430  tNumberOfBits -= BITS_IN_RAW_DATA_TYPE;
431  }
432 
433 #if defined(USE_MSB_DECODING_FOR_DISTANCE_DECODER)
435 #endif
436 
437  // Check for repeat
439 
440  /*
441  * Store timing data to reproduce frame for sending
442  */
443  decodedIRData.DistanceWidthTimingInfo.HeaderMarkMicros = (decodedIRData.rawDataPtr->rawbuf[1] * MICROS_PER_TICK);
444  decodedIRData.DistanceWidthTimingInfo.HeaderSpaceMicros = (decodedIRData.rawDataPtr->rawbuf[2] * MICROS_PER_TICK);
445  decodedIRData.DistanceWidthTimingInfo.ZeroMarkMicros = tMarkMicrosShort;
446  decodedIRData.DistanceWidthTimingInfo.ZeroSpaceMicros = tSpaceMicrosShort;
447  if (tMarkMicrosLong != 0) {
448  if (tSpaceMicrosLong == 0) {
449  // PULSE_DISTANCE, Sony
450  decodedIRData.DistanceWidthTimingInfo.OneMarkMicros = tMarkMicrosLong;
451  decodedIRData.DistanceWidthTimingInfo.OneSpaceMicros = tSpaceMicrosShort;
452  } else {
453  // PULSE_DISTANCE_WIDTH, we have 4 distinct values here
454  // Assume long space for a one when we have PulseDistanceWidth like for RS232, where a long inactive period (high) is a 1
455  decodedIRData.DistanceWidthTimingInfo.OneSpaceMicros = tSpaceMicrosLong;
456  decodedIRData.DistanceWidthTimingInfo.OneMarkMicros = tMarkMicrosShort;
457  decodedIRData.DistanceWidthTimingInfo.ZeroMarkMicros = tMarkMicrosLong;
458 // // Assume long mark for a one when we have PulseDistanceWidth
459 // decodedIRData.DistanceWidthTimingInfo.OneSpaceMicros = tSpaceMicrosShort;
460 // decodedIRData.DistanceWidthTimingInfo.ZeroSpaceMicros = tSpaceMicrosLong;
461 // decodedIRData.DistanceWidthTimingInfo.OneMarkMicros = tMarkMicrosLong;
462  }
463  } else {
464  // PULSE_WIDTH, NEC etc.
465  // Here tMarkMicrosLong is 0 => tSpaceMicrosLong != 0
466  decodedIRData.DistanceWidthTimingInfo.OneMarkMicros = tMarkMicrosShort;
467  decodedIRData.DistanceWidthTimingInfo.OneSpaceMicros = tSpaceMicrosLong;
468  }
469 
470 #if defined(LOCAL_DEBUG)
471  Serial.print(F("DistanceWidthTimingInfo="));
472  IrReceiver.printDistanceWidthTimingInfo(&Serial, &decodedIRData.DistanceWidthTimingInfo);
473  Serial.println();
474 #endif
475  return true;
476 }
477 
479 #if defined(LOCAL_DEBUG)
480 #undef LOCAL_DEBUG
481 #endif
482 #endif // _IR_DISTANCE_WIDTH_HPP
MICROS_PER_TICK
#define MICROS_PER_TICK
microseconds per clock interrupt tick
Definition: IRremote.hpp:250
BITS_IN_RAW_DATA_TYPE
#define BITS_IN_RAW_DATA_TYPE
Definition: IRremoteInt.h:110
IRData::numberOfBits
uint16_t numberOfBits
Number of bits received for data (address + command + parity) - to determine protocol length if diffe...
Definition: IRProtocol.h:119
IRRawlenType
unsigned int IRRawlenType
Definition: IRremoteInt.h:91
aggregateArrayCounts
bool aggregateArrayCounts(uint8_t aArray[], uint8_t aMaxIndex, uint8_t *aShortIndex, uint8_t *aLongIndex)
Definition: ir_DistanceWidthProtocol.hpp:150
IRrecv::decodeDistanceWidth
bool decodeDistanceWidth()
Definition: ir_DistanceWidthProtocol.hpp:197
DISTANCE_WIDTH_DECODER_DURATION_ARRAY_SIZE
#define DISTANCE_WIDTH_DECODER_DURATION_ARRAY_SIZE
Definition: ir_DistanceWidthProtocol.hpp:75
PULSE_WIDTH
@ PULSE_WIDTH
Definition: IRProtocol.h:42
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:131
IRData::decodedRawData
IRRawDataType decodedRawData
Up to 32/64 bit decoded raw data, to be used for send functions.
Definition: IRProtocol.h:113
PULSE_DISTANCE
@ PULSE_DISTANCE
Definition: IRProtocol.h:43
IRrecv::checkForRepeatSpaceTicksAndSetFlag
void checkForRepeatSpaceTicksAndSetFlag(uint16_t aMaximumRepeatSpaceTicks)
Definition: IRReceive.hpp:1150
IR_DEBUG_PRINT
#define IR_DEBUG_PRINT(...)
If DEBUG, print the arguments, otherwise do nothing.
Definition: IRremoteInt.h:161
IRrecv::decodedIRData
IRData decodedIRData
Definition: IRremoteInt.h:358
IRData::flags
uint8_t flags
IRDATA_FLAGS_IS_REPEAT, IRDATA_FLAGS_WAS_OVERFLOW etc. See IRDATA_FLAGS_* definitions above.
Definition: IRProtocol.h:120
IRrecv::decodePulseDistanceWidthData
bool decodePulseDistanceWidthData(PulseDistanceWidthProtocolConstants *aProtocolConstants, uint_fast8_t aNumberOfBits, IRRawlenType aStartOffset=3)
Decode pulse distance protocols for PulseDistanceWidthProtocolConstants.
Definition: IRReceive.hpp:954
IRrecv::printDistanceWidthTimingInfo
void printDistanceWidthTimingInfo(Print *aSerial, DistanceWidthTimingInfoStruct *aDistanceWidthTimingInfo)
Definition: IRReceive.hpp:1379
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:144
IRDATA_FLAGS_IS_MSB_FIRST
#define IRDATA_FLAGS_IS_MSB_FIRST
Value is mainly determined by the (known) protocol.
Definition: IRProtocol.h:100
IRData::rawlen
IRRawlenType rawlen
counter of entries in rawbuf of last received frame.
Definition: IRProtocol.h:128
IR_DEBUG_PRINTLN
#define IR_DEBUG_PRINTLN(...)
If DEBUG, print the arguments as a line, otherwise do nothing.
Definition: IRremoteInt.h:165
DISTANCE_WIDTH_MAXIMUM_REPEAT_DISTANCE_MICROS
#define DISTANCE_WIDTH_MAXIMUM_REPEAT_DISTANCE_MICROS
Definition: ir_DistanceWidthProtocol.hpp:62
IRData::protocol
decode_type_t protocol
UNKNOWN, NEC, SONY, RC5, PULSE_DISTANCE, ...
Definition: IRProtocol.h:109
IrReceiver
IRrecv IrReceiver
The receiver instance.
Definition: IRReceive.hpp:59