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

XMP Protocol Support #1414

Closed
alexyao2015 opened this issue Feb 16, 2021 · 24 comments · Fixed by #1422
Closed

XMP Protocol Support #1414

alexyao2015 opened this issue Feb 16, 2021 · 24 comments · Fixed by #1422
Assignees

Comments

@alexyao2015
Copy link

alexyao2015 commented Feb 16, 2021

Hi thanks for creating this library!

Is there any chance we could get support for the XMP protocol?

This is a protocol used commonly by Comcast/Xfinity remotes.

For this specific protocol, here are codes that allow you to generate raw IR data for this protocol. As well as the program that can be used to take those codes and generate raw IR data and also decode raw IR.

Here is a description of the protocol.

Lastly, here are some implementations of the XMP protocol that may help with implementation:
DecodeIR
Linux Kernel

Thanks for reading and taking a look! Hope this will help with implementing it here!

@crankyoldgit
Copy link
Owner

crankyoldgit commented Feb 17, 2021

@alexyao2015 Yes, it should be do-able to implement the XMP protocol. However, reading those sites, I'm not to familiar with their protocol descriptions, so I'd like you to supply some data by following: https://github.com/crankyoldgit/IRremoteESP8266/wiki/Adding-support-for-a-new-IR-protocol

Skimming the protocol descriptions, the protocol uses a 210 uSecond Mark, followed by a Space of 760uS + (0..15 * 135uS) to describe 4 bits of info. The library can do it, and it won't be the most reliable matching protocol ever, but we can probably make do.

I'll need the Raw data (per that Wiki page) to make sure I understand what the protocol is doing, and have something to test against. e.g. All the descriptions of a protocol pale to measuring the "real" thing. ;-)

@alexyao2015
Copy link
Author

alexyao2015 commented Feb 17, 2021

@crankyoldgit
Hi thanks for getting back! I use ESPHome and in my quest to decode the data, I gathered plenty of raw data from my remote before learning it was already a known protocol known as XMP. I specifically have the XR11 and XR2 from this page. Both remotes use this same XMP protocol.

The following is an Excel spreadsheet of several different buttons from the XR2 remote specifically (should be the same as an XR11 as well). In each sheet, I pressed the button down once and held it down. Unfortunately with that sheet, I failed to correctly record the entire length of the 2 packets of data sent so it appears as 3 packets instead (in 1,2,1,3,1,3 order). Its the same data, however, it misses out on the crucial -13000 delay that combines it into 1 packet of information.
Codes.xlsx

To supplement the spreadsheet, here are some button presses with more data with the 2 packets properly separated. You will notice that the packets here have a spacing of ~-13000 while the generated code from IRScruitinizer/decodeIR seems to have a space of -13800. Furthermore, this difference in space is just enough to cause IRScrutinizer/decodeIR to not be able to decode the packet of data. Changing this width to -13800 in the captured data allows for decoding in these applications, something important to keep in mind when implementing this is to allow for a larger leeway for this space.

Lastly in case I was not clear, the program IRScrutinizer has the ability to actually generate the raw timings without noise so you have a perfect spec of the protocol.

Hope this helps! Please let me know if there is anything else you need.

UP:
[217, -887, 213, -1702, 213, -759, 215, -2807, 208, -1310, 214, -1310, 212, -1180, 211, -2675, 188, -13014, 180, -923, 187, -2438, 180, -794, 183, -786, 185, -1054, 179, -918, 187, -784, 180, -793, 184]
[180, -923, 189, -1727, 188, -786, 187, -2830, 188, -1333, 215, -1308, 214, -1178, 214, -2673, 214, -13015, 214, -889, 217, -1279, 213, -1861, 212, -759, 216, -1018, 212, -890, 212, -760, 210, -760, 215]

DOWN:
[213, -890, 213, -1702, 212, -761, 211, -2806, 212, -1310, 213, -1311, 214, -1177, 213, -2673, 212, -12991, 213, -891, 213, -2254, 211, -761, 214, -757, 211, -1022, 212, -1023, 214, -760, 209, -759, 211]
[215, -889, 212, -1703, 214, -758, 211, -2808, 212, -1311, 212, -1310, 213, -1179, 214, -2673, 211, -12995, 236, -889, 213, -1152, 213, -1861, 212, -759, 212, -1025, 209, -1022, 212, -759, 212, -759, 212]

@crankyoldgit
Copy link
Owner

Thanks for that. That's given me some data to start with. I've got something sort-of working for decoding part of it.

I really need some captures from IRrecvDumpV2 or V3 from the examples directory.

crankyoldgit added a commit that referenced this issue Feb 17, 2021
* Add `sendXmp()` & `decodeXmp()`.
  - Add `IRrecv::matchMarkRange()` & `IRrecv::matchSpaceRange()` to support the new protocol.
* Unit test coverage.
  - Decode real example.
  - Self decode.
* Support checksum verification.

**Note:** Repeat functionality probably not working properly.

For #1414
@crankyoldgit
Copy link
Owner

Can you please download the branch: https://github.com/crankyoldgit/IRremoteESP8266/tree/xmp_support and try out the examples and let me know how it goes?

I think it should detect it now. Sending with repeats probably doesn't work correctly for real devices.

@crankyoldgit crankyoldgit self-assigned this Feb 17, 2021
@crankyoldgit crankyoldgit added enhancement Pending Confirmation Waiting for confirmation from user labels Feb 17, 2021
@crankyoldgit
Copy link
Owner

Oh, can you also supply the Xfinity device/model numbers etc that the remotes control via XMP?

