1

So i want to send this code : 01 00 14 00 58 over ModBus RTU utilizing minimalmodbus to my VIRTUAL COM Port (COM2).

So i do get the "code" but i also get other bytes before and after the code and i can seem to know where they come from and how i can resolve it.

Terminal Output Image

I did try to use another libary called pymodbus but i got the same result

PythonCode :

import serial
import minimalmodbus as mrtu
mrtu.BYTEORDER_BIG = 1
insmrt = mrtu.Instrument('COM2',1 ,mrtu.MODE_RTU,close_port_after_each_call= False,debug=True)
insmrt.precalculate_read_size= False
insmrt.clear_buffers_before_each_transaction= True
insmrt.serial.baudrate = 38400
insmrt.serial.bytesize = 8
insmrt.serial.parity = serial.PARITY_NONE
insmrt.serial.stopbits  =1
insmrt.serial.timeout = 5
insmrt.handle_local_echo = None
def inscommmand():

    #insmrt.write_string = "$0100140058"
    insmrt.write_registers(0,[0x01,0x14,0x58])
while 1:
    try:
         inscommmand()
    except:
        continue
Sunderam Dubey
  • 1
  • 11
  • 20
  • 40
kevin00756
  • 33
  • 6
  • Hello Kevin, welcome to SO. I don't think you have understood how Modbus works. When you call `write_registers()` minimalModbus creates a Modbus frame based on the registers and values you want to write. But it also needs to include other information to complete the protocol: the slave you are addressing and the checksum. Those are the *other bytes* you see. You should think exactly what you mean when you say *I want to send this code...* and ask yourself this question instead: what values do I want to write and in which register numbers should they end up? – Marcos G. Apr 22 '22 at 17:06

1 Answers1

0

I don't really know what you are trying to do or what you mean exactly by send this code by Modbus but I'm afraid what the library (minimalModbus) is doing is exactly what it is supposed to.

If you call:

insmrt.write_registers(0,[0x01,0x14,0x58])

The library will build the following Modbus frame:

01 10 0000 0003 06 0001 0014 0058 9ABE

This is what each value on this frame means:

01: The Slave Address (default is address 1)

10: The Function Code 16 (Write Multiple Holding Registers, 16 = 10 hex)

0000: The address of the first register (0000 hex = 0, +40001 offset = register #40001).

0003: Number of registers to write since you are giving a 3-element list

06: Number of data bytes that follow (3 registers x 2 bytes each = 6 bytes).

0001: Value to write to register 40001

0014: Value to write to register 40002

0058: Value to write to register 40003

9ABE: The CRC (Cyclic Redundancy Check) for error checking.

The sequence 01 00 14 00 58 is not a valid Modbus frame because there is no function code 00(only values from 1 to 6, 15, and 16 are allowed).

Maybe what you want is just to send that sequence over the serial port? Otherwise, you should think about where those values are coming from.

Marcos G.
  • 3,371
  • 2
  • 8
  • 16
  • Okay , that does make sense But let me explain why i think that i have to send it over through Modbus RTU. So i did try to send it over "RealTerm" to the Device but it didn't work with the sequence i posted here , then i tried sending it through DCON Utilities and selected Modbus RTU and tried sending the exact sequence to the device and it worked – kevin00756 Apr 25 '22 at 07:07
  • by DCON you mean with [this](https://www.icpdas.com/en/product/guide+Software+Utility_Driver+DCON__Utility__Pro)? I'm not familiar with that, if you explain how you enter the command there I might be able to understand how it works... – Marcos G. Apr 26 '22 at 14:02
  • Yes exactly i used that software to send modbus commands to my device. But you were right i was not sending Modbus sequences at all. So i tried sending the same Sequence over Coolterm as a Hex and it worked So it definitely wasn't Modbus related. – kevin00756 Apr 29 '22 at 12:04
  • glad to hear. Good luck with your projects. – Marcos G. Apr 30 '22 at 07:21