Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support the WowWee 11-Bit RoboRaptor-X protocol. #1939

Merged
merged 3 commits into from
Dec 31, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/IRrecv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1169,6 +1169,10 @@ bool IRrecv::decode(decode_results *results, irparams_t *save,
DPRINTLN("Attempting GORENJE decode");
if (decodeGorenje(results, offset)) return true;
#endif // DECODE_GORENJE
#if DECODE_WOWWEE
DPRINTLN("Attempting WOWWEE decode");
if (decodeWowwee(results, offset)) return true;
#endif // DECODE_WOWWEE
// Typically new protocols are added above this line.
}
#if DECODE_HASH
Expand Down
6 changes: 6 additions & 0 deletions src/IRrecv.h
Original file line number Diff line number Diff line change
Expand Up @@ -865,6 +865,12 @@ class IRrecv {
const uint16_t nbits = kBosch144Bits,
const bool strict = true);
#endif // DECODE_BOSCH144
#if DECODE_WOWWEE
bool decodeWowwee(decode_results *results,
uint16_t offset = kStartOffset,
const uint16_t nbits = kWowweeBits,
const bool strict = true);
#endif // DECODE_WOWWEE
};

#endif // IRRECV_H_
12 changes: 11 additions & 1 deletion src/IRremoteESP8266.h
Original file line number Diff line number Diff line change
Expand Up @@ -931,6 +931,13 @@
#define SEND_GORENJE _IR_ENABLE_DEFAULT_
#endif // SEND_GORENJE

#ifndef DECODE_WOWWEE
#define DECODE_WOWWEE _IR_ENABLE_DEFAULT_
#endif // DECODE_WOWWEE
#ifndef SEND_WOWWEE
#define SEND_WOWWEE _IR_ENABLE_DEFAULT_
#endif // SEND_WOWWEE

#if (DECODE_ARGO || DECODE_DAIKIN || DECODE_FUJITSU_AC || DECODE_GREE || \
DECODE_KELVINATOR || DECODE_MITSUBISHI_AC || DECODE_TOSHIBA_AC || \
DECODE_TROTEC || DECODE_HAIER_AC || DECODE_HITACHI_AC || \
Expand Down Expand Up @@ -1112,8 +1119,9 @@ enum decode_type_t {
SANYO_AC152,
DAIKIN312,
GORENJE,
WOWWEE,
// Add new entries before this one, and update it to point to the last entry.
kLastDecodeType = GORENJE,
kLastDecodeType = WOWWEE,
};

