Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Us3000c pylontech rs485 connection issue, no response #42

Open
klaute opened this issue Aug 3, 2024 · 8 comments
Open

Us3000c pylontech rs485 connection issue, no response #42

klaute opened this issue Aug 3, 2024 · 8 comments

Comments

@klaute
Copy link

klaute commented Aug 3, 2024

Hello,

thank you for your library! I try to get it work, to connect to a Pylontech US3000C.

My setup:
OrangePi One with Armbian
Python 3.11
China USB to RS485 device (tried out several types)

I have set all switches of the ADD Dip switch to zero (0000). Which should be set the battery to 115200 baud.

I build two cables. One of that is a CAT7, about 8-10 meter long. I crimped a connector to it. All pins are connected to the connector on the battery side. But only pin 6,7,8 are connected to the RS485 to USB connector.

the second cable is a half meter long patch cable I cut of the second connector.

I connected it to B/RS485 and also tried out A/CAN. The pylontech documentation describes that the pin connection is the same.

In short, non of them work. I tried out different setting of the dip switch, tried out 115200 and 9600 baud.
Tried out enable/disable the CAN resistor just in case that it might change something.

In all of the videos I have seen, and threads I have read, it sounds like there is nothing more to do after you have switched on the battery. And none of them use a 120Ohm resistors.

I also tried to read the battery status using the BatteryView software on windows. But I only got an timeout message. Maybe because it require a connection to the RS232 port.

I also tried out to connect without the GND line, and exchanged pin7(A) and pin8(B) without success.

I also tried to set the ADD dip switch to 1111. but it changed nothing.

I‘m currently stuck and don’t know what else to do.

I ordered a expensive RS485 USB connector, it should be arrive today. Also I will try out to communicate to the device after 120Ohm resistors are connected.
For my heat pump (Wärmepumpe) this was required, but for the PV inverter it wasn’t.

Do you have any suggestions? An advice what to do?

In the attachment you will find a file which shows some steps that will show you the error messages of python I receive.

Also I added two „print“ calls to see if there are raw_frame data and checksums received. Which don’t.

Thank you very much in advance!

Kai

—-
protocol.txt

@Frankkkkk
Copy link
Owner

Frankkkkk commented Aug 3, 2024 via email

@klaute
Copy link
Author

klaute commented Aug 3, 2024

Hi,

sorry if I missed some important points in the other threads and the documentation!

I also measured the wires with a continuity meter. It's fine.
Below I added the documentation page I used to set up the cables.

Thank you for your fast answer!

IMG_3251
IMG_3245
IMG_3244
IMG_3247
IMG_3241

@Frankkkkk
Copy link
Owner

I'd say:

  • use the standard config: RS485 port 115200 speed, etc
  • Try to use p.get_values_single(2), or at least basic functions like p.get_protocol_version(), p.get_manufacturer_info(), p.get_system_parameters()
  • if errors, show the frame
  • try swapping A/B wires
    good luck :)

@klaute
Copy link
Author

klaute commented Aug 4, 2024

Hi, thank you for your support!

Now I have attached two 120 Ohm resistors. One at each end between A and B.
I'm still use a ceap china USB to RS485 plug.

This is the result of a p.get_values_single(2) call:

$ python3 pylontech.py
raw_frame=b'~20024600F07A11020F0CDD0CDD0CDD0CDD0CDD0CDD0CDC0CDD0CDD0CDD0CDD0CDD0CDD0CDD0CDD050BC30BAF0BAA0BAF0BBC0000C0F2FFFF04FFFF0000008DA4012110E0F7\r'
frame_chksum = b'E0F7'
Container:
NumberOfModule = 2
NumberOfCells = 15
CellVoltages = ListContainer:
3.293
3.293
3.293
3.293
3.293
3.293
3.292
3.293
3.293
3.293
3.293
3.293
3.293
3.293
3.293
NumberOfTemperatures = 5
AverageBMSTemperature = 28.0
GroupedCellsTemperatures = ListContainer:
26.0
25.5
26.0
27.3
Current = 0.0
Voltage = 49.394
Power = 0.0
CycleNumber = 0
RemainingCapacity = 36.26
TotalCapacity = 74.0
TotalPower = 0.0
StateOfCharge = 0.49

