@@ -368,11 +368,10 @@ int IRrecv::decode(decode_results *results) {
368
368
if (decodeRC6 (results)) {
369
369
return DECODED;
370
370
}
371
- if (results->rawlen >= 6 ) {
372
- // Only return raw buffer if at least 6 bits
373
- results->decode_type = UNKNOWN;
374
- results->bits = 0 ;
375
- results->value = 0 ;
371
+ // decodeHash returns a hash on any input.
372
+ // Thus, it needs to be last in the list.
373
+ // If you add any decodes, add them before this.
374
+ if (decodeHash (results)) {
376
375
return DECODED;
377
376
}
378
377
// Throw away and start over
@@ -599,3 +598,57 @@ long IRrecv::decodeRC6(decode_results *results) {
599
598
results->decode_type = RC6;
600
599
return DECODED;
601
600
}
601
+
602
+ /* -----------------------------------------------------------------------
603
+ * hashdecode - decode an arbitrary IR code.
604
+ * Instead of decoding using a standard encoding scheme
605
+ * (e.g. Sony, NEC, RC5), the code is hashed to a 32-bit value.
606
+ *
607
+ * The algorithm: look at the sequence of MARK signals, and see if each one
608
+ * is shorter (0), the same length (1), or longer (2) than the previous.
609
+ * Do the same with the SPACE signals. Hszh the resulting sequence of 0's,
610
+ * 1's, and 2's to a 32-bit value. This will give a unique value for each
611
+ * different code (probably), for most code systems.
612
+ *
613
+ * http://arcfn.com/2010/01/using-arbitrary-remotes-with-arduino.html
614
+ */
615
+
616
+ // Compare two tick values, returning 0 if newval is shorter,
617
+ // 1 if newval is equal, and 2 if newval is longer
618
+ // Use a tolerance of 20%
619
+ int IRrecv::compare (unsigned int oldval, unsigned int newval) {
620
+ if (newval < oldval * .8 ) {
621
+ return 0 ;
622
+ }
623
+ else if (oldval < newval * .8 ) {
624
+ return 2 ;
625
+ }
626
+ else {
627
+ return 1 ;
628
+ }
629
+ }
630
+
631
+ // Use FNV hash algorithm: http://isthe.com/chongo/tech/comp/fnv/#FNV-param
632
+ #define FNV_PRIME_32 16777619
633
+ #define FNV_BASIS_32 2166136261
634
+
635
+ /* Converts the raw code values into a 32-bit hash code.
636
+ * Hopefully this code is unique for each button.
637
+ * This isn't a "real" decoding, just an arbitrary value.
638
+ */
639
+ long IRrecv::decodeHash (decode_results *results) {
640
+ // Require at least 6 samples to prevent triggering on noise
641
+ if (results->rawlen < 6 ) {
642
+ return ERR;
643
+ }
644
+ long hash = FNV_BASIS_32;
645
+ for (int i = 1 ; i+2 < results->rawlen ; i++) {
646
+ int value = compare (results->rawbuf [i], results->rawbuf [i+2 ]);
647
+ // Add value into the hash
648
+ hash = (hash * FNV_PRIME_32) ^ value;
649
+ }
650
+ results->value = hash;
651
+ results->bits = 32 ;
652
+ results->decode_type = UNKNOWN;
653
+ return DECODED;
654
+ }
0 commit comments