1

i am looking for some help.

i already figured out how to read the Chint DDSU666 energy meter, these meters are used with modbus RTU to communicate with solar battery inverters. so i would like to mimic this type of meter to adjust charging and discharging power.

my code to read this type of meter is:

import minimalmodbus
import struct

# The minimalmodbus library uses RTU mode for Modbus communication.
# You will need to set up the serial port and baud rate to match your energy meter's settings.
instrument1 = minimalmodbus.Instrument('com4',1)
instrument1.serial.baudrate = 9600
instrument1.close_port_after_each_call = True

# Set the slave address of your energy meter
instrument1.address = 0x01


while True:
   try:
    ##Chint Meter DDSU666
        spanning = instrument1.read_float(0x2000, 3, 2)
        freq = instrument1.read_float(0x200e, 3, 2)
        stroom = instrument1.read_float(0x2002, 3, 2)
        vermogen = instrument1.read_float(0x2004, 3, 2)
        baurdrate = instrument1.read_register(0x000c, 0)



        print(spanning)
        print(freq)
        print(stroom)
        print(vermogen)
        print(baurdrate)
   except:
        print('communication lost')

now i want to write the registers above by my own data. so i need to setup an modbus RTU slave/server where the inverter can read its data.

i started with pymodbus3.1 but was not able to get anywhere.. now i am trying with modbus_tk library to setup a server.

underneath my code.

import minimalmodbus
import struct
import pymodbus
import asyncio
import modbus_tk
import modbus_tk.defines as cst
from modbus_tk import modbus_rtu
import serial
import time

modbusserver = modbus_rtu.RtuServer(serial.Serial('com4'),baudrate = 9600, bytesize=8,parity = 'N', stopbits=1, xonxoff=0)
print('start')
modbusserver.start()

slave1 = modbusserver.add_slave(1)
slave1.add_block('spanning',cst.HOLDING_REGISTERS,0x2000,250)
slave1.add_block('freq',cst.HOLDING_REGISTERS,0x200e,50)
slave1.add_block('vermogen',cst.HOLDING_REGISTERS,0x2002,3000)

could someone guide me what i need to use or what is the best option to be able to mimic this energymeter?

Thank you in advance.

tried above code to mimic the meter but not working.

1 Answers1

1

Your code has two small problems.

First: you are not giving add_block the right values. According to this those are: name, type, starting address and number of registers so you should be doing something like:

slave1.add_block('spanning',cst.HOLDING_REGISTERS,0x2000,2)
slave1.add_block('freq',cst.HOLDING_REGISTERS,0x200e,2)
slave1.add_block('vermogen',cst.HOLDING_REGISTERS,0x2002,2)

And now that you have defined your blocks you can fill them with data. But be aware that to do that you need to use raw registers. You can't just send a float because the block is expecting raw registers as a list.

To circumvent that problem, the easiest thing to do is, instead of reading floats like so:

spanning = instrument1.read_float(0x2000, 3, 2)

Just read raw registers:

spanning = instrument1.read_registers(0x2000, 3, 2) #better read raw regs
freq = instrument1.read_registers(0x200e, 3, 2)
...

That should result in a list of two registers, so then you can directly do:

slave1.set_values("spanning", 0, spanning) #note that the first time we use quotes 
                                           #but not on the second. The fist is the
                                           #name of the block and the second the 
                                           #list of values for the regs
...

Now you are ready to start your server with:

modbusserver.start()    #start your server AFTER adding blocks and setting values

Finally, it might be a good idea to add a provision to manually stop your server; otherwise, you might end up killing the task resulting in havoc. You can have a look at this answer for inspiration.

Good luck! and veel plezier.

Marcos G.
  • 3,371
  • 2
  • 8
  • 16