p.get_system_parameters():
raw_frame=b'~20024600B032110E420BEA0AF00D030A470384D2F0B3B0A7F80D030A47FC7CF27E\r'
frame_chksum = b'F27E'
Container:
CellHighVoltageLimit = 3.65
CellLowVoltageLimit = 3.05
CellUnderVoltageLimit = 2.8
ChargeHighTemperatureLimit = 60.0
ChargeLowTemperatureLimit = -10.0
ChargeCurrentLimit = 90.0
ModuleHighVoltageLimit = 54.0
ModuleLowVoltageLimit = 46.0
ModuleUnderVoltageLimit = 43.0
DischargeHighTemperatureLimit = 60.0
DischargeLowTemperatureLimit = -10.0
DischargeCurrentLimit = -90.0

Looks good to me!

But the other commands do not work. No raw_frame is received. Maybe I'll try to switch to an expensive USB plug.

Thank you again!

@Frankkkkk
Copy link
Owner

Great! If the other commands do not work, I don't think that another rs485 transceiver will make it better. It's possible that the pylontech protocol on US3000c batteries is different.

You can look at the protocol definition, maybe something is different for us3000 batteries ?
Cheers

@klaute
Copy link
Author

klaute commented Aug 4, 2024

You are right, another transceiver didn‘t make it better, I tried it out…

I will have a look at the protocol after vacation in a few days!

@klaute
Copy link
Author

klaute commented Aug 11, 2024

Hi,

I have read through the RS485 spec. Didn't found any US3000C specific content.
But I had to apply a little changes to your code to get it work for my single US3000C battery (I do own only one battery).
Also I have to provide the device id (2) to all of the functions, read from address/device id 0 does not work for me.

Code changes:


@@ -237,13 +243,13 @@ class Pylontech:
         return batteries
 
 
-    def get_protocol_version(self):
-        self.send_cmd(0, 0x4f)
+    def get_protocol_version(self, dev_id=0):
+        self.send_cmd(dev_id, 0x4f)
         return self.read_frame()
 
 
-    def get_manufacturer_info(self):
-        self.send_cmd(0, 0x51)
+    def get_manufacturer_info(self, dev_id=0):
+        self.send_cmd(dev_id, 0x51)
         f = self.read_frame()
         return self.manufacturer_info_fmt.parse(f.info)

Data examples I read from my battery:

p.get_manufacturer_info(2)

raw_frame=b'~20024600C04055533330303043000000010750796C6F6E2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DEFBC\r'
frame_chksum = b'EFBC'
Container: 
    DeviceName = b'US3000C\x00\x00\x00' (total 10)
    SoftwareVersion = ListContainer: 
        1
        7
    ManufacturerName = b'Pylon-----------'... (truncated, total 20)

p.get_protocol_version(2)

raw_frame=b'~200246000000FDB2\r'
frame_chksum = b'FDB2'
Container: 
    ver = b' ' (total 1)
    adr = b'\x02' (total 1)
    cid1 = b'F' (total 1)
    cid2 = b'\x00' (total 1)
    infolength = b'\x00\x00' (total 2)
    info = b'' (total 0)

p.get_module_serial_number(2)

Also work's now, after I have provided the module ID.

p.get_management_info(2)

Should also be fine:

raw_frame=b'~20024600B01402D002AFC80172FE8EC0F91C\r'
frame_chksum = b'F91C'
b'\x02\xd0\x02\xaf\xc8\x01r\xfe\x8e\xc0'
10
Container: 
    ChargeVoltageLimit = 53.25
    DischargeVoltageLimit = 45.0
    ChargeCurrentLimit = 37.0
    DischargeCurrentLimit = -37.0
    status = Container: 
        ChargeEnable = True
        DischargeEnable = True
        ChargeImmediately2 = False
        ChargeImmediately1 = False
        FullChargeRequest = False
        ShouldCharge = False
Container: 
    ChargeVoltageLimit = 53.25
    DischargeVoltageLimit = 45.0
    ChargeCurrentLimit = 37.0
    DischargeCurrentLimit = -37.0
    status = Container: 
        ChargeEnable = True
        DischargeEnable = True
        ChargeImmediately2 = False
        ChargeImmediately1 = False

p.get_values()

Still get no response.

raw_frame=b''
frame_chksum = b''

Cheers

@Geising2
Copy link

Concerning your last problem: from my point of view there is no way to get data of all batteries by using 0xff. I've translated the chinese remarks around 0xff and from my point of view (and based on my tests) its impossible. So the function get_values() is not working.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants