@@ -368,11 +368,10 @@ int IRrecv::decode(decode_results *results) {
368368  if  (decodeRC6 (results)) {
369369    return  DECODED;
370370  }
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)) {
376375    return  DECODED;
377376  }
378377  //  Throw away and start over
@@ -599,3 +598,57 @@ long IRrecv::decodeRC6(decode_results *results) {
599598  results->decode_type  = RC6;
600599  return  DECODED;
601600}
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