Irremoteesp8266: Decoding Bathroom Washlet IR ๐Ÿšฝ

Created on 18 May 2019  ยท  9Comments  ยท  Source: crankyoldgit/IRremoteESP8266

Greetings from Tokyo! ๐Ÿ‡ฏ๐Ÿ‡ต

We have many IR based Washlets (Toilets) here and thought it'd be a fun experiment to hack around with their signals.

My strategy has been:

  • Capture signals with dump script
  • Analyse the raw data
  • Replay them to Washlet receiver and tweak values
  • Repeat till works

I am not having much luck replaying them to the receiver. I'd be humbled if you had any suggestions or ideas for debugging and replaying the signal?

Experience: Beginner knowledge with electronics

Version/revison of the library used

v2.6.0

Expected behavior

  1. Used IRrecvDumpV2 example to capture IR Commands from Washlet Control
  2. Send captured rawData at Washlet Receiver at 38kHz
  3. Toilet flushes

Actual behavior

Nothing ๐Ÿšฝโ˜น๏ธ

Output of raw data from IRrecvDumpV2.ino

Timestamp : 000396.455
Encoding  : UNKNOWN
Code      : B72A8759 (26 bits)
Library   : v2.6.0

Raw Timing[51]:
   +  8996, -  4474,    +   568, -   556,    +   560, -  1676,    +   568, -   556, 
   +   562, -  1676,    +   562, -  1678,    +   566, -  1674,    +   566, -   558, 
   +   560, -   560,    +   566, -   556,    +   566, -   556,    +   560, -  1678, 
   +   562, -  1676,    +   566, -   556,    +   562, -   560,    +   564, -  1672, 
   +   566, -   556,    +   562, -  1676,    +   562, -  1678,    +   562, -   560, 
   +   564, -   558,    +   564, -  1674,    +   560, -  1678,    +   564, -   560, 
   +   566, -  1670,    +   562

uint16_t rawData[51] = {8996, 4474,  568, 556,  560, 1676,  568, 556,  562, 1676,  562, 1678,  566, 1674,  566, 558,  560, 560,  566, 556,  566, 556,  560, 1678,  562, 1676,  566, 556,  562, 560,  564, 1672,  566, 556,  562, 1676,  562, 1678,  562, 560,  564, 558,  564, 1674,  560, 1678,  564, 560,  566, 1670,  562};  // UNKNOWN B72A8759

Timestamp : 000396.563
Encoding  : UNKNOWN
Code      : B72A8759 (26 bits)
Library   : v2.6.0

Raw Timing[51]:
   +  8996, -  4474,    +   566, -   558,    +   566, -  1670,    +   566, -   558, 
   +   558, -  1676,    +   566, -  1672,    +   588, -  1652,    +   566, -   556, 
   +   564, -   560,    +   564, -   558,    +   564, -   560,    +   564, -  1672, 
   +   564, -  1674,    +   564, -   558,    +   560, -   560,    +   564, -  1676, 
   +   564, -   558,    +   564, -  1674,    +   562, -  1674,    +   566, -   558, 
   +   564, -   558,    +   562, -  1678,    +   558, -  1676,    +   566, -   558, 
   +   558, -  1680,    +   564

uint16_t rawData[51] = {8996, 4474,  566, 558,  566, 1670,  566, 558,  558, 1676,  566, 1672,  588, 1652,  566, 556,  564, 560,  564, 558,  564, 560,  564, 1672,  564, 1674,  564, 558,  560, 560,  564, 1676,  564, 558,  564, 1674,  562, 1674,  566, 558,  564, 558,  562, 1678,  558, 1676,  566, 558,  558, 1680,  564};  

Washlet seems to send two duplicate signals. There are two transmitters on the controls. Perhaps as a fallback to ensure the message is received.

Example code used

const uint16_t kInaxHdrMark = 8996;
const uint16_t kInaxHdrSpace = 4474;
const uint16_t kInaxBitMark = 563;
const uint32_t kInaxOneSpace = 1675;
const uint32_t kInaxZeroSpace = 557;

uint16_t smallFlushRawData[51] = {8996, 4474,  568, 556,  560, 1676,  568, 556,  562, 1676,  562, 1678,  566, 1674,  566, 558,  560, 560,  566, 556,  566, 556,  560, 1678,  562, 1676,  566, 556,  562, 560,  564, 1672,  566, 556,  562, 1676,  562, 1678,  562, 560,  564, 558,  564, 1674,  560, 1678,  564, 560,  566, 1670,  562};

void setup() {
  irsend.begin();
  Serial.begin(115200, SERIAL_8N1, SERIAL_TX_ONLY);
}

// This method is entirely taken from the generated suggestion from analyse script
void sendWashletCommand(uint64_t data, uint16_t nbytes, uint16_t repeat) {
  irsend.enableIROut(38);
  for (uint16_t r = 0; r <= repeat; r++) {
    // Header
    irsend.mark(kInaxHdrMark);
    irsend.space(kInaxHdrSpace);
    // Data
    irsend.sendData(kInaxBitMark, kInaxOneSpace, kInaxBitMark, kInaxZeroSpace, data, nbytes, true);
    // Footer
    irsend.mark(kInaxBitMark);
    irsend.space(100000); 
  }
}

