-
Notifications
You must be signed in to change notification settings - Fork 878
Description
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.