Skip to content

Commit

Permalink
Rework matchData() to handle equal total data bit time protocols. (#408)
Browse files Browse the repository at this point in the history
* Give up on specific cpu-time optimised for matching data to save on overall
  code space/usage.
* Improves readablity & simplicty of the function.
* Now supports two more protocol types. More generic now.
  e.g. equal total data bit time, and arbitary mark/space timing for bit values.
* Unit tests to cover those cases & supported protocol types.

Ref #406
  • Loading branch information
crankyoldgit authored Feb 2, 2018
1 parent 8172712 commit 6f13468
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 31 deletions.
46 changes: 15 additions & 31 deletions src/IRrecv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -671,39 +671,23 @@ match_result_t IRrecv::matchData(volatile uint16_t *data_ptr,
const uint32_t zerospace,
const uint8_t tolerance) {
match_result_t result;
result.success = false;
result.success = false; // Fail by default.
result.data = 0;
if (onemark == zeromark) { // Is this space encoded data format?
for (result.used = 0;
result.used < nbits * 2;
result.used += 2, data_ptr++) {
if (!matchMark(*data_ptr, onemark, tolerance))
return result; // Fail
data_ptr++;
if (matchSpace(*data_ptr, onespace, tolerance))
result.data = (result.data << 1) | 1;
else if (matchSpace(*data_ptr, zerospace, tolerance))
result.data <<= 1;
else
return result; // Fail
}
result.success = true;
} else if (onespace == zerospace) { // Is this mark encoded data format?
for (result.used = 0;
result.used < nbits * 2;
result.used += 2, data_ptr++) {
if (matchMark(*data_ptr, onemark, tolerance))
result.data = (result.data << 1) | 1;
else if (matchMark(*data_ptr, zeromark, tolerance))
result.data <<= 1;
else
return result; // Fail
data_ptr++;
if (!matchSpace(*data_ptr, onespace, tolerance))
return result; // Fail
}
result.success = true;
for (result.used = 0;
result.used < nbits * 2;
result.used += 2, data_ptr += 2) {
// Is the bit a '1'?
if (matchMark(*data_ptr, onemark, tolerance) &&
matchSpace(*(data_ptr + 1), onespace, tolerance))
result.data = (result.data << 1) | 1;
// or is the bit a '0'?
else if (matchMark(*data_ptr, zeromark, tolerance) &&
matchSpace(*(data_ptr + 1), zerospace, tolerance))
result.data <<= 1;
else
return result; // It's neither, so fail.
}
result.success = true;
return result;
}

Expand Down
125 changes: 125 additions & 0 deletions test/IRrecv_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,3 +447,128 @@ TEST(TestDecode, DecodeAiwa) {
EXPECT_EQ(AIWA_RC_T501_BITS, irsend.capture.bits);
EXPECT_EQ(0x7F, irsend.capture.value);
}

// Test matchData() on space encoded data.
TEST(TestMatchData, SpaceEncoded) {
IRsendTest irsend(0);
IRrecv irrecv(1);
irsend.begin();

uint16_t space_encoded_raw[11] = {
500, 500,
500, 1500,
499, 499,
501, 1501,
499, 1490,
500
};
match_result_t result;

irsend.reset();
irsend.sendRaw(space_encoded_raw, 11, 38000);
irsend.makeDecodeResult();
result = irrecv.matchData(irsend.capture.rawbuf + 1, 5, 500, 1500, 500, 500);
ASSERT_TRUE(result.success);
EXPECT_EQ(0b01011, result.data);
EXPECT_EQ(10, result.used);

irsend.reset();
irsend.sendRaw(space_encoded_raw, 11, 38000);
irsend.makeDecodeResult();
result = irrecv.matchData(irsend.capture.rawbuf + 1, 5, 500, 1000, 500, 500);
ASSERT_FALSE(result.success);
}

// Test matchData() on mark encoded data.
TEST(TestMatchData, MarkEncoded) {
IRsendTest irsend(0);
IRrecv irrecv(1);
irsend.begin();

uint16_t mark_encoded_raw[11] = {
500, 500,
1500, 500,
499, 499,
1501, 501,
1499, 490,
500
};
match_result_t result;

irsend.reset();
irsend.sendRaw(mark_encoded_raw, 11, 38000);
irsend.makeDecodeResult();
result = irrecv.matchData(irsend.capture.rawbuf + 1, 5, 1500, 500, 500, 500);
ASSERT_TRUE(result.success);
EXPECT_EQ(0b01011, result.data);
EXPECT_EQ(10, result.used);

irsend.reset();
irsend.sendRaw(mark_encoded_raw, 11, 38000);
irsend.makeDecodeResult();
result = irrecv.matchData(irsend.capture.rawbuf + 1, 5, 1000, 500, 500, 500);
ASSERT_FALSE(result.success);
}

// Test matchData() on "equal total bit time" encoded data.
TEST(TestMatchData, EqualTotalBitTimeEncoded) {
IRsendTest irsend(0);
IRrecv irrecv(1);
irsend.begin();

uint16_t equal_encoded_raw[11] = {
500, 1500,
1500, 500,
499, 1499,
1501, 501,
1499, 490,
500
};
match_result_t result;

irsend.reset();
irsend.sendRaw(equal_encoded_raw, 11, 38000);
irsend.makeDecodeResult();
result = irrecv.matchData(irsend.capture.rawbuf + 1, 5, 1500, 500, 500, 1500);
ASSERT_TRUE(result.success);
EXPECT_EQ(0b01011, result.data);
EXPECT_EQ(10, result.used);

irsend.reset();
irsend.sendRaw(equal_encoded_raw, 11, 38000);
irsend.makeDecodeResult();
result = irrecv.matchData(irsend.capture.rawbuf + 1, 5, 1000, 500, 500, 1000);
ASSERT_FALSE(result.success);
}

// Test matchData() on arbitrary encoded data.
TEST(TestMatchData, ArbitraryEncoded) {
IRsendTest irsend(0);
IRrecv irrecv(1);
irsend.begin();

uint16_t arbitrary_encoded_raw[11] = {
500, 1500,
3000, 1000,
499, 1499,
3001, 1001,
2999, 990,
500
};
match_result_t result;

irsend.reset();
irsend.sendRaw(arbitrary_encoded_raw, 11, 38000);
irsend.makeDecodeResult();
result = irrecv.matchData(irsend.capture.rawbuf + 1, 5,
3000, 1000, 500, 1500);
ASSERT_TRUE(result.success);
EXPECT_EQ(0b01011, result.data);
EXPECT_EQ(10, result.used);

irsend.reset();
irsend.sendRaw(arbitrary_encoded_raw, 11, 38000);
irsend.makeDecodeResult();
result = irrecv.matchData(irsend.capture.rawbuf + 1, 5, 1000, 500, 500, 1000);
ASSERT_FALSE(result.success);
}

0 comments on commit 6f13468

Please sign in to comment.