-
Notifications
You must be signed in to change notification settings - Fork 841
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
Request for RecPro / Houghton RV Air Conditioner Protocol #2009
Comments
Please start with raw values, from the lowest temperature, to the highest, one step at a time. |
So I think I've got it pretty well worked out. Spent a really inappropriate amount of time going through the signals and have a good grasp on everything that's happening with the exception of one unmarked button in the remote. The signal is recognized as Carrier-128 protocol, but it does not seem to follow the same breakdown as far as I can tell from reading through the Carrier stuff. I created a 3 sheet spreadsheet that can be accessed here: https://1drv.ms/x/s!Alz2mRtd8II7itATCDTB9I0j-8cZIg?e=tB9whg
I think it's good to go based on my testing. Byte 11 is a little weird, but only when I press an unmarked button on the remote control. It doesn't look like any other manufacturer models use it, so I'm thinking it must be leftover junk from whatever design they stole it from originally. The information bounces all over the place from hex to binary to decimal stored as hex, so it was fn to figure out. Let me know if there's anything else that would help to get this into the project. |
Yes decoding protocols is a pain :D It is great effort to do what you have done, but we need to go back a bit. Please post the raw collection of timing data for your full temperature range, the lowest to the highest, one step at a time. This will allow to create basic support for the protocol, and with the most reasonable endiness. |
Here is the result of resetting the remote to defaults and going from minimum to maximum temperature (in Celsius).
|
Created a bit map of the information that is hopefully a little easier to read than the other sheet. https://docs.google.com/spreadsheets/d/1LJzJOy8rIhit1_dYZVBFdrprVubOtzBqAdxtzQidcsw/edit?usp=sharing |
Anything else I can do to help out here? Think I've provided everything that was requested. Thanks! |
Checking in again. Would really like to get this put in this year before the hot weather starts. |
This is becoming a very popular model of RV air conditioner and I would love to have it integrated into IRremote.
Unit: RP-AC3501-W-KT
Remote: HD01-C1
A raw dump is included along with one that has comments regarding the actions being taken.
IR Dump With Comments.txt
IR Dump.txt
Edited to Hide Dump - Was not receiving commands appropriately
auto_analyze_raw_data.py output: ``` Found 267 timing entries. Potential Mark Candidates: [9296, 4624, 392] Potential Space Candidates: [20966, 20464, 6662, 4912, 2640, 966, 436] DANGER: Unusual number of mark timings! Guessing encoding type: Looks like it uses space encoding. Yay!
Guessing key value:
kHdrMark = 4615
kHdrSpace = 2640
kBitMark = 363
kOneSpace = 903
kZeroSpace = 379
kLdrMark = 9296
kSpaceGap1 = 20966
kSpaceGap2 = 20464
kSpaceGap3 = 6662
kSpaceGap4 = 4912
Decoding protocol based on analysis so far:
kHdrMark+kHdrSpace+0110100001001000001010101110100000000000000000000110010000001100GAP(20464)
Bits: 64
Hex: 0x68482AE80000640C (MSB first)
0x3026000017541216 (LSB first)
Dec: 7514303154188477452 (MSB first)
3469460563326931478 (LSB first)
Bin: 0b0110100001001000001010101110100000000000000000000110010000001100 (MSB first)
0b0011000000100110000000000000000000010111010101000001001000010110 (LSB first)
kHdrMark+UNEXPECTED->GAP(6662)kLdrMark+UNEXPECTED->GAP(4912)kBitMark(UNEXPECTED)0000000000000000000101101001111000000000000000000100101000001010GAP(20966)
Bits: 64
Hex: 0x0000169E00004A0A (MSB first)
0x5052000079680000 (LSB first)
Dec: 24867860662794 (MSB first)
5787688473161367552 (LSB first)
Bin: 0b0000000000000000000101101001111000000000000000000100101000001010 (MSB first)
0b0101000001010010000000000000000001111001011010000000000000000000 (LSB first)
kHdrMark+
Total Nr. of suspected bits: 128
Generating a VERY rough code outline:
// Copyright 2020 David Conran (crankyoldgit)
/// @file
/// @brief Support for TBD protocol
// Supports:
// Brand: TBD, 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 kHdrMark = 4615;
const uint16_t kBitMark = 363;
const uint16_t kHdrSpace = 2640;
const uint16_t kOneSpace = 903;
const uint16_t kZeroSpace = 379;
const uint16_t kLdrMark = 9296;
const uint16_t kSpaceGap1 = 20966;
const uint16_t kSpaceGap2 = 20464;
const uint16_t kSpaceGap3 = 6662;
const uint16_t kSpaceGap4 = 4912;
const uint16_t kFreq = 38000; // Hz. (Guessing the most common frequency.)
const uint16_t kBits = 128; // Move to IRremoteESP8266.h
const uint16_t kStateLength = 16; // Move to IRremoteESP8266.h
const uint16_t kOverhead = 11;
// DANGER: More than 64 bits detected. A uint64_t for 'data' won't work!
#if SEND_TBD
// Function should be safe up to 64 bits.
/// Send a formatted message.
/// Status: ALPHA / Untested.
/// @param[in] data containing the IR command.
/// @param[in] nbits Nr. of bits to send. usually kBits
/// @param[in] repeat Nr. of times the message is to be repeated.
void IRsend::sendTBD(const uint64_t data, const uint16_t nbits, const uint16_t repeat) {
enableIROut(kFreq);
for (uint16_t r = 0; r <= repeat; r++) {
uint64_t send_data = data;
// Header
mark(kHdrMark);
space(kHdrSpace);
// Data Section #1
// e.g. data = 0x68482AE80000640C, nbits = 64
sendData(kBitMark, kOneSpace, kBitMark, kZeroSpace, send_data, 64, true);
send_data >>= 64;
// Footer
mark(kBitMark);
space(kSpaceGap);
// Header
mark(kHdrMark);
// Gap
space(kSpaceGap);
// Leader
mark(kLdrMark);
// Gap
space(kSpaceGap);
// Data Section #2
// e.g. data = 0x169E00004A0A, nbits = 64
sendData(kBitMark, kOneSpace, kBitMark, kZeroSpace, send_data, 64, true);
send_data >>= 64;
// Footer
mark(kBitMark);
space(kSpaceGap);
// Header
mark(kHdrMark);
space(kDefaultMessageGap); // A 100% made up guess of the gap between messages.
}
}
#endif // SEND_TBD
#if SEND_TBD
// Alternative >64bit function to send TBD messages
// Function should be safe over 64 bits.
/// Send a formatted message.
/// Status: ALPHA / Untested.
/// @param[in] data An array of bytes containing the IR command.
/// It is assumed to be in MSB order for this code.
/// e.g.
/// @code
/// uint8_t data[kStateLength] = {0x68, 0x48, 0x2A, 0xE8, 0x00, 0x00, 0x64, 0x0C, 0x00, 0x00, 0x16, 0x9E, 0x00, 0x00, 0x4A, 0x0A};
/// @Endcode
/// @param[in] nbytes Nr. of bytes of data in the array. (>=kStateLength)
/// @param[in] repeat Nr. of times the message is to be repeated.
void IRsend::sendTBD(const uint8_t data[], const uint16_t nbytes, const uint16_t repeat) {
for (uint16_t r = 0; r <= repeat; r++) {
uint16_t pos = 0;
// Data Section #1
// e.g.
// bits = 64; bytes = 8;
// *(data + pos) = {0x68, 0x48, 0x2A, 0xE8, 0x00, 0x00, 0x64, 0x0C};
sendGeneric(kHdrMark, kHdrSpace,
kBitMark, kOneSpace,
kBitMark, kZeroSpace,
kBitMark, kSpaceGap,
data + pos, 8, // Bytes
kFreq, true, kNoRepeat, kDutyDefault);
pos += 8; // Adjust by how many bytes of data we sent
// Data Section #2
// e.g.
// bits = 64; bytes = 8;
// *(data + pos) = {0x00, 0x00, 0x16, 0x9E, 0x00, 0x00, 0x4A, 0x0A};
sendGeneric(kLdrMark, 0,
kBitMark, kOneSpace,
kBitMark, kZeroSpace,
kBitMark, kSpaceGap,
data + pos, 8, // Bytes
kFreq, true, kNoRepeat, kDutyDefault);
pos += 8; // Adjust by how many bytes of data we sent
}
}
#endif // SEND_TBD
// DANGER: More than 64 bits detected. A uint64_t for 'data' won't work!
#if DECODE_TBD
// Function should be safe up to 64 bits.
/// Decode the supplied 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::decodeTBD(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) {
if (results->rawlen < 2 * nbits + kOverhead - offset)
return false; // Too short a message to match.
if (strict && nbits != kBits)
return false;
uint64_t data = 0;
match_result_t data_result;
// Header
if (!matchMark(results->rawbuf[offset++], kHdrMark))
return false;
if (!matchSpace(results->rawbuf[offset++], kHdrSpace))
return false;
// Data Section #1
// e.g. data_result.data = 0x68482AE80000640C, nbits = 64
data_result = matchData(&(results->rawbuf[offset]), 64,
kBitMark, kOneSpace,
kBitMark, kZeroSpace);
offset += data_result.used;
if (data_result.success == false) return false; // Fail
data <<= 64; // Make room for the new bits of data.
data |= data_result.data;
// Footer
if (!matchMark(results->rawbuf[offset++], kBitMark))
return false;
if (!matchSpace(results->rawbuf[offset++], kSpaceGap))
return false;
// Header
if (!matchMark(results->rawbuf[offset++], kHdrMark))
return false;
// Gap
if (!matchSpace(results->rawbuf[offset++], kSpaceGap))
return false;
// Leader
if (!matchMark(results->rawbuf[offset++], kLdrMark))
return false;
// Gap
if (!matchSpace(results->rawbuf[offset++], kSpaceGap))
return false;
// Data Section #2
// e.g. data_result.data = 0x169E00004A0A, nbits = 64
data_result = matchData(&(results->rawbuf[offset]), 64,
kBitMark, kOneSpace,
kBitMark, kZeroSpace);
offset += data_result.used;
if (data_result.success == false) return false; // Fail
data <<= 64; // Make room for the new bits of data.
data |= data_result.data;
// Footer
if (!matchMark(results->rawbuf[offset++], kBitMark))
return false;
if (!matchSpace(results->rawbuf[offset++], kSpaceGap))
return false;
// Header
if (!matchMark(results->rawbuf[offset++], kHdrMark))
return false;
// Success
results->decode_type = decode_type_t::TBD;
results->bits = nbits;
results->value = data;
results->command = 0;
results->address = 0;
return true;
}
#endif // DECODE_TBD
#if DECODE_TBD
// Function should be safe over 64 bits.
/// Decode the supplied 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::decodeTBD(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) {
if (results->rawlen < 2 * nbits + kOverhead - offset)
return false; // Too short a message to match.
if (strict && nbits != kBits)
return false;
uint16_t pos = 0;
uint16_t used = 0;
// Data Section #1
// e.g.
// bits = 64; bytes = 8;
// *(results->state + pos) = {0x68, 0x48, 0x2A, 0xE8, 0x00, 0x00, 0x64, 0x0C};
used = matchGeneric(results->rawbuf + offset, results->state + pos,
results->rawlen - offset, 64,
kHdrMark, kHdrSpace,
kBitMark, kOneSpace,
kBitMark, kZeroSpace,
kBitMark, kSpaceGap, true);
if (used == 0) return false; // We failed to find any data.
offset += used; // Adjust for how much of the message we read.
pos += 8; // Adjust by how many bytes of data we read
// Data Section #2
// e.g.
// bits = 64; bytes = 8;
// *(results->state + pos) = {0x00, 0x00, 0x16, 0x9E, 0x00, 0x00, 0x4A, 0x0A};
used = matchGeneric(results->rawbuf + offset, results->state + pos,
results->rawlen - offset, 64,
kLdrMark, 0,
kBitMark, kOneSpace,
kBitMark, kZeroSpace,
kBitMark, kSpaceGap, true);
if (used == 0) return false; // We failed to find any data.
offset += used; // Adjust for how much of the message we read.
pos += 8; // Adjust by how many bytes of data we read
// Success
results->decode_type = decode_type_t::TBD;
results->bits = nbits;
return true;
}
#endif // DECODE_TBD
The text was updated successfully, but these errors were encountered: