DEV Community

Cover image for Closed-loop comms over RS485: getting a JK BMS to talk to a Deye inverter when CAN refused to cooperate
Nodemint
Nodemint

Posted on • Originally published at nodemint.dev

Closed-loop comms over RS485: getting a JK BMS to talk to a Deye inverter when CAN refused to cooperate

If you run an off-grid solar setup, there's a moment that separates a pile of expensive components from an actual system: the inverter and the battery's BMS start talking to each other. Before that, the inverter is guessing your state of charge from voltage alone — which on a LiFePO4 pack is close to useless, because the voltage curve is famously flat. After it, the inverter reads real per-cell data, real SoC, real current limits, straight from the BMS. That's closed-loop communication, and it's the difference between a battery you babysit and one you trust.

Here's how I got there on my setup, and why the "recommended" path was a dead end.

The hardware

  • Inverter: Deye SUN-6K-SG04LP1-EU-SM2 (6kW, off-grid)
  • Pack: 16S LiFePO4, 16× EVE MB31 314Ah cells, ~16.1kWh
  • BMS: JK BMS PB2A16S30P > Tested on: Deye SUN-6K-SG04LP1-EU-SM2 — inverter protocol version 0201 (no separate software-version field on this unit) · JK BMS PB2A16S30P — hardware V19A, firmware V19.30, JK app v5.12.0 · battery protocol 014 (PYLON) · RS485 @ 9600 baud on UART1 > > Firmware matters here: BMS-to-inverter comms behavior can change between revisions, so if your versions differ from these, treat the protocol/baud combo as a starting point and confirm against your own setup.

On paper this is a well-supported combination. The Deye has a battery comms port, the JK BMS supports inverter protocols, and every guide tells you the same thing: use CAN bus, select the right protocol on the inverter, done.

Where CAN let me down

CAN is the path everyone recommends, so that's where I started. Wired the CAN lines from the BMS to the inverter's battery port, set the inverter's battery type to the matching protocol, and waited for the handshake.

Nothing. The inverter stayed in voltage-only mode, no closed-loop data, no SoC coming across. I went through the usual suspects — pinout, wiring, termination, protocol selection on both ends — and still couldn't get a stable CAN link.

If you're hitting this too: it's worth confirming the exact pinout of your Deye revision's battery port against your BMS, because the silkscreen and the manual don't always agree, and CAN is unforgiving about which pair you land on.

At some point you have to make a call: keep chasing the recommended path, or switch to the one that works. I switched.

What actually worked: RS485, protocol 014, 9600 baud

The JK BMS exposes more than one comms route, and the Deye speaks several battery protocols. The combination that brought the link up for me was:

  • RS485 (not CAN), on UART1 of the BMS
  • Protocol 014 on the Deye — this is the PYLON protocol
  • Baud rate 9600 The moment that lined up, the inverter switched out of voltage-guessing mode and started reading the BMS directly: SoC, pack voltage, current, and the charge/discharge limits the BMS was advertising. Closed loop, finally.

A few things worth knowing if you're doing the same:

  • Pick the right UART. The JK has multiple ports, and they aren't interchangeable for this. UART1 was the one that carried the inverter protocol cleanly for me.
  • Match the baud exactly. 9600 for the PYLON protocol. A baud mismatch gives you the same silent failure as a wiring fault, which is what makes this hard to diagnose — everything looks connected.
  • Protocol number is the whole game. On the Deye, the protocol selector is just a number. 014 = PYLON. Choosing the wrong one means the inverter is speaking fluent nonsense at a BMS that's listening in a different language. ## Why bother

With closed-loop comms running, the inverter stops over- or under-charging based on a voltage curve that barely moves between 20% and 80%. It respects the BMS's actual current limits, which matters a lot for cell longevity, and it reports an SoC you can trust on the dashboard. For a pack I'm planning to keep healthy for 20 years on an 80% depth-of-discharge strategy, that accuracy isn't a nicety — it's the whole point.

The takeaway

The recommended path isn't always the one that works. CAN is the default advice for a reason, but when it won't come up and you've exhausted the wiring and pinout checks, RS485 with the correct protocol and baud is a completely valid — and often more forgiving — fallback. On a Deye + JK BMS pairing, protocol 014 (PYLON) over RS485 at 9600 baud on UART1 is the combination I'd reach for first next time.


I'm building Nodemint — software, with a hardware-adjacent streak. If you're working on solar monitoring, embedded comms, or anything in this space, get in touch.

Top comments (0)