62 #ifndef _IR_DISTANCE_WIDTH_HPP
63 #define _IR_DISTANCE_WIDTH_HPP
73 #if !defined(DISTANCE_WIDTH_MAXIMUM_REPEAT_DISTANCE_MICROS)
74 #define DISTANCE_WIDTH_MAXIMUM_REPEAT_DISTANCE_MICROS 100000 // 100 ms, bit it is just a guess
79 #if !defined(DISTANCE_WIDTH_DECODER_DURATION_ARRAY_SIZE)
80 # if (defined(RAMEND) && RAMEND <= 0x8FF) || (defined(RAMSIZE) && RAMSIZE < 0x8FF)
81 #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
83 #define DISTANCE_WIDTH_DECODER_DURATION_ARRAY_SIZE 200 // The decoder accepts mark or space durations up to 200 * 50 (MICROS_PER_TICK) = 10 milliseconds
126 #if defined(LOCAL_DEBUG)
127 void printDurations(uint8_t aArray[], uint8_t aMaxIndex) {
128 for (uint_fast8_t i = 0; i <= aMaxIndex; i++) {
137 Serial.print(F(
": "));
140 Serial.print(aArray[i]);
141 if (aArray[i] != 0) {
145 Serial.print(F(
" | "));
157 uint16_t tWeightedSum = 0;
158 uint8_t tGapCount = 0;
159 for (uint_fast8_t i = 0; i <= aMaxIndex; i++) {
160 uint8_t tCurrentDurations = aArray[i];
161 if (tCurrentDurations != 0) {
163 tSum += tCurrentDurations;
164 tWeightedSum += (tCurrentDurations * i);
170 if (tSum != 0 && (i == aMaxIndex || tGapCount > 1)) {
174 uint8_t tAggregateIndex = (tWeightedSum + (tSum / 2)) / tSum;
175 aArray[tAggregateIndex] = tSum;
177 if (*aShortIndex == 0) {
178 *aShortIndex = tAggregateIndex;
179 }
else if (*aLongIndex == 0) {
180 *aLongIndex = tAggregateIndex;
217 #if defined(DEBUG) || defined(SHOW_DISTANCE_WIDTH_DECODER_ERRORS)
218 Serial.print(F(
"PULSE_DISTANCE_WIDTH: "));
219 Serial.print(F(
"Data length="));
221 Serial.println(F(
" is less than 18"));
229 uint8_t tIndexOfMaxDuration = 0;
234 #if(DISTANCE_WIDTH_DECODER_DURATION_ARRAY_SIZE > 0xFF)
240 tDurationArray[tDurationTicks]++;
241 if (tIndexOfMaxDuration < tDurationTicks) {
242 tIndexOfMaxDuration = tDurationTicks;
245 #if defined(LOCAL_DEBUG) || defined(SHOW_DISTANCE_WIDTH_DECODER_ERRORS)
246 Serial.print(F(
"PULSE_DISTANCE_WIDTH: Mark "));
248 Serial.print(F(
" is longer than maximum "));
250 Serial.print(F(
" us. Index="));
260 uint8_t tMarkTicksShort = 0;
261 uint8_t tMarkTicksLong = 0;
262 bool tSuccess =
aggregateArrayCounts(tDurationArray, tIndexOfMaxDuration, &tMarkTicksShort, &tMarkTicksLong);
263 #if defined(LOCAL_DEBUG)
264 Serial.println(F(
"Mark:"));
265 printDurations(tDurationArray, tIndexOfMaxDuration);
269 #if defined(LOCAL_DEBUG) || defined(SHOW_DISTANCE_WIDTH_DECODER_ERRORS)
270 Serial.println(F(
"PULSE_DISTANCE_WIDTH: Mark aggregation failed, more than 2 distinct mark duration values found"));
281 tIndexOfMaxDuration = 0;
285 tDurationArray[tDurationTicks]++;
286 if (tIndexOfMaxDuration < tDurationTicks) {
287 tIndexOfMaxDuration = tDurationTicks;
290 #if defined(LOCAL_DEBUG) || defined(SHOW_DISTANCE_WIDTH_DECODER_ERRORS)
291 Serial.print(F(
"PULSE_DISTANCE_WIDTH: Space "));
293 Serial.print(F(
" is longer than maximum "));
295 Serial.print(F(
" us. Index="));
305 uint8_t tSpaceTicksShort = 0;
306 uint8_t tSpaceTicksLong = 0;
307 tSuccess =
aggregateArrayCounts(tDurationArray, tIndexOfMaxDuration, &tSpaceTicksShort, &tSpaceTicksLong);
308 #if defined(LOCAL_DEBUG)
309 Serial.println(F(
"Space:"));
310 printDurations(tDurationArray, tIndexOfMaxDuration);
314 #if defined(LOCAL_DEBUG) || defined(SHOW_DISTANCE_WIDTH_DECODER_ERRORS)
315 Serial.println(F(
"PULSE_DISTANCE_WIDTH: Space aggregation failed, more than 2 distinct space duration values found"));
320 #if RAW_BUFFER_LENGTH <= (512 -4)
321 uint_fast8_t tNumberOfBits;
323 uint16_t tNumberOfBits;
326 if (tSpaceTicksLong > 0) {
345 #if defined(LOCAL_DEBUG)
346 Serial.print(F(
"DistanceWidthTimingInfoStruct: "));
347 Serial.print(tNumberOfBits);
348 Serial.print(F(
", "));
350 Serial.print(F(
", "));
352 Serial.print(F(
", "));
353 if(tMarkTicksLong == 0) {
358 Serial.print(F(
", "));
359 if(tSpaceTicksLong == 0) {
364 Serial.print(F(
", "));
366 Serial.print(F(
", "));
379 if (tMarkTicksLong == 0 && tSpaceTicksLong == 0) {
381 F(
"PULSE_DISTANCE: Cannot decode, because there is only one distinct duration value for each space and mark"));
384 unsigned int tSpaceMicrosShort;
385 #if defined(LOCAL_DEBUG)
386 if(tMarkTicksLong > 0 && tSpaceTicksLong > 0) {
387 Serial.println(F(
"PULSE_DISTANCE_WIDTH signal found"));
396 for (uint_fast8_t i = 0; i <= tNumberOfAdditionalArrayValues; ++i) {
397 uint8_t tNumberOfBitsForOneDecode = tNumberOfBits;
404 if (tSpaceTicksLong > 0) {
410 #if defined(USE_THRESHOLD_DECODER)
417 #
if defined(USE_MSB_DECODING_FOR_DISTANCE_DECODER)
431 #if defined(USE_THRESHOLD_DECODER)
438 #
if defined(USE_MSB_DECODING_FOR_DISTANCE_DECODER)
447 #if defined(LOCAL_DEBUG)
448 # if (__INT_WIDTH__ < 32)
461 #if defined(USE_MSB_DECODING_FOR_DISTANCE_DECODER)
467 &&
decodedIRData.decodedRawDataArray[tNumberOfAdditionalArrayValues] == lastDecodedRawData) {
477 decodedIRData.DistanceWidthTimingInfo.ZeroMarkMicros = tMarkMicrosShort;
478 decodedIRData.DistanceWidthTimingInfo.ZeroSpaceMicros = tSpaceMicrosShort;
479 if (tMarkMicrosLong != 0) {
480 if (tSpaceMicrosLong == 0) {
482 decodedIRData.DistanceWidthTimingInfo.OneMarkMicros = tMarkMicrosLong;
483 decodedIRData.DistanceWidthTimingInfo.OneSpaceMicros = tSpaceMicrosShort;
487 decodedIRData.DistanceWidthTimingInfo.OneSpaceMicros = tSpaceMicrosLong;
488 decodedIRData.DistanceWidthTimingInfo.OneMarkMicros = tMarkMicrosShort;
489 decodedIRData.DistanceWidthTimingInfo.ZeroMarkMicros = tMarkMicrosLong;
498 decodedIRData.DistanceWidthTimingInfo.OneMarkMicros = tMarkMicrosShort;
499 decodedIRData.DistanceWidthTimingInfo.OneSpaceMicros = tSpaceMicrosLong;
502 #if defined(LOCAL_DEBUG)
503 Serial.print(F(
"DistanceWidthTimingInfo="));
513 #endif // _IR_DISTANCE_WIDTH_HPP