Skip to content

Commit 31808d8

Browse files
committed
Argo WREM2 - changed proto msg size: 96->90 bits
Includes `matchBytes()` change to be able to work with non-byte-aligned bit lengths. Signed-off-by: Mateusz Bronk <[email protected]>
1 parent 850a45f commit 31808d8

File tree

5 files changed

+77
-18
lines changed

5 files changed

+77
-18
lines changed

src/IRac.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -4563,7 +4563,8 @@ namespace IRAcUtils {
45634563
#endif // DECODE_AMCOR
45644564
#if DECODE_ARGO
45654565
case decode_type_t::ARGO: {
4566-
const uint16_t length = decode->bits / 8;
4566+
const uint16_t length = static_cast<uint16_t>(
4567+
ceil(static_cast<float>(decode->bits) / 8.0));
45674568
if (IRArgoAC_WREM3::isValidWrem3Message(decode->state,
45684569
decode->bits, true)) {
45694570
IRArgoAC_WREM3 ac(kGpioUnused);

src/IRrecv.cpp

+22-13
Original file line numberDiff line numberDiff line change
@@ -1583,8 +1583,6 @@ uint16_t IRrecv::_matchGeneric(volatile uint16_t *data_ptr,
15831583
const uint8_t tolerance,
15841584
const int16_t excess,
15851585
const bool MSBfirst) {
1586-
// If we are expecting byte sizes, check it's a factor of 8 or fail.
1587-
if (!use_bits && nbits % 8 != 0) return 0;
15881586
// Calculate if we expect a trailing space in the data section.
15891587
const bool kexpectspace = footermark || (onespace != zerospace);
15901588
// Calculate how much remaining buffer is required.
@@ -1607,23 +1605,34 @@ uint16_t IRrecv::_matchGeneric(volatile uint16_t *data_ptr,
16071605
return 0;
16081606

16091607
// Data
1610-
if (use_bits) { // Bits.
1611-
match_result_t result = IRrecv::matchData(data_ptr + offset, nbits,
1608+
if (!use_bits) { // Bytes.
1609+
uint16_t data_used = IRrecv::matchBytes(data_ptr + offset, result_bytes_ptr,
1610+
remaining - offset, nbits / 8,
1611+
onemark, onespace,
1612+
zeromark, zerospace, tolerance,
1613+
excess, MSBfirst, kexpectspace);
1614+
if (!data_used) return 0;
1615+
offset += data_used;
1616+
}
1617+
1618+
// Only using bits,
1619+
// -or- using *bytes*, but number of bits was not a multiple of 8
1620+
if (use_bits || nbits % 8 != 0) {
1621+
uint16_t target_bit_cnt = (use_bits)? nbits : nbits % 8;
1622+
match_result_t result = IRrecv::matchData(data_ptr + offset, target_bit_cnt,
16121623
onemark, onespace,
16131624
zeromark, zerospace, tolerance,
16141625
excess, MSBfirst, kexpectspace);
16151626
if (!result.success) return 0;
1616-
*result_bits_ptr = result.data;
1627+
if (use_bits) {
1628+
*result_bits_ptr = result.data;
1629+
} else {
1630+
// Fill in last (non-full) byte
1631+
result_bytes_ptr[nbits / 8] = static_cast<uint8_t>(result.data);
1632+
}
16171633
offset += result.used;
1618-
} else { // bytes
1619-
uint16_t data_used = IRrecv::matchBytes(data_ptr + offset, result_bytes_ptr,
1620-
remaining - offset, nbits / 8,
1621-
onemark, onespace,
1622-
zeromark, zerospace, tolerance,
1623-
excess, MSBfirst, kexpectspace);
1624-
if (!data_used) return 0;
1625-
offset += data_used;
16261634
}
1635+
16271636
// Footer
16281637
if (footermark && !matchMark(*(data_ptr + offset++), footermark, tolerance,
16291638
excess))

src/IRremoteESP8266.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -1165,7 +1165,8 @@ const uint16_t kAmcorBits = kAmcorStateLength * 8;
11651165
const uint16_t kAmcorDefaultRepeat = kSingleRepeat;
11661166
const uint16_t kArgoStateLength = 12;
11671167
const uint16_t kArgoShortStateLength = 4;
1168-
const uint16_t kArgoBits = kArgoStateLength * 8;
1168+
const uint16_t kArgoBits = 90; // The protocol bit length
1169+
// is NOT full byte aligned
11691170
const uint16_t kArgoShortBits = kArgoShortStateLength * 8;
11701171
const uint16_t kArgo3AcControlStateLength = 6; // Bytes
11711172
const uint16_t kArgo3iFeelReportStateLength = 2; // Bytes

test/IRrecv_test.cpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -1289,7 +1289,7 @@ TEST(TestMatchGeneric, UsingBytes) {
12891289
EXPECT_GT(irsend.capture.rawlen - kStartOffset, entries_used);
12901290
EXPECT_EQ(16, entries_used);
12911291

1292-
// Asking for non mod-8 size should fail.
1292+
// Asking for non mod-8 size should SUCCEED and fill-in next byte.
12931293
entries_used = irrecv.matchGeneric(
12941294
irsend.capture.rawbuf + offset, result_data,
12951295
irsend.capture.rawlen - offset,
@@ -1302,7 +1302,11 @@ TEST(TestMatchGeneric, UsingBytes) {
13021302
1, // 1% Tolerance
13031303
0, // No excess margin
13041304
true); // MSB first.
1305-
ASSERT_EQ(0, entries_used);
1305+
ASSERT_NE(0, entries_used);
1306+
EXPECT_EQ(0b10101010, result_data[0]);
1307+
EXPECT_EQ(0b1, result_data[1]);
1308+
EXPECT_GT(irsend.capture.rawlen - kStartOffset, entries_used);
1309+
EXPECT_EQ(18, entries_used);
13061310

13071311
// Expecting different timings should fail.
13081312
entries_used = irrecv.matchGeneric(

test/ir_Argo_test.cpp

+45-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ TEST(TestArgoACClass, MessageConstructon) {
104104
auto expected = std::vector<uint8_t>({
105105
0xAC, 0xF5, 0x00, 0x24, 0x02, 0x00, 0x00, 0x00, 0x00, 0xAC, 0xD6, 0x01});
106106
auto actual = ac.getRaw();
107-
EXPECT_THAT(std::vector<uint8_t>(actual, actual + kArgoBits / 8),
107+
EXPECT_THAT(std::vector<uint8_t>(actual, actual + static_cast<uint8_t>(ceil(static_cast<float>(kArgoBits) / 8.0))),
108108
::testing::ElementsAreArray(expected));
109109
EXPECT_EQ(
110110
"Model: 1 (WREM2), Power: On, Mode: 0 (Cool), Fan: 0 (Auto), Temp: 20C, "
@@ -1461,6 +1461,50 @@ TEST(TestDecodeArgo, RealShortDecode) {
14611461
EXPECT_EQ(28, r.sensorTemperature);
14621462
}
14631463

1464+
TEST(TestDecodeArgo, Issue2133_90bit_message) {
1465+
IRsendTest irsend(kGpioUnused);
1466+
IRrecv irrecv(kGpioUnused);
1467+
irsend.begin();
1468+
1469+
// Full Argo command message (90 bits)
1470+
const uint16_t command_90bit[193] = {
1471+
6422, 3190, 408, 872, 428, 848, 428, 2126, 402, 2150, 408, 872, 404, 2152, 402, 874, 402,
1472+
2152, 402, 2154, 406, 872, 428, 2126, 404, 876, 404, 2150, 430, 2124, 432, 2122, 432, 2124,
1473+
404, 874, 404, 874, 426, 852, 428, 850, 412, 864, 406, 872, 404, 874, 400, 2154, 428, 2128,
1474+
402, 876, 402, 874, 400, 2154, 404, 2150, 406, 2150, 400, 878, 400, 876, 402, 874, 416, 2136,
1475+
404, 2152, 402, 876, 402, 874, 402, 874, 428, 852, 402, 874, 404, 872, 400, 876, 402, 876,
1476+
404, 872, 430, 846, 402, 2152, 406, 2150, 406, 2150, 404, 874, 432, 846, 426, 850, 428, 850,
1477+
400, 878, 398, 876, 404, 874, 404, 874, 400, 2152, 432, 2124, 428, 2128, 432, 846, 426, 852,
1478+
400, 2154, 404, 874, 426, 2128, 428, 2128, 404, 872, 430, 848, 426, 2128, 404, 872, 414, 2140,
1479+
432, 848, 400, 876, 426, 850, 404, 872, 402, 876, 400, 876, 430, 848, 404, 872, 404, 874, 402,
1480+
2154, 402, 876, 428, 2126, 406, 872, 426, 2128, 426, 852, 404, 872, 430, 2124, 404, 874, 430,
1481+
846, 426, 2128, 400
1482+
}; // ARGO WREM2 (off command)
1483+
1484+
irsend.reset();
1485+
uint8_t expectedState[kArgoStateLength] = {
1486+
0xAC, 0xF5, 0x80, 0x39, 0x06, 0xE0, 0x00, 0xA7, 0x29, 0x80, 0x4A, 0x02 };
1487+
irsend.sendRaw(command_90bit, sizeof(command_90bit) / sizeof(command_90bit[0]), 38);
1488+
irsend.makeDecodeResult();
1489+
EXPECT_TRUE(irrecv.decode(&irsend.capture));
1490+
EXPECT_EQ(decode_type_t::ARGO, irsend.capture.decode_type);
1491+
EXPECT_EQ(kArgoBits, irsend.capture.bits);
1492+
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
1493+
EXPECT_EQ(
1494+
"Model: 1 (WREM2), Power: Off, Mode: 0 (Cool), Fan: 3 (Max), Temp: 10C, Sensor Temp: 21C, Max: Off, IFeel: On, Night: Off",
1495+
IRAcUtils::resultAcToString(&irsend.capture));
1496+
stdAc::state_t r, p;
1497+
EXPECT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
1498+
EXPECT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
1499+
1500+
EXPECT_EQ(21, r.sensorTemperature); // Note: This may be off by 1 per the report in #2133
1501+
EXPECT_TRUE(r.iFeel);
1502+
EXPECT_FALSE(r.power);
1503+
EXPECT_EQ(10, r.degrees);
1504+
EXPECT_EQ(stdAc::opmode_t::kCool, r.mode);
1505+
}
1506+
1507+
14641508
///
14651509
/// @brief Test Fixture for recorded tests
14661510
///

0 commit comments

Comments
 (0)