// Message lengths & required repeat values
Expand Down Expand Up @@ -1387,6 +1395,8 @@ const uint16_t kWhirlpoolAcStateLength = 21;
const uint16_t kWhirlpoolAcBits = kWhirlpoolAcStateLength * 8;
const uint16_t kWhirlpoolAcDefaultRepeat = kNoRepeat;
const uint16_t kWhynterBits = 32;
const uint16_t kWowweeBits = 11;
const uint16_t kWowweeDefaultRepeat = kNoRepeat;
const uint8_t kVestelAcBits = 56;
const uint16_t kXmpBits = 64;
const uint16_t kZepealBits = 16;
Expand Down
7 changes: 7 additions & 0 deletions src/IRsend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,8 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) {
case MULTIBRACKETS:
case GORENJE:
return 8;
case WOWWEE:
return 11;
case RC5:
case SYMPHONY:
return 12;
Expand Down Expand Up @@ -1120,6 +1122,11 @@ bool IRsend::send(const decode_type_t type, const uint64_t data,
sendWhynter(data, nbits, min_repeat);
break;
#endif
#if SEND_WOWWEE
case WOWWEE:
sendWowwee(data, nbits, min_repeat);
break;
#endif // SEND_WOWWEE
#if SEND_XMP
case XMP:
sendXmp(data, nbits, min_repeat);
Expand Down
4 changes: 4 additions & 0 deletions src/IRsend.h
Original file line number Diff line number Diff line change
Expand Up @@ -870,6 +870,10 @@ class IRsend {
const uint16_t nbytes = kBosch144StateLength,
const uint16_t repeat = kNoRepeat);
#endif // SEND_BOSCH144
#if SEND_WOWWEE
void sendWowwee(const uint64_t data, const uint16_t nbits = kWowweeBits,
const uint16_t repeat = kWowweeDefaultRepeat);
#endif // SEND_WOWWEE

protected:
#ifdef UNIT_TEST
Expand Down
2 changes: 2 additions & 0 deletions src/IRtext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,8 @@ IRTEXT_CONST_BLOB_DECL(kAllProtocolNamesStr) {
D_STR_DAIKIN312, D_STR_UNSUPPORTED) "\x0"
COND(DECODE_GORENJE || SEND_GORENJE,
D_STR_GORENJE, D_STR_UNSUPPORTED) "\x0"
COND(DECODE_WOWWEE || SEND_WOWWEE,
D_STR_WOWWEE, D_STR_UNSUPPORTED) "\x0"
///< New protocol (macro) strings should be added just above this line.
"\x0" ///< This string requires double null termination.
};
Expand Down
69 changes: 69 additions & 0 deletions src/ir_Wowwee.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright 2022 David Conran

/// @file
/// @brief Support for WowWee RoboRapter protocol
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues1938

// Supports:
// Brand: WowWee, Model: RoboRapter-X

#include <algorithm>
#include "IRrecv.h"
#include "IRsend.h"
#include "IRutils.h"

// Constants
const uint16_t kWowweeHdrMark = 6684;
const uint16_t kWowweeHdrSpace = 723;
const uint16_t kWowweeBitMark = 912;
const uint16_t kWowweeOneSpace = 3259;
const uint16_t kWowweeZeroSpace = kWowweeHdrSpace;
const uint16_t kWowweeFreq = 38000; // Hz. (Just a guess)


#if SEND_WOWWEE
/// Send a WowWee formatted message.
/// Status: BETA / Untested on a real device.
/// @param[in] data The message to be sent.
/// @param[in] nbits The number of bits of message to be sent.
/// @param[in] repeat The number of times the command is to be repeated.
void IRsend::sendWowwee(uint64_t data, uint16_t nbits, uint16_t repeat) {
sendGeneric(kWowweeHdrMark, kWowweeHdrSpace,
kWowweeBitMark, kWowweeOneSpace,
kWowweeBitMark, kWowweeZeroSpace,
kWowweeBitMark, kDefaultMessageGap, data,
nbits, kWowweeFreq, true, repeat, 33);
}
#endif // SEND_WOWWEE

#if DECODE_WOWWEE
/// Decode the supplied WowWee message.
/// Status: BETA / Untested on a real device.
/// @param[in,out] results Ptr to the data to decode & where to store the result
/// @param[in] offset The starting index to use when attempting to decode the
/// raw data. Typically/Defaults to kStartOffset.
/// @param[in] nbits The number of data bits to expect.
/// @param[in] strict Flag indicating if we should perform strict matching.
bool IRrecv::decodeWowwee(decode_results *results, uint16_t offset,
const uint16_t nbits, const bool strict) {
if (strict && nbits != kWowweeBits)
return false; // We expect Wowwee to be a certain sized message.

uint64_t data = 0;

// Match Header + Data + Footer
if (!matchGeneric(results->rawbuf + offset, &data,
results->rawlen - offset, nbits,
kWowweeHdrMark, kWowweeHdrSpace,
kWowweeBitMark, kWowweeOneSpace,
kWowweeBitMark, kWowweeZeroSpace,
kWowweeBitMark, kDefaultMessageGap, true)) return false;
// Success
results->bits = nbits;
results->value = data;
results->decode_type = WOWWEE;
results->command = 0;
results->address = 0;
return true;
}
#endif // DECODE_WOWWEE
3 changes: 3 additions & 0 deletions src/locale/defaults.h
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,9 @@ D_STR_INDIRECT " " D_STR_MODE
#ifndef D_STR_WHYNTER
#define D_STR_WHYNTER "WHYNTER"
#endif // D_STR_WHYNTER
#ifndef D_STR_WOWWEE
#define D_STR_WOWWEE "WOWWEE"
#endif // D_STR_WOWWEE
#ifndef D_STR_XMP
#define D_STR_XMP "XMP"
#endif // D_STR_XMP
Expand Down
103 changes: 103 additions & 0 deletions test/ir_Wowwee_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// Copyright 2022 David Conran

#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"

TEST(TestUtils, Housekeeping) {
ASSERT_EQ("WOWWEE", typeToString(decode_type_t::WOWWEE));
ASSERT_EQ(decode_type_t::WOWWEE, strToDecodeType("WOWWEE"));
ASSERT_FALSE(hasACState(decode_type_t::WOWWEE));
ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::WOWWEE));
ASSERT_EQ(kWowweeBits, IRsend::defaultBits(decode_type_t::WOWWEE));
ASSERT_EQ(kWowweeDefaultRepeat, IRsend::minRepeats(decode_type_t::WOWWEE));
}

// Tests for sendWowwee().
// Test sending typical data only.
TEST(TestSendWowwee, SendDataOnly) {
IRsendTest irsend(kGpioUnused);
irsend.begin();

irsend.reset();
irsend.sendWowwee(0x186); // Nikai TV Power Off.
EXPECT_EQ(
"f38000d33"
"m6684s723"
"m912s723m912s723m912s3259m912s3259m912s723m912s723m912s723m912s723"
"m912s3259m912s3259m912s723m912s100000",
irsend.outputStr());

irsend.reset();
}

// Tests for decodeWowwee().

// Decode normal Wowwee messages.
TEST(TestDecodeWowwee, RealDecode) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();

// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1938#issue-1513240242
const uint16_t rawForward[25] = {
6684, 740, 918, 724, 942, 724, 918, 3250, 870, 3268, 872, 770, 940, 690,
942, 688, 942, 738, 942, 3250, 868, 3268, 872, 732, 918
}; // UNKNOWN 7469BF81
irsend.reset();
irsend.sendRaw(rawForward, 25, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(decode_type_t::WOWWEE, irsend.capture.decode_type);
EXPECT_EQ(kWowweeBits, irsend.capture.bits);
EXPECT_EQ(0x186, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_EQ(0x0, irsend.capture.address);

// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1938#issue-1513240242
const uint16_t rawLeft[25] = {
6630, 764, 868, 762, 892, 788, 866, 3324, 792, 3348, 818, 760, 866, 788,
894, 772, 892, 750, 870, 786, 920, 750, 864, 776, 868
}; // UNKNOWN 28A1120F
irsend.reset();
irsend.sendRaw(rawLeft, 25, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(decode_type_t::WOWWEE, irsend.capture.decode_type);
EXPECT_EQ(kWowweeBits, irsend.capture.bits);
EXPECT_EQ(0x180, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_EQ(0x0, irsend.capture.address);
}

// Decode normal repeated Wowwee messages.
TEST(TestDecodeWowwee, SyntheticDecode) {
IRsendTest irsend(kGpioUnused);
IRrecv irrecv(kGpioUnused);
irsend.begin();

// Normal Wowwee 11-bit message.
irsend.reset();
irsend.sendWowwee(0x186);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(decode_type_t::WOWWEE, irsend.capture.decode_type);
EXPECT_EQ(kWowweeBits, irsend.capture.bits);
EXPECT_EQ(0x186, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_EQ(0x0, irsend.capture.address);

// Normal Wowwee 11-bit message.
irsend.reset();
irsend.sendWowwee(0x180);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(decode_type_t::WOWWEE, irsend.capture.decode_type);
EXPECT_EQ(kWowweeBits, irsend.capture.bits);
EXPECT_EQ(0x180, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_EQ(0x0, irsend.capture.address);
}