void loop() {
  Serial.println("Sending Washlet Command");
  sendWashletCommand(0x5C32CD, 24, 0);
  delay(2000);
  Serial.println("Sending Washlet Raw Data");
  irsend.sendRaw(smallFlushRawData, 51, 38);
  delay(2000);
  Serial.println("Sending TV Power ON (Control)");
  // Testing can transmit working IR command
  irsend.sendNEC(0xFDB04F);
  delay(2000);
}

Circuit diagram and hardware used

Board: NodeMCU v1.0
Receiver: KY-022
Transmitter: KY-005

I am able to dump my TV remote NEC commands and replay them successfully with the circuit.

I have followed the steps in the Troubleshooting Guide & read the FAQ

Yes

help wanted

Most helpful comment

Um... so I just flushed the toilet from my computer... ๐Ÿ˜ณ

After some debugging, I've confirmed second signal is just an unnecessary repeat, the problem was just aiming the transmitter correctly. Looks like the defacto 38kHz and one command was all that was needed ๐Ÿ‘Œ

Fortunately this porcelain wonder still had the model number printed on it:
Brand: Lixil
Model: Inax
Type: DT-BA283

Found manual online here: https://www.lixil-manual.com/GCW-1365-16050/GCW-1365-16050.pdf
Of course they have an expired SSL cert for their domain ๐Ÿคฆโ€โ™€๏ธ

Looking at page 9 you can see there's a lot of buttons I'll need to record from control board. I'm happy to contribute a Class in the style of others in the /src dir with these commands formatted.

Thanks for your help and suggestions ๐Ÿ™‡

All 9 comments

That code/approach looks good to me. It should _in theory_ work.
I'd suggest changing the transmit frequency. Try values of 36, 40, & 56 for kHz.

Hmmm. Looking at the timestamps you provided for the raw data (yay for supplying more and lots of data!!):
Timestamp : 000396.455 & Timestamp : 000396.563.
That's about 108 msecs (~0.1 seconds) between the two signals. I'd suggest that maybe those two signals need to be played back to back.

Looking at the data again, it's the same signal twice. So, it's probably a repeat.

Try changing the value of 100000 usec gap/space (100msecs) at the end to something like 30000, 40000, 50000, or 60000; and use a repeat.
e.g.
sendWashletCommand(0x5C32CD, 24, 1);

The maximum length of a "normal" packet will be about:
kInaxHdrMark + kInaxHdrSpace + (24 * (kInaxBitMark + kInaxOneSpace)) + kInaxBitMark = ~68000 usecs. (~68 msecs)
e.g. 563 - 455 = 108msec. 108 - 68 msec = 40 msecs (40000 usecs) for the "gap" between the two messages.

Also \o/ for potentially adding support for a Toilet to the library. That's all kind of geeky awesome! Thus you have my full attention! let me know how you go!

Or try:

Serial.println("Sending Washlet Raw Data");
irsend.sendRaw(smallFlushRawData, 51, 38);
delay(40);  // Delay of 40msecs/40000usecs. (try 30, 50, & 60 too)
irsend.sendRaw(smallFlushRawData, 51, 38);
delay(2000);

Amazing, thanks for the suggestions @crankyoldgit! Can't wait to tinker more and get a royal flush ๐Ÿ˜‰

Will update with any progress.

Good luck! Remember, turd time is the charm! ๐Ÿ˜‰

While I think of it, can you get the brand & model of both the toilet and the remote please? We may be able to find some info on the protocol on-line, and we'll probably need that info when we add formal flush support to the library.

And .. how did it go?!

Um... so I just flushed the toilet from my computer... ๐Ÿ˜ณ

After some debugging, I've confirmed second signal is just an unnecessary repeat, the problem was just aiming the transmitter correctly. Looks like the defacto 38kHz and one command was all that was needed ๐Ÿ‘Œ

Fortunately this porcelain wonder still had the model number printed on it:
Brand: Lixil
Model: Inax
Type: DT-BA283

Found manual online here: https://www.lixil-manual.com/GCW-1365-16050/GCW-1365-16050.pdf
Of course they have an expired SSL cert for their domain ๐Ÿคฆโ€โ™€๏ธ

Looking at page 9 you can see there's a lot of buttons I'll need to record from control board. I'm happy to contribute a Class in the style of others in the /src dir with these commands formatted.

Thanks for your help and suggestions ๐Ÿ™‡

Huzzah! Mr Hanky would be so proud.

I'll look at coding up a general send/decode function on the 'morrow for it. If you want to add a class, knock yourself out, It's up to you. I won't stop you. How could I when you are so _flush_ with success?

FYI, The changes mentioned above have been include in v2.6.1 of this library, which has just been released.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

C0rn3j picture C0rn3j  ยท  5Comments

crankyoldgit picture crankyoldgit  ยท  3Comments

direk picture direk  ยท  6Comments

wahibmichael picture wahibmichael  ยท  4Comments

Shalabyer picture Shalabyer  ยท  7Comments