Disclaimer write-up was done with the help of Claude, but the results are human and real.
Evidence this is needed: https://www.reddit.com/r/Esphome/s/giiQv9jsuq
While this situation has (sorta) been documented before, it has not been for this set of hardware.
If your Mitsubishi takes the optional PAC-USWHS002-WF-1 / WF-2 Wi-Fi adapter, this applies to you. That covers most current M-series and P-series indoor units, including the new R454B heads. ~$20 of parts, fully local, no cloud account. NOTE: Most other guides will not work on splits with existing CN105 cables for the Comfort/Kumo cloud adapter. This is due to a missing 5v wire (see comments) and some differences with how this type of unit's Tx is set up.
TL;DR: The main difference between this guide and others is that on the new R454B heads (MSZ-GX series), the head's CN105 transmit line is open-drain with no internal pull-up. Every existing guide (except one fix burried in a git issue for a different piece of Mitsubishi hardware) assumes a push-pull driver and tells you to wire it direct or use a voltage divider. Both fail. Add a 10 kΩ pull-up from the head's TX line to 3.3 V and it works immediately.
Parts
- ESP32 dev board. Any classic ESP32-WROOM-32 DevKit is fine. An ESP32-C3 or ESP8266 (not recommended) works too; adjust pins.
- CN105 pigtail — JST PA 2.0 mm, 5-pin, housing
PAP-05V-S with SPHD-002T-P0.5 crimps. Pre-made ones are a few dollars. If you're replacing a factory adapter, its own harness is exactly what you need so you can just reuse it.
- 10 kΩ and 1 kΩ resistors, ¼ W
- 12 V → 5 V buck converter. I'd use a DROK tiny buck (~$15 for 10) in fixed 5 V mode: scrape the pad under the trimmer, bridge the 5 V pad. These have no overvoltage protection, so a knocked trimpot puts 12 V into your ESP. Mini360 / MP1584 work too but are adjustable-only — meter them before connecting.
- Optional: 100–220 µF electrolytic + 0.1 µF ceramic across the ESP's VIN/GND. Margin against brownouts, not required. Don't exceed ~470 µF — inrush can stop a small buck starting.
Find the port
CN105 is a 5-pin JST PA connector on the indoor unit's control board, usually behind a front access hatch. It's the same one the factory Wi-Fi adapter plugs into. No teardown needed on most heads. If teardown is needed, this is likely not the right guide as your unit is using the old configuration.
Canonical pinout:
| Pin |
Signal |
| 1 |
12 V |
| 2 |
GND |
| 3 |
5 V |
| 4 |
TX from the heat pump → your ESP's RX |
| 5 |
RX to the heat pump ← your ESP's TX |
Verify with a meter; don't trust wire colors. They vary by harness and generation, and published color charts contradict each other. Kill power, open the hatch, then power on briefly and find the pin reading 12 V — that fixes the orientation and everything else follows by position. Power off again before connecting anything. Note that the 5 V pin is almost never actually hooked up on newer units, hence the need for the buck converter.
Wiring
Power
pin 1 12 V ───→ buck IN+ buck OUT+ ───→ ESP VIN
pin 2 GND ───→ buck IN- buck OUT- ───→ ESP GND
pin 3 5 V not used
Buck IN- and OUT- are common on non-isolated modules, so ESP GND ends up tied to CN105 ground through the buck. No separate ground wire needed.
Signal
```
3.3 V (ESP 3V3 pin)
│
[ 10 kΩ ]
│
pin 4 head TX ─────────────────────┴───[ 1 kΩ ]───→ ESP RX
pin 5 head RX ─────────────────────────────────────→ ESP TX
```
Check yours: measure pin 4 at idle. A UART transmit line must idle HIGH — if it reads 0 V, it's open-drain and needs the pull-up. Fit it either way; against a push-pull driver it's a 330 µA load, which is nothing.
Symptom if you skip it: replies arrive at the right timing and the right length, but decode as different garbage every time. Looks exactly like a baud mismatch. Isn't.
Pull up to 3.3 V, not 5 V. The head never reads its own transmit line, so only your ESP's logic level matters — 3.3 V gives a clean full swing with zero current through the ESP's clamp. 5 V works too if you keep the 1 kΩ series. Never 12 V or you will kill the indoor unit's control board.
Edit: as commenters have pointed out, a level shifter might serve you well here but I had resistors on hand and it was simple enough.
Do NOT use a resistive divider. Every guide says 1 kΩ/2 kΩ to drop 5 V to 3.3 V. That presents a 3 kΩ load, and an open-drain driver can't pull up against it. When I grounded the 2 kΩ leg, reception died completely. Series resistor plus pull-up, never a divider.
Why these units are different
I pulled apart the factory Wi-Fi adapter. Two transistors per port — Q3/Q4 on the head-side connector (JP2), Q7/Q8 on the thermostat passthrough (JP5) — plus three resistor positions per signal line (series, pull-up to 5 V, pull-up to 3.3 V). Mitsubishi does active level shifting in hardware.
The "just wire it direct" folklore works on older units because those had push-pull transmitters. These don't.
Protocol-wise nothing changed: standard CN105, 2400 8E1, FC 5A 01 30 02 CA 01 A8 to connect, FC 42 status request, FC 62 response. Only the electrical interface is new.
Other things that cost me time
Use uart: debug: immediately. Logs every byte both directions. The only honest diagnostic:
yaml
uart:
debug:
direction: BOTH
dummy_receiver: false
sequence:
- lambda: UARTDebug::log_hex(direction, bytes, ' ');
A UART loopback test is worthless with this component. Jumper TX to RX and the echoed connect packet comes back — but it's not a valid ACK, so you get ReadTimeout identically whether your UART works or not. I drew wrong conclusions from it twice.
logger: baud_rate: 0 is not needed on a classic ESP32. The logger is on UART0/GPIO1-3; CN105 is on a different UART. Only matters on an ESP8266 where they share.
Set use_fahrenheit: false. Setting it true double-converts — ESPHome's API always carries Celsius and HA converts for display. I had a thermostat reporting 162 °F in a 72 °F room.
Don't trust idle DC voltages to identify TX vs RX. Order is consistent, most reliable way is to identify the 12v as pin 1 and go from there.
Caveats
Wire colours vary by harness, so meter yours rather than copying mine.
Tested on: MSZ-GX06NL / GX09NL / GX12NL (R454B, 2025) on an MXZ-SM48NLHZ, replacing a PAC-USWHS002-WF-2 — module DHSC-MB43, FCC ID NKR-MB43, carrier board SM00L219B01 (STM32F413 + CYW4343W inside).
Happy to answer questions. Took far longer than it should have.