@alexyao2015
Copy link
Author

Unfortunately, I no longer have the devices that the remote controls. I just have the remotes on hand and have been more interested in being able to decode the data rather than the other way around. Thanks for the quick implementation of it! I'll give them a try nearing the week.

Just thoughts, wouldn't reencoding the data be easier as you can simply generate clean raw signal using IRScrutinizer? From there, you can use that information to encode it?

@crankyoldgit
Copy link
Owner

Just thoughts, wouldn't reencoding the data be easier as you can simply generate clean raw signal using IRScrutinizer? From there, you can use that information to encode it?

"Ground truth" (raw) data is better than "Synthesised" data. That way I'm implementing what the remote actually sends, not what another program thinks the remote actually sends. I'm not saying IRScruitinizer has it wrong, but if there is an error in it's implementation, then I'd just be re-implementing that error. i.e. It's better to go to the original source for the data.

See: https://github.com/crankyoldgit/IRremoteESP8266/wiki/Frequently-Asked-Questions#I_want_to_support_a_new_device_but_all_I_have_is_an_allinone_learning_or_appdriven_IR_remote_device_for_sending_messages

@alexyao2015
Copy link
Author

@crankyoldgit Hi again! I still haven't been able to try the lastest code, but reading through the commit, I noticed in the test, only part of the data was included. The data coming in there was split into two pieces with a delay in between. Those two pieces of information were not separate independent presses but rather came from a single press.

I rerecorded the same presses again with the extra delay between the two pieces of information to be extra clear. I hope this clears up some confusion. The only change here is the space of ~-82500 between the two packets of information I provided earlier. Both packets provided earlier are part of the same message. Sorry about the confusion here. I should have been more clear.

UP:
[184, -920, 181, -1735, 183, -788, 182, -2836, 183, -1339, 182, -1341, 183, -1209, 182, -2705, 183, -13020, 183, -920, 181, -2444, 183, -788, 182, -790, 182, -1050, 185, -918, 182, -790, 183, -788, 182, -82593, 183, -919, 183, -1733, 181, -791, 182, -2837, 181, -1341, 182, -1340, 182, -1210, 182, -2704, 184, -13045, 185, -919, 184, -1312, 184, -1890, 181, -791, 180, -1053, 181, -922, 179, -792, 181, -790, 181]

DOWN:
[214, -890, 210, -1707, 210, -761, 210, -2808, 211, -1311, 213, -1310, 213, -1180, 212, -2674, 211, -13018, 212, -866, 212, -2254, 211, -760, 211, -761, 210, -1023, 210, -1023, 213, -759, 213, -758, 211, -82611, 214, -889, 211, -1705, 211, -760, 213, -2807, 210, -1313, 212, -1310, 210, -1180, 212, -2676, 212, -13016, 215, -889, 210, -1154, 213, -1861, 211, -761, 211, -1022, 212, -1022, 212, -760, 210, -761, 210]

@crankyoldgit
Copy link
Owner

A gap of 82ms is pretty much another message. i.e. Its a long long time in IR messages. I think it's a repeat. But the code (value) is different. Reading up on it, XMP does some funky stuff with changing the value when there is a repeat. I haven't worked that out.
It could also be a "button pressed" and a "button released" message. I don't know.
Either way, I need more samples (pref captured with IRrecvDumpV2 or V3) to work it out for sure. i.e. to see if there is a pattern. Or if it is a 128 bits of data, instead of 64bits + and modified 64 bits.
Your spreadsheet data isn't super helpful as it doesn't indicate when a message starts or stops. e.g. Like you've just described. e.g. Is there an implicit gap of 13ms at the end of each line of each tab in the spreadsheet. Where are the 82ms gaps, if any etc?

@alexyao2015
Copy link
Author

It essentially is 2 pieces of information. There is the first piece before the pause that starts with a header message (call this code 1) followed by a space of 13000 then a unique code specific to the button pressed (code 2). Following this is a 82ms space then the same header message (code 1) from earlier and another 13000 space. This is then followed by another unique code that is button specific (code 3).

The spreadsheet has the pieces of data with a short timeout between packets of information. For example, row by row is code 1 followed by code 2, 1, and 3. Between each code is a missing space that I described earlier. So each code is row 1, 13000 space, row 2, 82000 space, row 3, 13000 space, row 4. Following is a repeat of the button.

The repeats are the same as other protocols as it continues to repeat the 1, 13000 space, 3 message until the button is released.

@crankyoldgit
Copy link
Owner

Thanks for the info about your spreadsheet., Any chance you can covert them like you did in #1414 (comment) ?

Per http://www.hifi-remote.com/wiki/index.php/XMP paragraph 3:

This protocol has a 4-bit toggle T that is 0 for the first frame and normally 8 for all repeat frames. There is, however, a variant in which a further frame with T=9 is sent after the button is released, separated from the preceding frame by the short leadout of 13.8m that is used between two half-frames rather than the long lead-out of 80.4m used at the end of all other frames. When this frame is detected then the Misc field displays "With Final Frame". For this to be shown in a learned signal, the button must be released before the learning process times out, so a short button press is needed.

