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

WowWee protocol (for Roboraptor) #1938

Closed
dragoncoder047 opened this issue Dec 28, 2022 · 6 comments · Fixed by #1939
Closed

WowWee protocol (for Roboraptor) #1938

dragoncoder047 opened this issue Dec 28, 2022 · 6 comments · Fixed by #1939
Assignees
Labels
enhancement Pending Confirmation Waiting for confirmation from user

Comments

@dragoncoder047
Copy link

Device: A WowWee Roboraptor X (https://wowwee.com/roboraptor-x) -- the similar Roboraptor Blue is probably the same in terms of IR protocol.

Remote is the one in the box with it, and is the focus of this issue.

Manual can be found readily online. Just google "wowwee roboraptor manual", it should be towards the top.

I am using the internal IR recievers in the Roboraptor itself to capture the packets. Because why not. (I am trying to reverse-engineer it and do some "upgrades", of which this is the first.)

Micrcontroller: Sparkfun ESP32 Thing Plus

Wiring: Open up Roboraptor. Note 2 largest plugs containing individual thin wires leading into neck. Unplug them both and look at labels on circuit board.

3V3 --> IRV (larger plug) -- either L or R works, just pick one
GND --> GND (smaller plug)
14  --> IRO (larger plug) -- use same L or R as for 3V3 pin or you'll get garbage

As these are really just direct connections to a demodulator IC in the head, IRrecvDumpV2 worked mostly flawlessly.

The IR recievers are a little finicky (not just with the ESP32, they were always finicky since the day I unboxed my Roboraptor), so any dump outputs that do not say 13 bits and/or do not start with a first rawData array entry in the 6xxx range can probably just be thrown out as gibberish.

Obviously it prints UNKNOWN for all of the codes, because, well, this is a new protocol. Here are some of the timing arrays for different buttons on the remote:

Button Timing array
Forward uint16_t rawData[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
Backward uint16_t rawData[25] = {6684, 714, 894, 774, 894, 750, 894, 3310, 870, 3270, 870, 732, 894, 762, 894, 772, 894, 748, 894, 3272, 872, 3270, 872, 3280, 872}; // UNKNOWN 7569C112
Left uint16_t rawData[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
Right uint16_t rawData[25] = {6630, 702, 866, 800, 842, 800, 868, 3322, 844, 3272, 818, 846, 842, 814, 816, 814, 868, 3324, 818, 774, 890, 776, 868, 774, 868}; // UNKNOWN 139C80D1
Stop uint16_t rawData[25] = {6224, 724, 916, 750, 918, 698, 944, 3246, 872, 3268, 868, 770, 916, 712, 942, 710, 916, 3274, 870, 3254, 844, 3294, 868, 748, 938}; // UNKNOWN ECB3BDC9

auto_analyse_raw_data.py said (of the "Forward" code):

Found 25 timing entries.
Potential Mark Candidates:
[6684, 942]
Potential Space Candidates:
[3268, 770]

Guessing encoding type:
Sorry, it looks like it is Mark encoded. I can't do that yet. Exiting.

I deleted the first two entries (so it is now uint16_t rawData[23] = {918, 724, 942, 724, 918, 3250, 870, 3268, 872, 770, 940, 690, 942, 688, 942, 738, 942, 3250, 868, 3268, 872, 732, 918}; and it produced this output:

Click to show lots of output
Found 23 timing entries.
Potential Mark Candidates:
[942]
Potential Space Candidates:
[3268, 770]

Guessing encoding type:
Looks like it uses space encoding. Yay!

Guessing key value:
kRoboraptorHdrMark   = 0
kRoboraptorHdrSpace  = 0
kRoboraptorBitMark   = 912
kRoboraptorOneSpace  = 3259
kRoboraptorZeroSpace = 723

Decoding protocol based on analysis so far:

kRoboraptorBitMark(UNEXPECTED)00110000110
  Bits: 11
  Hex:  0x186 (MSB first)
        0x30C (LSB first)
  Dec:  390 (MSB first)
        780 (LSB first)
  Bin:  0b00110000110 (MSB first)
        0b01100001100 (LSB first)

Total Nr. of suspected bits: 11

Generating a VERY rough code outline:

// Copyright 2020 David Conran (crankyoldgit)
/// @file
/// @brief Support for Roboraptor protocol

// Supports:
//   Brand: Roboraptor,  Model: TODO add device and remote

#include "IRrecv.h"
#include "IRsend.h"
#include "IRutils.h"

// WARNING: This probably isn't directly usable. It's a guide only.

// See https://github.com/crankyoldgit/IRremoteESP8266/wiki/Adding-support-for-a-new-IR-protocol
// for details of how to include this in the library.
const uint16_t kRoboraptorHdrMark = 0;
const uint16_t kRoboraptorBitMark = 912;
const uint16_t kRoboraptorHdrSpace = 0;
const uint16_t kRoboraptorOneSpace = 3259;
const uint16_t kRoboraptorZeroSpace = 723;
const uint16_t kRoboraptorFreq = 38000;  // Hz. (Guessing the most common frequency.)
const uint16_t kRoboraptorBits = 11;  // Move to IRremoteESP8266.h
const uint16_t kRoboraptorOverhead = 1;

#if SEND_ROBORAPTOR
// Function should be safe up to 64 bits.
/// Send a Roboraptor formatted message.
/// Status: ALPHA / Untested.
/// @param[in] data containing the IR command.
/// @param[in] nbits Nr. of bits to send. usually kRoboraptorBits
/// @param[in] repeat Nr. of times the message is to be repeated.
void IRsend::sendRoboraptor(const uint64_t data, const uint16_t nbits, const uint16_t repeat) {
  enableIROut(kRoboraptorFreq);
  for (uint16_t r = 0; r <= repeat; r++) {
    uint64_t send_data = data;
    // Data Section #1
    // e.g. data = 0x186, nbits = 11
    sendData(kRoboraptorBitMark, kRoboraptorOneSpace, kRoboraptorBitMark, kRoboraptorZeroSpace, send_data, 11, true);
    send_data >>= 11;
    // Footer
    mark(kRoboraptorBitMark);
    space(kDefaultMessageGap);  // A 100% made up guess of the gap between messages.
  }
}
#endif  // SEND_ROBORAPTOR

#if DECODE_ROBORAPTOR
// Function should be safe up to 64 bits.
/// Decode the supplied Roboraptor message.
/// Status: ALPHA / Untested.
/// @param[in,out] results Ptr to the data to decode & where to store the decode
/// @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.
/// @return A boolean. True if it can decode it, false if it can't.
bool IRrecv::decodeRoboraptor(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) {
  if (results->rawlen < 2 * nbits + kRoboraptorOverhead - offset)
    return false;  // Too short a message to match.
  if (strict && nbits != kRoboraptorBits)
    return false;

  uint64_t data = 0;
  match_result_t data_result;

  // Data Section #1
  // e.g. data_result.data = 0x186, nbits = 11
  data_result = matchData(&(results->rawbuf[offset]), 11,
                          kRoboraptorBitMark, kRoboraptorOneSpace,
                          kRoboraptorBitMark, kRoboraptorZeroSpace);
  offset += data_result.used;
  if (data_result.success == false) return false;  // Fail
  data <<= 11;  // Make room for the new bits of data.
  data |= data_result.data;

  // Footer
  if (!matchMark(results->rawbuf[offset++], kRoboraptorBitMark))
    return false;

  // Success
  results->decode_type = decode_type_t::ROBORAPTOR;
  results->bits = nbits;
  results->value = data;
  results->command = 0;
  results->address = 0;
  return true;
}
#endif  // DECODE_ROBORAPTOR

Should I do more codes?

I also found https://github.com/kelliott121/roboraptor/blob/master/RoboRaptor_Remote/RoboRaptor_Remote.ino, which seems to implement this protocol. auto_analyse_raw_data.py's above guess at the "Forward" code lines up with @kelliott121's code there. Maybe that would help.

@crankyoldgit
Copy link
Owner

Have you successfully been able to control the device by replaying the Raw IR messages back to the device?
And yes, auto_analyse_raw_data.py is not perfect and doesn't handle this case well.

@dragoncoder047
Copy link
Author

Ah yes, the problem is that the whole reason I wanted to make this "upgrade" was that my Roboraptor stopped working. But I'll see if I can get some sort of response out of it tomorrow. I do not have any spare IR LED's, so I will have to hijack one of the ones in the nose and then hold up a piece of paper in front. The speaker still works and so if I get it to make certain noises then I'll know the original circuit board successfully received them.

@dragoncoder047
Copy link
Author

Have you successfully been able to control the device by replaying the Raw IR messages back to the device?

I'm working on that right now. Please tell me whether my code is correct before I waste any more time trying to debug my wiring.

click to show code
#include <IRremoteESP8266.h>
#include <IRsend.h>

IRsend irsend(4);

void setup() {
    Serial.begin(115200); // Note the high baud rate
    irsend.enableIROut(38);
}

#define commandLength 25
const uint16_t hunting[commandLength] = {6670, 718,  914, 750,  916, 720,  918, 3246,  868, 3266,  846, 794,  916, 3246,  866, 3268,  868, 732,  916, 3244,  916, 712,  916, 760,  920};
const uint16_t happy[commandLength] = {6698, 712,  916, 710,  916, 762,  894, 3268,  870, 3266,  844, 758,  892, 3306,  870, 3266,  868, 732,  892, 760,  894, 3280,  844, 3304,  844};
const uint16_t cautious[commandLength] = {6696, 714,  912, 752,  918, 720,  918, 3244,  914, 3222,  916, 722,  918, 3244,  868, 3266,  870, 772,  914, 734,  918, 3220,  888, 752,  916};
const uint16_t guard[commandLength] = {6546, 722,  890, 736,  920, 758,  920, 3244,  868, 3266,  846, 756,  894, 3270,  914, 3220,  892, 748,  920, 732,  918, 748,  920, 718,  920};
const uint16_t stopcommand[commandLength] = {6224, 724,  916, 750,  918, 698,  944, 3246,  872, 3268,  868, 770,  916, 712,  942, 710,  916, 3274,  870, 3254,  844, 3294,  868, 748,  938};

void loop() {
    yield();
    if (Serial.available() > 0) {
        char c = Serial.read();
        switch(c) {
            case 'h':
                Serial.print("Sending HUNTING MOOD command");
                irsend.sendRaw(hunting, commandLength, 38);
                break;
            case 'a':
                Serial.print("Sending HAPPY MOOD command");
                irsend.sendRaw(happy, commandLength, 38);
                break;
            case 'c':
                Serial.print("Sending CAUTIOUS MOOD command");
                irsend.sendRaw(cautious, commandLength, 38);
                break;
            case 'g':
                Serial.print("Sending GUARD MODE command");
                irsend.sendRaw(guard, commandLength, 38);
                break;
            case '\r':
            case '\n':
                // ignore
                break;
            default:
                Serial.printf("Didn't understand '%c' - Sending STOP command", c);
                irsend.sendRaw(stopcommand, commandLength, 38);
                break;
        }
        Serial.flush();
        Serial.write('\n');
    }
}

I connected the LED between pin 4 and 3V3, and nothing. I swapped it out for a red LED and only got a feeble dim glow constantly on that only went away when I held down the reset button. Does it look like a hardware problem or a software problem?

@dragoncoder047 dragoncoder047 changed the title Add support for WowWee Roboraptor protocol (Mark encoded; no help from auto_analyse_raw_data.py) WowWee protocol (for Roboraptor) Dec 29, 2022
crankyoldgit added a commit that referenced this issue Dec 30, 2022
* Basic `sendWowwee()` & decodeWowwee()` routines.
* Unit test coverage including decoding of two different captured messages from a real remote.

Fixes #1938
@crankyoldgit
Copy link
Owner

    irsend.enableIROut(38);

Replace that with irsend.begin();, That configures the GPIO for output. i.e. So it can send the IR signal.
Please also note the recommended circuit design in the wiki/faq/troubleshooting guide(s)

@crankyoldgit
Copy link
Owner

Please download & try out branch: https://github.com/crankyoldgit/IRremoteESP8266/tree/WowWee / PR #1939
It should give you the ability to decode the IR messages into 11-bit codes. (e.g. For "Forward" you get 0x186)
and you should be able to send using:

irsend.sendWowwee(code);  // e.g. 0x180 for "Left" etc

Please let me know how it goes.

@crankyoldgit crankyoldgit added the Pending Confirmation Waiting for confirmation from user label Dec 30, 2022
@dragoncoder047
Copy link
Author

Replace that with irsend.begin();, That configures the GPIO for output. i.e. So it can send the IR signal.
Please also note the recommended circuit design in the wiki/faq/troubleshooting guide(s).

Oops, forgot about that! Thank you! I didn't have a regular bipolar NPN transistor so I used an N-channel MOSFET (2N7000).

Ad it works!! I swapped out the .sendRaw calls for the new .sendWowwee calls with the values below and everything works as if I pressed buttons on the remote.

Please let me know how it goes.

decodeWowwee works great!!

Button Code
Forward 0x186
Backward 0x187
Left 0x180
Right 0x188
Stop 0x18E
Demo 0x1D0
Head Clockwise 0x194
Head Counterclockwise 0x191
Tail Left 0x192
Tail Right 0x193
Bite 0x1D1
Roam 0x1B1
Hunting Mood 0x1B4
Playful Mood 0x1B3
Cautious Mood 0x1B2
Guard Mode 0x1B0

I would also suggest either adding an enum with these codes in the code, or referring users to this comment in the documentation.

crankyoldgit added a commit that referenced this issue Dec 31, 2022
* Basic `sendWowwee()` & decodeWowwee()` routines.
* Unit test coverage including decoding of two different captured messages from a real remote.
* Add reference for available/known RoboRaptor-X codes.

Fixes #1938
crankyoldgit added a commit that referenced this issue Mar 5, 2023
_v2.8.5 (20230305)_

**[Bug Fixes]**
- Missing argument in use of midea function (#1959 #1958)
- IRMQTTServer: Improve HA MQTT climate handling. (#1911)
- SEND_SANYO_AC88: Fix poor cut-n-paste error (#1905 #1897)

**[Features]**
- IRMQTTServer: SHT-3x Temperature Sensor Support (#1951)
- IRMQTTServer: HA multi output discovery (#1947)
- IRMQTTServer: extended with new A/C common fields (#1940)
- IRMQTTServer: Sync the on state to power from mode for HA (#1946)
- Experimental basic support for Carrier 84-bit protocol. (#1945 #1943)
- Add support the WowWee 11-Bit RoboRaptor-X protocol. (#1939 #1938)
- Added 'sensorTemperature' and 'iFeel' to IRac (common) (#1928)
- Added extra 'mid' option for Fan & SwingV to IRac (#1929)
- Added "commandType" to IRAc (#1921)
- Added support for Argo WREM-3 A/C remote protocol [part1] (#1920)
- Added Dutch (nl-NL) translation (#1907)
- ARGO: Improve code & add support for decoding 32bit sensor msgs. (#1906 #1859)
- Added support for Gorenje cooker hood IR protocol (#1888 #1887)

**[Misc]**
- Update `XMP` status to Stable (#1944)
- upgrade to a later version of `googletest` (#1936)
- MITSUBISHI128: Added model to supported protocol (#1924)
- Added Dutch (nl-NL) README (#1908)
- Added GMock to UT Makefile (#1902)
- Update HA example config for HA 2022.6+ (#1901 #1900)
crankyoldgit added a commit that referenced this issue May 8, 2023
_v2.8.5 (20230508)_

**[Bug Fixes]**
- Fix a bug where we never detached the timer interrupt on ESP32s. (#1984 #1983)
- Missing argument in use of midea function (#1959 #1958)
- IRMQTTServer: Improve HA MQTT climate handling. (#1911)
- SEND_SANYO_AC88: Fix poor cut-n-paste error (#1905 #1897)

**[Features]**
- Add support for a 40bit variant of the standard Panasonic protocol (#1977 @1976)
- Initial support for York AC protocol (#1889)
- IRMQTTServer: SHT-3x Temperature Sensor Support (#1951)
- IRMQTTServer: HA multi output discovery (#1947)
- IRMQTTServer: extended with new A/C common fields (#1940)
- IRMQTTServer: Sync the on state to power from mode for HA (#1946)
- Experimental basic support for Carrier 84-bit protocol. (#1945 #1943)
- Add support the WowWee 11-Bit RoboRaptor-X protocol. (#1939 #1938)
- Added 'sensorTemperature' and 'iFeel' to IRac (common) (#1928)
- Added extra 'mid' option for Fan & SwingV to IRac (#1929)
- Added "commandType" to IRAc (#1921)
- Added support for Argo WREM-3 A/C remote protocol [part1] (#1920)
- Added Dutch (nl-NL) translation (#1907)
- ARGO: Improve code & add support for decoding 32bit sensor msgs. (#1906 #1859)
- Added support for Gorenje cooker hood IR protocol (#1888 #1887)

**[Misc]**
- Add Electrolux YKR-H/531E as a supported device (#1981 #1980)
- Update `XMP` status to Stable (#1944)
- upgrade to a later version of `googletest` (#1936)
- MITSUBISHI128: Added model to supported protocol (#1924)
- Added Dutch (nl-NL) README (#1908)
- Added GMock to UT Makefile (#1902)
- Update HA example config for HA 2022.6+ (#1901 #1900)
- Add a `d1_mini_noMDNS` build option to `IRMQTTServer`. (#1985)
crankyoldgit added a commit that referenced this issue May 8, 2023
## _v2.8.5 (20230508)_

**[Bug Fixes]**
- Fix a bug where we never detached the timer interrupt on ESP32s. (#1984 #1983)
- Missing argument in use of midea function (#1959 #1958)
- IRMQTTServer: Improve HA MQTT climate handling. (#1911)
- SEND_SANYO_AC88: Fix poor cut-n-paste error (#1905 #1897)

**[Features]**
- Add support for a 40bit variant of the standard Panasonic protocol (#1977 @1976)
- Initial support for York AC protocol (#1889)
- IRMQTTServer: SHT-3x Temperature Sensor Support (#1951)
- IRMQTTServer: HA multi output discovery (#1947)
- IRMQTTServer: extended with new A/C common fields (#1940)
- IRMQTTServer: Sync the on state to power from mode for HA (#1946)
- Experimental basic support for Carrier 84-bit protocol. (#1945 #1943)
- Add support the WowWee 11-Bit RoboRaptor-X protocol. (#1939 #1938)
- Added 'sensorTemperature' and 'iFeel' to IRac (common) (#1928)
- Added extra 'mid' option for Fan & SwingV to IRac (#1929)
- Added "commandType" to IRAc (#1921)
- Added support for Argo WREM-3 A/C remote protocol [part1] (#1920)
- Added Dutch (nl-NL) translation (#1907)
- ARGO: Improve code & add support for decoding 32bit sensor msgs. (#1906 #1859)
- Added support for Gorenje cooker hood IR protocol (#1888 #1887)

**[Misc]**
- Add Electrolux YKR-H/531E as a supported device (#1981 #1980)
- Update `XMP` status to Stable (#1944)
- upgrade to a later version of `googletest` (#1936)
- MITSUBISHI128: Added model to supported protocol (#1924)
- Added Dutch (nl-NL) README (#1908)
- Added GMock to UT Makefile (#1902)
- Update HA example config for HA 2022.6+ (#1901 #1900)
- Add a `d1_mini_noMDNS` build option to `IRMQTTServer`. (#1985)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Pending Confirmation Waiting for confirmation from user
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants