8000 Add "hash encoding" to generate a value for unknown encodings. · RemoteControl/Arduino-IRremote@e12e9ea · GitHub
[go: up one dir, main page]

Skip to content

Commit e12e9ea

Browse files
committed
Add "hash encoding" to generate a value for unknown encodings.
For an unknown encoding, an arbitrary 32-bit value will be generated.
1 parent c6ec2fd commit e12e9ea

File tree

3 files changed

+77
-23
lines changed

3 files changed

+77
-23
lines changed

IRremote.cpp

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
}

IRremote.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ class IRrecv
5656
long decodeSony(decode_results *results);
5757
long decodeRC5(decode_results *results);
5858
long decodeRC6(decode_results *results);
59+
long decodeHash(decode_results *results);
60+
int compare(unsigned int oldval, unsigned int newval);
61+
5962
}
6063
;
6164

examples/IRrecvDump/IRrecvDump.pde

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,26 +28,24 @@ void setup()
2828
void dump(decode_results *results) {
2929
int count = results->rawlen;
3030
if (results->decode_type == UNKNOWN) {
31-
Serial.println("Could not decode message");
31+
Serial.print("Unknown encoding: ");
3232
}
33-
else {
34-
if (results->decode_type == NEC) {
35-
Serial.print("Decoded NEC: ");
36-
}
37-
else if (results->decode_type == SONY) {
38-
Serial.print("Decoded SONY: ");
39-
}
40-
else if (results->decode_type == RC5) {
41-
Serial.print("Decoded RC5: ");
42-
}
43-
else if (results->decode_type == RC6) {
44-
Serial.print("Decoded RC6: ");
45-
}
46-
Serial.print(results->value, HEX);
47-
Serial.print(" (");
48-
Serial.print(results->bits, DEC);
49-
Serial.println(" bits)");
33+
else if (results->decode_type == NEC) {
34+
Serial.print("Decoded NEC: ");
35+
}
36+
else if (results->decode_type == SONY) {
37+
Serial.print("Decoded SONY: ");
38+
}
39+
else if (results->decode_type == RC5) {
40+
Serial.print("Decoded RC5: ");
41+
}
42+
else if (results->decode_type == RC6) {
43+
Serial.print("Decoded RC6: ");
5044
}
45+
Serial.print(results->value, HEX);
46+
Serial.print(" (");
47+
Serial.print(results->bits, DEC);
48+
Serial.println(" bits)");
5149
Serial.print("Raw (");
5250
Serial.print(count, DEC);
5351
Serial.print("): ");

0 commit comments

Comments
 (0)
0