We may be able to deduce your code (3) from the code (1) value. (I haven't looked at it yet. But this is why I think repeats may be currently broken, and are not as simple as you think)

Each of your code (1), code (2), & code (3) are 32 bits. Which leads to 96 bits of data. We can do 96 bits but not as a single integer (biggest is 64 bits). If we generate the checksum nibble on the fly, we can reduce each code to 28 bits, so 84 bits. Ideally we want to shave another 20 bits to get it to fit in a 64 bit integer, rather than going to a uint8_t code[12].

I'd still like some data recorded via IRrecvDumpV3 etc.

@alexyao2015
Copy link
Author

Sorry I still haven't gotten a chance to run IRrecvDumpV3 since it would require me to solder some headers to my device and I haven't gotten around to doing that yet.

With regards to how you can convert the codes, it's simply the same as just adding the respective spaces between each row as described. From there, the only difference is just a surrounding []. Is there something else you would need from that data?

The checksum seems to be described in the irp notation in the description of the XMP protocol provided as C1 and C2. A description of the IRP notation can be found here.

@alexyao2015
Copy link
Author

alexyao2015 commented Feb 27, 2021

Hi @crankyoldgit I finally got around to testing this with IRrecvDumpV3 on the xmp_support branch and it does seem to be decoding it perfectly! The only issue is that it's not differentiating the repeats like it should when I hold a button down for an extended period of time.

I'm holding these buttons down for approximately 3 sec.

Down: Timestamp : 000210.812 Library : v2.7.15

Protocol : XMP
Code : 0x170F443E1B002200 (64 Bits)
uint16_t rawData[35] = {214, 888, 212, 1704, 214, 758, 210, 2808, 212, 1310, 212, 1308, 214, 1178, 212, 2674, 212, 13014, 214, 862, 214, 2252, 214, 756, 214, 758, 214, 1020, 210, 1022, 210, 760, 214, 758, 214}; // XMP 170F443E1B002200
uint64_t data = 0x170F443E1B002200;

Timestamp : 000210.932
Library : v2.7.15

Protocol : XMP
Code : 0x170F443E13802200 (64 Bits)
uint16_t rawData[35] = {214, 888, 212, 1702, 214, 758, 214, 2804, 214, 1308, 214, 1308, 214, 1178, 212, 2674, 212, 13016, 216, 888, 214, 1150, 214, 1860, 214, 756, 212, 1020, 212, 1020, 214, 756, 214, 756, 212}; // XMP 170F443E13802200
uint64_t data = 0x170F443E13802200;

Timestamp : 000211.053
Library : v2.7.15

Protocol : XMP
Code : 0x170F443E13802200 (64 Bits)
uint16_t rawData[35] = {216, 888, 214, 1702, 210, 760, 214, 2804, 212, 1310, 212, 1310, 214, 1176, 214, 2672, 214, 13014, 214, 890, 212, 1152, 214, 1858, 214, 758, 212, 1018, 214, 1020, 214, 758, 210, 760, 210}; // XMP 170F443E13802200
uint64_t data = 0x170F443E13802200;

Timestamp : 000211.173
Library : v2.7.15

Protocol : XMP
Code : 0x170F443E13802200 (64 Bits)
uint16_t rawData[35] = {214, 888, 212, 1704, 212, 758, 210, 2808, 212, 1310, 210, 1312, 212, 1178, 212, 2674, 212, 13016, 214, 890, 210, 1154, 212, 1858, 210, 760, 214, 1020, 214, 1020, 212, 758, 212, 758, 214}; // XMP 170F443E13802200
uint64_t data = 0x170F443E13802200;

Timestamp : 000211.293
Library : v2.7.15

Protocol : XMP
Code : 0x170F443E13802200 (64 Bits)
uint16_t rawData[35] = {214, 890, 212, 1702, 214, 756, 212, 2806, 214, 1308, 212, 1308, 212, 1178, 212, 2674, 212, 13016, 212, 892, 212, 1150, 212, 1860, 214, 756, 212, 1022, 210, 1022, 212, 756, 212, 758, 210}; // XMP 170F443E13802200
uint64_t data = 0x170F443E13802200;

Timestamp : 000211.413
Library : v2.7.15

Protocol : XMP
Code : 0x170F443E13802200 (64 Bits)
uint16_t rawData[35] = {216, 888, 214, 1702, 212, 758, 210, 2806, 210, 1312, 210, 1312, 212, 1178, 210, 2676, 212, 13016, 212, 888, 212, 1154, 210, 1860, 210, 760, 212, 1020, 212, 1022, 210, 760, 210, 760, 210}; // XMP 170F443E13802200
uint64_t data = 0x170F443E13802200;

Timestamp : 000211.533
Library : v2.7.15

Protocol : XMP
Code : 0x170F443E13802200 (64 Bits)
uint16_t rawData[35] = {238, 888, 214, 1702, 212, 758, 212, 2806, 214, 1308, 212, 1310, 212, 1178, 210, 2676, 212, 13016, 212, 864, 212, 1178, 214, 1858, 212, 758, 212, 1020, 212, 1020, 214, 756, 212, 756, 214}; // XMP 170F443E13802200
uint64_t data = 0x170F443E13802200;

Timestamp : 000211.654
Library : v2.7.15

Protocol : XMP
Code : 0x170F443E13802200 (64 Bits)
uint16_t rawData[35] = {214, 888, 212, 1702, 214, 756, 214, 2804, 212, 1312, 210, 1312, 210, 1178, 214, 2672, 212, 13018, 214, 888, 214, 1152, 210, 1862, 214, 758, 210, 1022, 210, 1022, 214, 756, 214, 758, 212}; // XMP 170F443E13802200
uint64_t data = 0x170F443E13802200;

Timestamp : 000211.774
Library : v2.7.15

Protocol : XMP
Code : 0x170F443E13802200 (64 Bits)
uint16_t rawData[35] = {212, 888, 212, 1704, 214, 756, 214, 2802, 214, 1308, 212, 1310, 214, 1176, 214, 2672, 212, 13016, 214, 888, 212, 1154, 210, 1862, 214, 756, 212, 1022, 210, 1022, 212, 758, 212, 760, 212}; // XMP 170F443E13802200
uint64_t data = 0x170F443E13802200;

Timestamp : 000211.894
Library : v2.7.15

Protocol : XMP
Code : 0x170F443E13802200 (64 Bits)
uint16_t rawData[35] = {214, 890, 212, 1704, 212, 758, 210, 2806, 212, 1308, 210, 1312, 212, 1178, 212, 2674, 212, 12994, 236, 890, 210, 1152, 210, 1862, 212, 758, 212, 1020, 214, 1018, 212, 758, 212, 760, 212}; // XMP 170F443E13802200
uint64_t data = 0x170F443E13802200;

Timestamp : 000212.014
Library : v2.7.15

Protocol : XMP
Code : 0x170F443E13802200 (64 Bits)
uint16_t rawData[35] = {214, 890, 212, 1704, 210, 760, 212, 2804, 214, 1308, 212, 1308, 214, 1176, 212, 2674, 214, 12994, 232, 890, 212, 1152, 210, 1860, 214, 756, 212, 1020, 212, 1020, 212, 760, 210, 758, 214}; // XMP 170F443E13802200
uint64_t data = 0x170F443E13802200;

Timestamp : 000212.135
Library : v2.7.15

Protocol : XMP
Code : 0x170F443E13802200 (64 Bits)
uint16_t rawData[35] = {214, 888, 210, 1704, 212, 756, 214, 2804, 212, 1310, 212, 1308, 214, 1178, 214, 2672, 214, 13014, 216, 888, 212, 1152, 212, 1860, 212, 758, 210, 1024, 210, 1022, 212, 758, 212, 760, 212}; // XMP 170F443E13802200
uint64_t data = 0x170F443E13802200;

Timestamp : 000212.255
Library : v2.7.15

Protocol : XMP
Code : 0x170F443E13802200 (64 Bits)
uint16_t rawData[35] = {214, 888, 210, 1704, 212, 758, 212, 2806, 212, 1310, 212, 1308, 212, 1178, 212, 2674, 212, 12994, 234, 892, 212, 1152, 212, 1858, 214, 758, 214, 1018, 214, 1020, 214, 756, 212, 758, 214}; // XMP 170F443E13802200
uint64_t data = 0x170F443E13802200;

Up: Timestamp : 000366.184 Library : v2.7.15

Protocol : XMP
Code : 0x170F443E1C002100 (64 Bits)
uint16_t rawData[35] = {212, 890, 214, 1702, 214, 756, 212, 2804, 216, 1308, 214, 1308, 212, 1178, 212, 2674, 214, 13014, 214, 862, 214, 2410, 212, 758, 212, 758, 212, 1020, 214, 888, 214, 756, 212, 758, 214}; // XMP 170F443E1C002100
uint64_t data = 0x170F443E1C002100;

Timestamp : 000366.304
Library : v2.7.15

Protocol : XMP
Code : 0x170F443E14802100 (64 Bits)
uint16_t rawData[35] = {214, 890, 210, 1704, 214, 758, 212, 2806, 212, 1310, 212, 1310, 214, 1176, 212, 2676, 214, 13014, 212, 888, 214, 1310, 212, 1834, 214, 758, 210, 1022, 212, 890, 212, 758, 212, 758, 212}; // XMP 170F443E14802100
uint64_t data = 0x170F443E14802100;

Timestamp : 000366.424
Library : v2.7.15

Protocol : XMP
Code : 0x170F443E14802100 (64 Bits)
uint16_t rawData[35] = {214, 890, 212, 1702, 212, 756, 214, 2804, 212, 1310, 210, 1310, 214, 1176, 214, 2672, 214, 13014, 212, 892, 212, 1308, 212, 1834, 212, 758, 214, 1018, 212, 888, 212, 758, 212, 758, 210}; // XMP 170F443E14802100
uint64_t data = 0x170F443E14802100;

Timestamp : 000366.544
Library : v2.7.15

Protocol : XMP
Code : 0x170F443E14802100 (64 Bits)
uint16_t rawData[35] = {214, 888, 210, 1706, 212, 758, 210, 2806, 214, 1310, 212, 1308, 212, 1178, 212, 2674, 214, 13014, 214, 890, 210, 1310, 212, 1834, 212, 758, 212, 1022, 210, 890, 210, 760, 214, 756, 214}; // XMP 170F443E14802100
uint64_t data = 0x170F443E14802100;

Timestamp : 000366.664
Library : v2.7.15

Protocol : XMP
Code : 0x170F443E14802100 (64 Bits)
uint16_t rawData[35] = {216, 888, 214, 1702, 212, 758, 208, 2808, 212, 1308, 212, 1308, 212, 1178, 210, 2676, 212, 12994, 236, 888, 212, 1312, 210, 1834, 214, 758, 214, 1018, 214, 890, 214, 756, 212, 758, 214}; // XMP 170F443E14802100
uint64_t data = 0x170F443E14802100;

Timestamp : 000366.785
Library : v2.7.15

Protocol : XMP
Code : 0x170F443E14802100 (64 Bits)
uint16_t rawData[35] = {214, 888, 212, 1702, 212, 758, 212, 2806, 212, 1308, 214, 1308, 214, 1176, 214, 2672, 214, 13014, 214, 888, 212, 1310, 214, 1832, 214, 758, 210, 1022, 210, 890, 212, 758, 212, 758, 212}; // XMP 170F443E14802100
uint64_t data = 0x170F443E14802100;

Timestamp : 000366.905
Library : v2.7.15

Protocol : XMP
Code : 0x170F443E14802100 (64 Bits)
uint16_t rawData[35] = {214, 888, 214, 1700, 212, 756, 214, 2804, 216, 1306, 212, 1310, 212, 1178, 214, 2672, 212, 13016, 212, 890, 214, 1308, 212, 1836, 212, 758, 210, 1022, 210, 892, 210, 758, 214, 756, 214}; // XMP 170F443E14802100
uint64_t data = 0x170F443E14802100;

Timestamp : 000367.025
Library : v2.7.15

Protocol : XMP
Code : 0x170F443E14802100 (64 Bits)
uint16_t rawData[35] = {212, 890, 212, 1702, 212, 758, 210, 2806, 212, 1310, 212, 1310, 212, 1178, 212, 2674, 212, 13016, 212, 890, 214, 1308, 212, 1832, 212, 760, 212, 1020, 216, 886, 212, 758, 214, 756, 210}; // XMP 170F443E14802100
uint64_t data = 0x170F443E14802100;

Timestamp : 000367.145
Library : v2.7.15

Protocol : XMP
Code : 0x170F443E14802100 (64 Bits)
uint16_t rawData[35] = {214, 888, 212, 1702, 210, 760, 212, 2806, 212, 1310, 212, 1308, 214, 1176, 214, 2672, 214, 12992, 234, 890, 212, 1310, 212, 1834, 214, 756, 214, 1020, 212, 888, 214, 756, 214, 756, 212}; // XMP 170F443E14802100
uint64_t data = 0x170F443E14802100;

Timestamp : 000367.265
Library : v2.7.15

Protocol : XMP
Code : 0x170F443E14802100 (64 Bits)
uint16_t rawData[35] = {212, 892, 210, 1704, 212, 758, 210, 2808, 210, 1310, 212, 1310, 212, 1178, 210, 2674, 214, 12990, 242, 886, 212, 1308, 214, 1832, 214, 756, 214, 1020, 212, 890, 212, 758, 214, 758, 214}; // XMP 170F443E14802100
uint64_t data = 0x170F443E14802100;

Timestamp : 000367.386
Library : v2.7.15

Protocol : XMP
Code : 0x170F443E14802100 (64 Bits)
uint16_t rawData[35] = {214, 890, 212, 1704, 212, 758, 212, 2804, 214, 1310, 210, 1310, 214, 1176, 216, 2670, 214, 13016, 212, 888, 214, 1308, 214, 1832, 210, 760, 212, 1020, 214, 888, 212, 756, 210, 760, 212}; // XMP 170F443E14802100
uint64_t data = 0x170F443E14802100;

Timestamp : 000367.506
Library : v2.7.15

Protocol : XMP
Code : 0x170F443E14802100 (64 Bits)
uint16_t rawData[35] = {214, 888, 214, 1702, 212, 758, 214, 2804, 214, 1308, 212, 1308, 212, 1178, 214, 2672, 214, 13014, 212, 890, 214, 1308, 214, 1834, 212, 758, 214, 1020, 212, 890, 212, 760, 210, 758, 214}; // XMP 170F443E14802100
uint64_t data = 0x170F443E14802100;

Timestamp : 000367.626
Library : v2.7.15

Protocol : XMP
Code : 0x170F443E14802100 (64 Bits)
uint16_t rawData[35] = {214, 888, 210, 1704, 212, 758, 214, 2804, 214, 1308, 212, 1310, 214, 1176, 210, 2676, 214, 13014, 210, 892, 214, 1308, 210, 1836, 212, 758, 210, 1022, 210, 890, 212, 758, 212, 758, 210}; // XMP 170F443E14802100
uint64_t data = 0x170F443E14802100;

@crankyoldgit
Copy link
Owner

First off, thanks for that data & confirmation. It's really helpful. It will allow me to construct "correct" synthetic repeat messages. I'll work on that soon.

The only issue is that it's not differentiating the repeats like it should when I hold a button down for an extended period of time.

Um, it looks to me as if it is.

e.g.

Down:
Timestamp : 000210.812
Protocol : XMP
Code : 0x170F443E1B002200 (64 Bits)

Timestamp : 000210.932
Protocol : XMP
Code : 0x170F443E13802200 (64 Bits)

I've highlighted the bits that change from the original & the repeats.

That doesn't seem to be the case. e.g. First two messages captured. The first is the "key press", the next ones are the "repeats". i.e. Different codes.

@alexyao2015
Copy link
Author

Any idea how those bits are found? Is it some checksum or is there a way to predict what the repeat bits will be so that you can report that it's repeated like NEC?

@crankyoldgit
Copy link
Owner

Now that I have some ground truth data, I'll try to work out exactly that based on the XMP specs. As I said earlier:

I'll work on that soon.

@crankyoldgit crankyoldgit removed Pending Confirmation Waiting for confirmation from user more info labels Feb 28, 2021
crankyoldgit added a commit that referenced this issue Feb 28, 2021
* Correctly identify potential XMP repeat messages.
* Use the correct values for an XMP message when sending a repeat.
* Refactor the existing code.
* Add unit tests that confirm the additions/changes.

Fixes #1414
@crankyoldgit
Copy link
Owner

crankyoldgit commented Feb 28, 2021

Hey ya, can you please download and test the latest commit to that branch, and let me know how it goes?
i.e. PR #1422
I've added proper support for repeats now. It should detect & mark them, and it should also create them on the fly when sending.
e.g.

  irsend.sendXmp(0x170F443E1B002200, kXmpBits, 1);  // Down + a single repeat

will produce a "Down" message with a value of 0x170F443E1B002200 and followed by a "Down (repeat)" message of 0x170F443E13802200.

@crankyoldgit
Copy link
Owner

crankyoldgit commented Feb 28, 2021

Any idea how those bits are found?

The repeat nibble (4 bits) is the 3rd Most Significant Nibble in the second 32-bit data segment.
i.e. The mask for a standard 64bit XMP message would be 0x0000000000F00000ULL

Is it some checksum or is there a way to predict what the repeat bits will be so that you can report that it's repeated like NEC?

Yes and Yes.

Yes, There is also a checksum. Two in fact. One of which needs to be recalculated when repeating a msg code.

And Yes, a "repeat" can be detected using the mask above. i.e.
(per http://www.hifi-remote.com/wiki/index.php/XMP)
if ((((msg_code & 0x0000000000F00000ULL) >> 24) & 0xF) == 8) // or 9 then it's a repeat message.
if ((((msg_code & 0x0000000000F00000ULL) >> 24) & 0xF) == 0) then it's not a repeat message. (aka Normal)

@alexyao2015
Copy link
Author

alexyao2015 commented Feb 28, 2021

I just tested the latest version and its a huge success! Awesome work. Repeats are now identified correctly.

There is one quirk, but I'm not sure if its within the scope of this project or not. The xfinity button on the remote sends 2 different codes instead of a single code like all the other buttons. Not sure if supporting that would be outside of this project, but either way, the current work is awesome!

Short press: Timestamp : 000198.502 Library : v2.7.15

Protocol : XMP
Code : 0x170F443E1D002000 (64 Bits)
uint16_t rawData[35] = {182, 920, 180, 1736, 180, 790, 180, 2836, 182, 1340, 180, 1342, 182, 1208, 182, 2704, 180, 13024, 204, 922, 180, 2576, 180, 764, 180, 816, 182, 1026, 180, 788, 184, 788, 182, 788, 182}; // XMP 170F443E1D002000
uint64_t data = 0x170F443E1D002000;

Timestamp : 000198.622
Library : v2.7.15

Protocol : XMP (Repeat)
Code : 0x170F443E15802000 (64 Bits)
uint16_t rawData[35] = {182, 920, 180, 1734, 180, 790, 180, 2836, 182, 1340, 180, 1340, 178, 1212, 180, 2706, 182, 13046, 184, 918, 182, 1446, 180, 1894, 180, 788, 182, 1052, 182, 790, 182, 788, 182, 788, 182}; // XMP (Repeat) 170F443E15802000
uint64_t data = 0x170F443E15802000;

Timestamp : 000199.212
Library : v2.7.15

Protocol : XMP
Code : 0x170F443E1100E000 (64 Bits)
uint16_t rawData[35] = {180, 922, 180, 1734, 180, 790, 180, 2838, 182, 1340, 180, 1340, 182, 1208, 182, 2704, 182, 13046, 182, 920, 180, 896, 180, 790, 180, 790, 180, 2708, 180, 792, 178, 790, 180, 790, 180}; // XMP 170F443E1100E000
uint64_t data = 0x170F443E1100E000;

Long press: Timestamp : 000225.577 Library : v2.7.15

Protocol : XMP
Code : 0x170F443E1D002000 (64 Bits)
uint16_t rawData[35] = {182, 920, 180, 1736, 180, 790, 180, 2836, 182, 1340, 182, 1340, 184, 1206, 182, 2704, 182, 13020, 182, 920, 182, 2572, 182, 790, 180, 790, 182, 1052, 180, 790, 182, 788, 182, 788, 182}; // XMP 170F443E1D002000
uint64_t data = 0x170F443E1D002000;

Timestamp : 000225.697
Library : v2.7.15

Protocol : XMP (Repeat)
Code : 0x170F443E15802000 (64 Bits)
uint16_t rawData[35] = {182, 918, 184, 1732, 184, 788, 182, 2834, 184, 1338, 182, 1340, 182, 1208, 182, 2704, 182, 13022, 208, 920, 180, 1444, 184, 1890, 182, 788, 182, 1052, 180, 790, 182, 788, 182, 788, 184}; // XMP (Repeat) 170F443E15802000
uint64_t data = 0x170F443E15802000;

Timestamp : 000225.818
Library : v2.7.15

Protocol : XMP (Repeat)
Code : 0x170F443E15802000 (64 Bits)
uint16_t rawData[35] = {182, 920, 180, 1734, 182, 790, 180, 2836, 182, 1340, 182, 1340, 180, 1210, 182, 2704, 182, 13046, 184, 920, 182, 1444, 182, 1890, 182, 788, 182, 1050, 182, 788, 182, 788, 182, 790, 180}; // XMP (Repeat) 170F443E15802000
uint64_t data = 0x170F443E15802000;

Timestamp : 000225.939
Library : v2.7.15

Protocol : XMP (Repeat)
Code : 0x170F443E15802000 (64 Bits)
uint16_t rawData[35] = {182, 920, 180, 1734, 182, 790, 180, 2836, 182, 1340, 182, 1338, 182, 1208, 180, 2706, 184, 13046, 182, 894, 182, 1472, 180, 1892, 182, 788, 182, 1052, 180, 790, 180, 790, 182, 788, 182}; // XMP (Repeat) 170F443E15802000
uint64_t data = 0x170F443E15802000;

Timestamp : 000226.059
Library : v2.7.15

Protocol : XMP (Repeat)
Code : 0x170F443E15802000 (64 Bits)
uint16_t rawData[35] = {182, 920, 182, 1734, 182, 788, 182, 2836, 184, 1340, 182, 1338, 180, 1210, 182, 2704, 182, 13048, 182, 920, 180, 1446, 182, 1890, 182, 788, 180, 1052, 182, 788, 180, 790, 182, 788, 180}; // XMP (Repeat) 170F443E15802000
uint64_t data = 0x170F443E15802000;

Timestamp : 000226.179
Library : v2.7.15

Protocol : XMP (Repeat)
Code : 0x170F443E15802000 (64 Bits)
uint16_t rawData[35] = {182, 922, 178, 1736, 180, 790, 182, 2836, 182, 1340, 182, 1340, 182, 1210, 180, 2704, 184, 13046, 180, 922, 178, 1448, 180, 1892, 182, 788, 180, 1054, 176, 794, 178, 790, 182, 790, 180}; // XMP (Repeat) 170F443E15802000
uint64_t data = 0x170F443E15802000;

Timestamp : 000226.299
Library : v2.7.15

Protocol : XMP (Repeat)
Code : 0x170F443E15802000 (64 Bits)
uint16_t rawData[35] = {184, 918, 180, 1736, 180, 790, 182, 2836, 182, 1340, 180, 1340, 180, 1210, 182, 2706, 180, 13020, 182, 920, 180, 1472, 182, 1892, 180, 790, 180, 1052, 182, 788, 182, 788, 182, 788, 180}; // XMP (Repeat) 170F443E15802000
uint64_t data = 0x170F443E15802000;

Timestamp : 000226.420
Library : v2.7.15

Protocol : XMP (Repeat)
Code : 0x170F443E15802000 (64 Bits)
uint16_t rawData[35] = {182, 920, 180, 1734, 184, 788, 182, 2836, 182, 1342, 180, 1340, 180, 1210, 180, 2706, 182, 13046, 182, 920, 182, 1444, 182, 1890, 182, 790, 180, 1052, 180, 790, 180, 790, 180, 790, 182}; // XMP (Repeat) 170F443E15802000
uint64_t data = 0x170F443E15802000;

Timestamp : 000226.541
Library : v2.7.15

Protocol : XMP (Repeat)
Code : 0x170F443E15802000 (64 Bits)
uint16_t rawData[35] = {182, 920, 182, 1734, 182, 790, 180, 2836, 182, 1340, 186, 1336, 180, 1210, 180, 2706, 180, 13048, 182, 920, 180, 1446, 182, 1890, 182, 788, 182, 1052, 180, 790, 180, 790, 180, 790, 180}; // XMP (Repeat) 170F443E15802000
uint64_t data = 0x170F443E15802000;

Timestamp : 000226.661
Library : v2.7.15

Protocol : XMP (Repeat)
Code : 0x170F443E15802000 (64 Bits)
uint16_t rawData[35] = {184, 920, 178, 1736, 180, 790, 180, 2836, 182, 1340, 182, 1340, 180, 1210, 182, 2704, 184, 13044, 182, 920, 180, 1446, 182, 1892, 180, 792, 180, 1052, 180, 790, 182, 788, 182, 790, 180}; // XMP (Repeat) 170F443E15802000
uint64_t data = 0x170F443E15802000;

Timestamp : 000226.782
Library : v2.7.15

Protocol : XMP (Repeat)
Code : 0x170F443E15802000 (64 Bits)
uint16_t rawData[35] = {182, 922, 180, 1732, 182, 790, 180, 2836, 184, 1338, 182, 1340, 180, 1210, 180, 2706, 180, 13048, 182, 920, 182, 1444, 180, 1894, 182, 790, 180, 1052, 182, 788, 182, 790, 180, 790, 182}; // XMP (Repeat) 170F443E15802000
uint64_t data = 0x170F443E15802000;

Timestamp : 000226.902
Library : v2.7.15

Protocol : XMP (Repeat)
Code : 0x170F443E15802000 (64 Bits)
uint16_t rawData[35] = {182, 922, 180, 1734, 182, 790, 180, 2836, 184, 1340, 180, 1342, 180, 1210, 182, 2704, 184, 13044, 184, 918, 182, 1444, 180, 1870, 202, 790, 180, 1054, 180, 788, 182, 788, 180, 790, 180}; // XMP (Repeat) 170F443E15802000
uint64_t data = 0x170F443E15802000;

Timestamp : 000227.024
Library : v2.7.15

Protocol : XMP (Repeat)
Code : 0x170F443E15802000 (64 Bits)
uint16_t rawData[35] = {180, 922, 180, 1734, 180, 790, 180, 2838, 180, 1342, 178, 1344, 180, 1210, 180, 2706, 182, 13046, 182, 920, 180, 1446, 180, 1894, 178, 790, 180, 1054, 180, 790, 180, 790, 180, 790, 182}; // XMP (Repeat) 170F443E15802000
uint64_t data = 0x170F443E15802000;

Timestamp : 000227.144
Library : v2.7.15

Protocol : XMP (Repeat)
Code : 0x170F443E15802000 (64 Bits)
uint16_t rawData[35] = {202, 922, 182, 1734, 182, 788, 182, 2836, 180, 1340, 180, 1340, 182, 1208, 182, 2704, 180, 13048, 184, 920, 180, 1446, 182, 1890, 182, 790, 182, 1050, 182, 788, 180, 792, 180, 790, 182}; // XMP (Repeat) 170F443E15802000
uint64_t data = 0x170F443E15802000;

Timestamp : 000227.264
Library : v2.7.15

Protocol : XMP (Repeat)
Code : 0x170F443E15802000 (64 Bits)
uint16_t rawData[35] = {182, 920, 182, 1732, 182, 790, 180, 2836, 182, 1340, 180, 1340, 184, 1208, 182, 2704, 182, 13046, 182, 894, 182, 1470, 182, 1890, 182, 790, 180, 1052, 182, 788, 180, 790, 180, 790, 182}; // XMP (Repeat) 170F443E15802000
uint64_t data = 0x170F443E15802000;

Timestamp : 000227.842
Library : v2.7.15

Protocol : XMP
Code : 0x170F443E1100E000 (64 Bits)
uint16_t rawData[35] = {180, 924, 178, 1736, 180, 790, 180, 2836, 182, 1340, 180, 1342, 180, 1210, 180, 2706, 182, 13046, 184, 920, 182, 894, 182, 790, 182, 788, 180, 2704, 184, 788, 182, 788, 182, 788, 182}; // XMP 170F443E1100E000
uint64_t data = 0x170F443E1100E000;

@alexyao2015
Copy link
Author

I also wanted to mention that the xfinity button sends codes that are also used by other buttons, but its only an "xfinity" button press if both those codes are sent in a given time.

@crankyoldgit
Copy link
Owner

There is one quirk, but I'm not sure if its within the scope of this project or not. The xfinity button on the remote sends 2 different codes instead of a single code like all the other buttons. Not sure if supporting that would be outside of this project, but either way, the current work is awesome!

It's kind-of out of scope.
e.g. A user of the library can reproduce your data by coding:

// Short Press
irsend.sendXmp(0x170F443E1D002000, kXmpBits, 1);  // Including a single(1) repeat
irsend.sendXmp(0x170F443E1100E000);

// or

// Long Press
irsend.sendXmp(0x170F443E1D002000, kXmpBits, 14);  // Including 14 repeats
irsend.sendXmp(0x170F443E1100E000);

Oh, and thanks for the confirmation it's working.

crankyoldgit added a commit that referenced this issue Mar 1, 2021
* Add `sendXmp()` & `decodeXmp()`.
  - Add `IRrecv::matchMarkRange()` & `IRrecv::matchSpaceRange()` to support the new protocol.
* Support checksum verification and calculation.
* Correctly identify potential XMP repeat messages.
* Use corrected values for an XMP message when sending a repeat.
* Unit test coverage.
  - Decode real example.
  - Self decode.
  - Decode & detect a real repeat message.
  - Sending repeat messages.
  - Housekeeping.

Fixes #1414
crankyoldgit added a commit that referenced this issue Mar 24, 2021
_v2.7.16 (20210324)_

**[Features]**
- ToshibaAC: Swing handling and `setRaw()` improvements. (#1423 #1424 #1425)
- Support for XMP (Xfinity) protocol. (#1414 #1422)
- ToshibaAC: Adjust inter-message gap timing to improve matching. (#1420 #1421)
- Ecoclim: Add detailed A/C support (#1397 #1415)

**[Misc]**
- [ESP32] Fix `addApbChangeCallback(): duplicate func` kernel msgs (#1434 #1435)
- refactor ir_Fujitsu (#1419)
- refactor ir_Whirlpool (#1416)
- refactor ir_Vestel (#1413)
- refactor ir_Trotec (#1412)
crankyoldgit added a commit that referenced this issue Mar 24, 2021
## _v2.7.16 (20210324)_

**[Features]**
- ToshibaAC: Swing handling and `setRaw()` improvements. (#1423 #1424 #1425)
- Support for XMP (Xfinity) protocol. (#1414 #1422)
- ToshibaAC: Adjust inter-message gap timing to improve matching. (#1420 #1421)
- Ecoclim: Add detailed A/C support (#1397 #1415)

**[Misc]**
- [ESP32] Fix `addApbChangeCallback(): duplicate func` kernel msgs (#1434 #1435)
- refactor ir_Fujitsu (#1419)
- refactor ir_Whirlpool (#1416)
- refactor ir_Vestel (#1413)
- refactor ir_Trotec (#1412)
@crankyoldgit
Copy link
Owner

FYI, the aforementioned changes have been included in the new v2.7.16 release for the library.

@frankwaldner
Copy link

I have XR15v2 remote and have all the buttons' timings from LIRC and also have a working LIRC.conf file. Of course some of the buttons are intended to operate the external attached device i.e. television. Interestingly, this remote CAN switch to RF transmission from IR.

Is this useful to you?

@adoUEI
Copy link

adoUEI commented Apr 8, 2024

Hi, I have a beginner question. I see you define the Space step = 135
const uint16_t kXmpSpaceStep = 135; ///< uSeconds

while the Wifi page states "XMP uses one burst pair to encode numbers 0 to 15, with an on duration of 210uS, and off duration of 760uS + n x136uS where n takes on values of 0 to 15"
http://www.hifi-remote.com/wiki/index.php/XMP
Is this on purpose? I have trouble getting consistent decoded data at far distance (>20ft). The output kept switching from XMP protocol to Non-XMP protocol when the signal looked fine on my scope. I used TSOP34338 as my IR receiver.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants