@@ -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