Skip to content

Attempts to modify the PCB hardware to fix invalid messages #166

Description

@kchen

I've been debugging issues with corrupted messages (see reports in #154 and #160), and I have an upcoming software fix that I'm still reviewing and testing that will work around the corruptions. I should be ready to create a PR in the next few days. (My current branch can be found at https://github.com/kchen/esphome-lg-controller/tree/handle-corrupted-messages )

Aside from the software fix, it looks like there may also be some hardware issues contributing to the corrupted messages. Below is Gemini's writeup of the issue. I have reviewed it and it looks reasonable, but I don't have substantial electronics experience, so can't fully confirm it. I am happy to order some new hardware with the changes Gemini proposes, but it will take a while (since I'll have to learn to update the files and then wait for the hardware to be produced and shipped).

Problem Description

During long-term logging of the serial stream on the single-wire communication bus, the microcontroller intermittently experiences severe UART framing errors. These errors consistently manifest during periods of idle traffic, chopping normal 13-byte packets into distinct fragments (most commonly 10+2 or 11+1 byte splits).

[kchen's note: This is because one byte is fully lost, triggering a new message timeout I've implemented, causing the first 10 or 11 bytes to be discarded, and then receiving the remaining 1 or 2 bytes, which are also discarded. The missing byte is never received in software.]

A deep-dive review of the hardware-tiny source files (bom.csv and lg_hvac_esp32.kicad_sch) paired with physical hardware verification reveals a structural circuit conflict. While the KiCad schematic uses an outdated/misleading library symbol footprint marked TJA1029T, the overridden value field and the actual populated physical chip is an NXP TJA1027T/20/1J (U2).

Because the TJA1027 lacks an automatic TXD dominant timeout safety switch, the framing errors are a pure physical-layer logic threshold failure caused by a conflicting Commander (Master) Pull-up topology on the data line.


Technical Breakdown: How 104 bps Timing, Capacitance, and Resistance Create a Threshold Failure

1. The Physics of the 104 bps Null-Byte Flatline

The LG single-wire HVAC bus operates as an asynchronous open-drain UART connection running at an exceptionally slow crawl of 104 bps. At this speed, the physical time width of the electrical pulses becomes massive:

  • A single bit width is exactly 9.615 ms.
  • During idle traffic, the AC unit transmits a series of four consecutive null (0x00) padding bytes (... 00 00 00 00 ...).
  • Within each null byte, the line is driven LOW for 9 consecutive bits (1 Start bit + 8 Data bits). At 104 bps, this creates an enormous 86.54 ms continuous low-voltage window.

This prolonged 86.54 ms time window gives the high parasitic capacitance of shielded cabling ample time to completely drain, bottoming the wire out into a deep electrical ditch. The only opportunity the line has to recover back to an idle logic-high state is a single 9.615 ms Stop bit window at the end of each byte.

2. The "Long Climb" Failure: Parallel Resistance + Cable Capacitance

When our custom adapter board is completely unplugged, measuring the voltage on the AC unit's communication port between the Data and GND pins reads a steady 12V DC. This confirms that the air conditioner's mainboard already houses its own native internal signal pull-up resistor to establish the logic-high communication baseline.

However, the hardware-tiny schematic populates a 1kΩ resistor (R5) and diode (D2) directly on the LINBUS data line. Introducing an external 1kΩ pull-up in parallel with the AC unit's native internal pull-up creates an unwanted parallel resistance network. By the laws of parallel circuits, this aggressively drops the total equivalent bus resistance below its native design parameters ($R_{\text{total}} < 1\text{k}\Omega$).

This artificially low resistance floods the data wire with excessive current. When the transceiver attempts to sink the line LOW during those massive 86.54 ms null-byte windows, the low-side driver has to fight this doubled current load, causing the logic-low voltage baseline to hover abnormally high (around 1.2V to 1.5V).

When the transmission finally hits the brief 9.615 ms Stop bit, the low-side transistor opens, and the voltage must perform a "long climb" back up to 12V. However, the high parasitic capacitance of the shielded cable acts as a sluggish analog sponge ($RC$ time constant), smoothing the sharp digital edge into a lazy, sloped curve.

Because the voltage curve is forced to start its climb from an already elevated 1.5V ditch, the rise time is severely choked. The ESP32's hardware UART peripheral takes an instantaneous digital snapshot exactly halfway through the Stop bit window (at the 4.8 ms mark). Due to the sluggish climb, the voltage at that exact microsecond has not recovered enough to clear the ESP32's rigid digital logic-high threshold. The hardware UART assumes the Stop bit never arrived, flags a Framing Error, and deletes the byte—resulting in the shifting 10+2 and 11+1 packet splits.


Proposed Solution / Fix

To decouple this interaction and stabilize the bus, the board must be converted to a true Responder (Slave) Configuration:

  1. Mark R5 or D2 as DNP (Do Not Populate): In the KiCad project, set resistor R5 or diode D2 properties to DNP. This removes our board's redundant 1kΩ path from the data line.
  2. Resulting Electrical Correction: With the parallel current path eliminated, the logic-low voltage baseline drops cleanly to a true 0.0V. Even though the cable capacitance will still cause a sloped climb, starting the "long climb" from absolute zero grants the signal the necessary electrical clearance to successfully cross the digital logic-high threshold by the time the UART takes its 4.8 ms center-bit snapshot.
  3. Schematic Clean-up Note: It is also recommended to update the KiCad schematic symbol for U2 to match the actual TJA1027 part definition to remove the confusing legacy reference to the TJA1029T.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions