mirror of
https://github.com/Theaninova/Arduino-IRremote.git
synced 2026-01-20 08:12:53 +00:00
Add "hash encoding" to generate a value for unknown encodings.
For an unknown encoding, an arbitrary 32-bit value will be generated.
This commit is contained in:
63
IRremote.cpp
63
IRremote.cpp
@@ -368,11 +368,10 @@ int IRrecv::decode(decode_results *results) {
|
|||||||
if (decodeRC6(results)) {
|
if (decodeRC6(results)) {
|
||||||
return DECODED;
|
return DECODED;
|
||||||
}
|
}
|
||||||
if (results->rawlen >= 6) {
|
// decodeHash returns a hash on any input.
|
||||||
// Only return raw buffer if at least 6 bits
|
// Thus, it needs to be last in the list.
|
||||||
results->decode_type = UNKNOWN;
|
// If you add any decodes, add them before this.
|
||||||
results->bits = 0;
|
if (decodeHash(results)) {
|
||||||
results->value = 0;
|
|
||||||
return DECODED;
|
return DECODED;
|
||||||
}
|
}
|
||||||
// Throw away and start over
|
// Throw away and start over
|
||||||
@@ -599,3 +598,57 @@ long IRrecv::decodeRC6(decode_results *results) {
|
|||||||
results->decode_type = RC6;
|
results->decode_type = RC6;
|
||||||
return DECODED;
|
return DECODED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------
|
||||||
|
* hashdecode - decode an arbitrary IR code.
|
||||||
|
* Instead of decoding using a standard encoding scheme
|
||||||
|
* (e.g. Sony, NEC, RC5), the code is hashed to a 32-bit value.
|
||||||
|
*
|
||||||
|
* The algorithm: look at the sequence of MARK signals, and see if each one
|
||||||
|
* is shorter (0), the same length (1), or longer (2) than the previous.
|
||||||
|
* Do the same with the SPACE signals. Hszh the resulting sequence of 0's,
|
||||||
|
* 1's, and 2's to a 32-bit value. This will give a unique value for each
|
||||||
|
* different code (probably), for most code systems.
|
||||||
|
*
|
||||||
|
* http://arcfn.com/2010/01/using-arbitrary-remotes-with-arduino.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Compare two tick values, returning 0 if newval is shorter,
|
||||||
|
// 1 if newval is equal, and 2 if newval is longer
|
||||||
|
// Use a tolerance of 20%
|
||||||
|
int IRrecv::compare(unsigned int oldval, unsigned int newval) {
|
||||||
|
if (newval < oldval * .8) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (oldval < newval * .8) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use FNV hash algorithm: http://isthe.com/chongo/tech/comp/fnv/#FNV-param
|
||||||
|
#define FNV_PRIME_32 16777619
|
||||||
|
#define FNV_BASIS_32 2166136261
|
||||||
|
|
||||||
|
/* Converts the raw code values into a 32-bit hash code.
|
||||||
|
* Hopefully this code is unique for each button.
|
||||||
|
* This isn't a "real" decoding, just an arbitrary value.
|
||||||
|
*/
|
||||||
|
long IRrecv::decodeHash(decode_results *results) {
|
||||||
|
// Require at least 6 samples to prevent triggering on noise
|
||||||
|
if (results->rawlen < 6) {
|
||||||
|
return ERR;
|
||||||
|
}
|
||||||
|
long hash = FNV_BASIS_32;
|
||||||
|
for (int i = 1; i+2 < results->rawlen; i++) {
|
||||||
|
int value = compare(results->rawbuf[i], results->rawbuf[i+2]);
|
||||||
|
// Add value into the hash
|
||||||
|
hash = (hash * FNV_PRIME_32) ^ value;
|
||||||
|
}
|
||||||
|
results->value = hash;
|
||||||
|
results->bits = 32;
|
||||||
|
results->decode_type = UNKNOWN;
|
||||||
|
return DECODED;
|
||||||
|
}
|
||||||
|
|||||||
@@ -56,6 +56,9 @@ private:
|
|||||||
long decodeSony(decode_results *results);
|
long decodeSony(decode_results *results);
|
||||||
long decodeRC5(decode_results *results);
|
long decodeRC5(decode_results *results);
|
||||||
long decodeRC6(decode_results *results);
|
long decodeRC6(decode_results *results);
|
||||||
|
long decodeHash(decode_results *results);
|
||||||
|
int compare(unsigned int oldval, unsigned int newval);
|
||||||
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
@@ -28,26 +28,24 @@ void setup()
|
|||||||
void dump(decode_results *results) {
|
void dump(decode_results *results) {
|
||||||
int count = results->rawlen;
|
int count = results->rawlen;
|
||||||
if (results->decode_type == UNKNOWN) {
|
if (results->decode_type == UNKNOWN) {
|
||||||
Serial.println("Could not decode message");
|
Serial.print("Unknown encoding: ");
|
||||||
}
|
}
|
||||||
else {
|
else if (results->decode_type == NEC) {
|
||||||
if (results->decode_type == NEC) {
|
Serial.print("Decoded NEC: ");
|
||||||
Serial.print("Decoded NEC: ");
|
|
||||||
}
|
|
||||||
else if (results->decode_type == SONY) {
|
|
||||||
Serial.print("Decoded SONY: ");
|
|
||||||
}
|
|
||||||
else if (results->decode_type == RC5) {
|
|
||||||
Serial.print("Decoded RC5: ");
|
|
||||||
}
|
|
||||||
else if (results->decode_type == RC6) {
|
|
||||||
Serial.print("Decoded RC6: ");
|
|
||||||
}
|
|
||||||
Serial.print(results->value, HEX);
|
|
||||||
Serial.print(" (");
|
|
||||||
Serial.print(results->bits, DEC);
|
|
||||||
Serial.println(" bits)");
|
|
||||||
}
|
}
|
||||||
|
else if (results->decode_type == SONY) {
|
||||||
|
Serial.print("Decoded SONY: ");
|
||||||
|
}
|
||||||
|
else if (results->decode_type == RC5) {
|
||||||
|
Serial.print("Decoded RC5: ");
|
||||||
|
}
|
||||||
|
else if (results->decode_type == RC6) {
|
||||||
|
Serial.print("Decoded RC6: ");
|
||||||
|
}
|
||||||
|
Serial.print(results->value, HEX);
|
||||||
|
Serial.print(" (");
|
||||||
|
Serial.print(results->bits, DEC);
|
||||||
|
Serial.println(" bits)");
|
||||||
Serial.print("Raw (");
|
Serial.print("Raw (");
|
||||||
Serial.print(count, DEC);
|
Serial.print(count, DEC);
|
||||||
Serial.print("): ");
|
Serial.print("): ");
|
||||||
|
|||||||
Reference in New Issue
Block a user