You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A recurring pattern across support issues (#841, #875, and others) shows that users fail to
get the UART-TTL (GPS port) connection working out of the box. Two root causes dominate:
Interference from a USB-UART converter sharing UART0 (GPIO1/GPIO3)
Serial logger output also written to UART0, corrupting the BMS data stream
Both issues are silent – the firmware compiles and flashes without errors, but the BMS
either stays silent or sends garbled data. Symptoms include Invalid header errors,
wildly wrong sensor values (cell voltages at ±100 V, temperatures at 1316 °C), or
complete silence on the bus.
Affected configuration files
This issue concerns only the UART-TTL (GPS port) setup. The following files are
affected:
Note on naming confusion: The jk_modbus component used in the UART-TTL examples
is not real Modbus RTU. It implements the JK-proprietary framing protocol that
happens to travel over a UART-TTL wire. The name is misleading but intentional within
this project. Real Modbus (RS485, JK-PB series) lives in the jk-pb-modbus-example files.
Root cause
UART0 (GPIO1 = TXD, GPIO3 = RXD) is a shared resource
On virtually every ESP32/ESP8266 development board, UART0 is wired to the on-board
USB-UART bridge (CH340, CP2102, …). During normal operation this means:
The USB-UART converter is already electrically driving those pins from the host PC.
The ESPHome logger (default config) outputs its log stream to UART0.
Attaching the BMS to the same bus turns the connection into a three-way collision:
BMS frames, logger output, and USB converter traffic all fight on the same wire.
Platform-specific recommendations
ESP32 – use the GPIO matrix
The ESP32 contains a full GPIO matrix. Any of the three hardware UARTs (UART0, UART1,
UART2) can be routed to any GPIO. The component already defaults to GPIO16/GPIO17
(UART2), which is the right choice. Users just need to understand why they must not
change those to GPIO1/GPIO3.
The logger continues to write to UART0 (GPIO1/GPIO3) in the background, but since the
BMS is connected to UART2 (GPIO16/GPIO17) there is zero interference. No baud_rate: 0
hack is needed for the logger on ESP32.
Do not use GPIO1 or GPIO3 for the BMS connection on an ESP32.
ESP8266 – SoftwareSerial with logger disabled
The ESP8266 has only one hardware UART (UART0, GPIO1/GPIO3). There is no second hardware
UART that could be routed elsewhere. ESPHome therefore falls back to SoftwareSerial
when the configured pins differ from GPIO1/GPIO3.
SoftwareSerial at 115200 baud is tight on an 80 MHz single-core MCU. Occasional CRC
errors are expected but the connection is usable. The current example already uses
GPIO4/GPIO5. That is the correct choice.
Critically, the logger must be silenced because it would otherwise spam UART0 and
interfere even when the BMS is on different pins (the ESP8266 TXD output is always
GPIO1 unless explicitly disabled):
logger:
baud_rate: 0# REQUIRED on ESP8266 – disables serial log output
The current esp8266-example.yaml already includes this. It must stay there.
BMS-side protocol selection
The JK-BMS GPS/UART port must be configured with the correct protocol. Newer firmware
versions (≥ v18) show an explicit protocol selection screen on the BMS display.
Make sure the GPS port is set to RS485 / UART and not to a GPS or 4G modem
protocol. A wrong protocol setting on the BMS side produces the exact same symptoms as
a wiring problem: Invalid header: 0x4E 0x40, corrupted sensor readings, or silence.
Screenshot from issue #841 showing the protocol selection on the BMS display:
Proposed documentation changes
Add a Troubleshooting subsection to the README under the Schematics block that
explicitly calls out the UART0 / GPIO1/GPIO3 conflict.
Add a one-liner comment to esp32-example.yaml substitutions block explaining why
GPIO16/GPIO17 is the safe default: yaml tx_pin: GPIO16 # Avoid GPIO1 (UART0/TXD) – shared with USB-UART converter and logger rx_pin: GPIO17 # Avoid GPIO3 (UART0/RXD) – shared with USB-UART converter and logger
Add a similar comment to esp8266-example.yaml and explicitly note that logger: baud_rate: 0 is not optional.
Verify that images/circuit.jpg does not show GPIO1/GPIO3 in the wiring diagram.
If it does, update the image.
Mention the BMS-side protocol selection requirement in the Schematics / wiring
section of the README.
References
JKBMS Hardware V18 #841 – Invalid header / corrupted data,
solved by switching away from UART0 and setting correct BMS protocol
Changes in fw 19.27? #875 – No data after firmware upgrade,
root cause traced to GPIO1/GPIO3 conflict with USB converter and logger
Summary
A recurring pattern across support issues (#841, #875, and others) shows that users fail to
get the UART-TTL (GPS port) connection working out of the box. Two root causes dominate:
Both issues are silent – the firmware compiles and flashes without errors, but the BMS
either stays silent or sends garbled data. Symptoms include
Invalid headererrors,wildly wrong sensor values (cell voltages at ±100 V, temperatures at 1316 °C), or
complete silence on the bus.
Affected configuration files
This issue concerns only the UART-TTL (GPS port) setup. The following files are
affected:
esp32-example.yamlesp32-example-debug.yamlesp32-example.yaml, adds UART debug outputesp32-example-multiple-devices.yamlesp8266-example.yamlesp8266-example-debug.yamlesp8266-example.yaml, adds UART debug outputesp32-ble-uart-hybrid-example.yamlDo NOT confuse with
These setups use completely different transport layers and are not affected by the
GPIO1/GPIO3 problem described here:
esp32-ble-*.yamlesp32-jk-pb-modbus-example.yaml/esp8266-jk-pb-modbus-example.yamlesp32-display-example.yaml/esp8266-display-example.yamlesp32-active-balancer-example.yaml/esp8266-active-balancer-example.yamlRoot cause
UART0 (GPIO1 = TXD, GPIO3 = RXD) is a shared resource
On virtually every ESP32/ESP8266 development board, UART0 is wired to the on-board
USB-UART bridge (CH340, CP2102, …). During normal operation this means:
Attaching the BMS to the same bus turns the connection into a three-way collision:
BMS frames, logger output, and USB converter traffic all fight on the same wire.
Platform-specific recommendations
ESP32 – use the GPIO matrix
The ESP32 contains a full GPIO matrix. Any of the three hardware UARTs (UART0, UART1,
UART2) can be routed to any GPIO. The component already defaults to GPIO16/GPIO17
(UART2), which is the right choice. Users just need to understand why they must not
change those to GPIO1/GPIO3.
The logger continues to write to UART0 (GPIO1/GPIO3) in the background, but since the
BMS is connected to UART2 (GPIO16/GPIO17) there is zero interference. No
baud_rate: 0hack is needed for the logger on ESP32.
Do not use GPIO1 or GPIO3 for the BMS connection on an ESP32.
ESP8266 – SoftwareSerial with logger disabled
The ESP8266 has only one hardware UART (UART0, GPIO1/GPIO3). There is no second hardware
UART that could be routed elsewhere. ESPHome therefore falls back to SoftwareSerial
when the configured pins differ from GPIO1/GPIO3.
SoftwareSerial at 115200 baud is tight on an 80 MHz single-core MCU. Occasional CRC
errors are expected but the connection is usable. The current example already uses
GPIO4/GPIO5. That is the correct choice.
Critically, the logger must be silenced because it would otherwise spam UART0 and
interfere even when the BMS is on different pins (the ESP8266 TXD output is always
GPIO1 unless explicitly disabled):
The current
esp8266-example.yamlalready includes this. It must stay there.BMS-side protocol selection
The JK-BMS GPS/UART port must be configured with the correct protocol. Newer firmware
versions (≥ v18) show an explicit protocol selection screen on the BMS display.
Make sure the GPS port is set to RS485 / UART and not to a GPS or 4G modem
protocol. A wrong protocol setting on the BMS side produces the exact same symptoms as
a wiring problem:
Invalid header: 0x4E 0x40, corrupted sensor readings, or silence.Screenshot from issue #841 showing the protocol selection on the BMS display:
Proposed documentation changes
explicitly calls out the UART0 / GPIO1/GPIO3 conflict.
esp32-example.yamlsubstitutions block explaining whyGPIO16/GPIO17 is the safe default:
yaml tx_pin: GPIO16 # Avoid GPIO1 (UART0/TXD) – shared with USB-UART converter and logger rx_pin: GPIO17 # Avoid GPIO3 (UART0/RXD) – shared with USB-UART converter and loggeresp8266-example.yamland explicitly note thatlogger: baud_rate: 0is not optional.images/circuit.jpgdoes not show GPIO1/GPIO3 in the wiring diagram.If it does, update the image.
section of the README.
References
solved by switching away from UART0 and setting correct BMS protocol
root cause traced to GPIO1/GPIO3 conflict with USB converter and logger