Modbus RTU Server

Hello.

I am designing a panel that captures data from a sensor (temperatures, pressures, and vibrations), and this panel is capable of displaying all the information on the screen. However, now I need to make this panel an RTU Server through the RS485 serial port in order to deliver all this information to a telemetry system (SCADA).

In this I have more or less about 6 months investigating and trying to solve this problem without success. The available libraries or nodes only allow me to create TCP / IP servers, but none allow me to create an RTU server.

For this reason, I think it is time to look for other alternatives. I also tried to solve this problem using Python (modbus-tk library). This library does allow me to create the RTU server, but it does not work well, when it consults the panel data, CRC errors or framing errors always appear. Sometimes I manage to survey all the data in the logs.

Also tried to use this node:

image

But it doesn't work, it generates an error saying that it can't open the port. I am clear how to use the ports, however with this node I have not succeeded.

I would like to read some new opinions on this topic, I see that in the forum and in general on the internet nobody explains a single example of how a Modbus RTU server can be made.

Unfortunately in my case, it has to be RTU Server via RS485. I don't need a TCP server, I have already a TCP server working with modbus-tk library and it's respective python code and works ok.!

Captura1|625x500

Thanks for your comments in advance.

1 Like

So. Are all these sensors to be connected to a plc? If so, what PLC? There are many contrib nodes on here that talk to PLCs.

What do you mean by "this panel". Is that a PC screen with node-red running a Dashboard? Or a dedicated HMI?
Why must you make "this panel" an RS485 RTU server to send data to a SCADA?
What SCADA are you using?

Hi Steve.

I am working on a NanoPC-T4 (FriendlyArm) with "FriendlyCore" operating system.

When I refer to the panel, it is the entire set of components integrated into the NanoPC-T4 (sorry my engles is not entirely good, therefore I support myself with the google translator).

I have a USB-RS232 / 485 / TTL (Waveshare) converter connected to one of the NanoPC-T4 ports. It is identified in the system as / dev / ttyUSB2. Up to this point everything is fine.

The problem is that when I run the program to maintain a service that gives me the data in this converter, said data to be consulted is lost very often, sometimes it is not even delivered for hours.

I share with you the program I am running for the "Slave Server RTU":

#----------------------------------------------------------------------------------------------------------
#!/usr/bin/env python

-- coding: utf_8 --

import sys
#add logging capability
import logging
import threading
import random
import time
import modbus_tk
import modbus_tk.defines as cst
import modbus_tk.modbus as modbus
import modbus_tk.modbus_rtu as modbus_rtu
import serial
import db
dbo = db.DB()

logger = modbus_tk.utils.create_logger(name="console", record_format="%(message)s")

Initial configuration

PARAMETERS = dbo.buscar("SELECT value FROM config where (parameter = 'MODBUS_SLAVE_PORT') OR (parameter = 'MODBUS_SLAVE_BAUDRATE') OR (parameter = 'MODBUS_SLAVE_DATABIT') OR (parameter = 'MODBUS_SLAVE_PARITY') OR (parameter = 'MODBUS_SLAVE_STOPBIT') OR (parameter = 'MODBUS_SLAVE_NUMBER') ")
PORT_RS485 = str(dbo.get_config("MODBUS_SLAVE_PORT"))
BAUDRATE_RS485 = int(dbo.get_config("MODBUS_SLAVE_BAUDRATE"))
DATABIT = int(dbo.get_config("MODBUS_SLAVE_DATABIT"))
MODBUS_PARITY = str(dbo.get_config("MODBUS_SLAVE_PARITY"))
MODBUS_STOPBIT = int(dbo.get_config("MODBUS_SLAVE_STOPBIT"))
MODBUS_SLAVE_NUMBER = int(dbo.get_config("MODBUS_SLAVE_NUMBER"))

print str(PORT_RS485) + " " + str(BAUDRATE_RS485) + " " + str(MODBUS_PARITY) + " " + str(MODBUS_STOPBIT) + " "

if name == "main":
#Create the server
server = modbus_rtu.RtuServer(serial.Serial(PORT_RS485, BAUDRATE_RS485, bytesize= DATABIT, parity=MODBUS_PARITY, stopbits=MODBUS_STOPBIT, xonxoff=0))

try:
logger.info("running...")
logger.info("enter 'quit' for closing the server")

server.start()
time.sleep(1)

#Definir numero de Esclavo

slave_1 = server.add_slave(MODBUS_SLAVE_NUMBER)
slave_1.add_block("a", 3, 0, 20)

sutvar = []

while 1:

    PARAMETERS2 = dbo.buscar("SELECT value FROM config where (parameter = \'MODBUS_SLAVE_PORT\') OR (parameter = \'MODBUS_SLAVE_BAUDRATE\') OR (parameter = \'MODBUS_SLAVE_DATABIT\') OR (parameter = \'MODBUS_SLAVE_PARITY\') OR (parameter = \'MODBUS_SLAVE_STOPBIT\') OR (parameter = \'MODBUS_SLAVE_NUMBER\') ")
    if(PARAMETERS == PARAMETERS2):

        
        sql2 = dbo.buscar("SELECT PIPVAR, PDVAR, TIVAR, TMVAR, VXYVAR, VZVAR, CTVAR, VTVAR, DELTAP, ISOLATION, RELAY1, RELAY2, RELAY3, FIRMWARE, PIPPSI, PDPSI, TIPSI, TMPSI FROM LASTDATA where TIMESTAMP = \'1\'")

        sutvar = [sql2[0][0],sql2[0][1]]  #,sql2[0][2],sql2[0][3],sql2[0][4],sql2[0][5],sql2[0][6],sql2[0][7],sql2[0][8],sql2[0][9],sql2[0][10],sql2[0][11],sql2[0][12],sql2[0][13],sql2[0][14],sql2[0][15],sql2[0][16],sql2[0][17]
        print sutvar

        #vxyvar = sql2[0][4]

        #sql6 = "UPDATE WDT set WDT1=\'" + str(vxyvar) + "\'  "
        #dbo.ejecutar(sql6)

        #Tabla modbus estandar:
        slave_1.set_values("a", 0, sutvar)

        time.sleep(5)

    else:

        server.stop()
        time.sleep(1)
        print "Cambio la Configuracion"
        PORT_RS485 = str(dbo.get_config("MODBUS_SLAVE_PORT"))
        BAUDRATE_RS485 = int(dbo.get_config("MODBUS_SLAVE_BAUDRATE"))
        DATABIT = int(dbo.get_config("MODBUS_SLAVE_DATABIT"))
        MODBUS_PARITY = str(dbo.get_config("MODBUS_SLAVE_PARITY"))
        MODBUS_STOPBIT = int(dbo.get_config("MODBUS_SLAVE_STOPBIT"))
        MODBUS_SLAVE_NUMBER = int(dbo.get_config("MODBUS_SLAVE_NUMBER"))
        server = modbus_rtu.RtuServer(serial.Serial(PORT_RS485, BAUDRATE_RS485, bytesize= DATABIT, parity=MODBUS_PARITY, stopbits=MODBUS_STOPBIT, xonxoff=0))
        server.start()
        slave_1 = server.add_slave(MODBUS_SLAVE_NUMBER)
        slave_1.add_block("a", 3, 0, 20)
        PARAMETERS = PARAMETERS2

except Exception, err:
print "Error sending data to the display"
pass

finally:
server.stop()

Hi, so I have a few questions - they may help direct you (or direct someone else to help you)

  • what does any of this have to do with node-red?
    • the code you have posted is python. are you running the python from inside node-red?
  • Why are you using Modbus RTU
    • is it to access the sensors? or to communicate to node-red?
  • What SCADA are you using? iFIX? Cimplicity? RSView? Other?
    • Or do you mean node-red is your SCADA?

I made this diagram for better understanding:

And this morning I implement this possible solution, but it not the idea because IT implies more $$$:

hi, you didnt really answer any of my questions from the previous post :frowning:

More questions...
Are you really considering a Windows PC based program MbPoll as a SCADA? node-red has a beautiful dashboard you could use!

A few things that I dont understand.

  • Why are you using modbus RTU at all? ( I certainly wouldn't be considering USB to Serial in an industrial setting) - There are many Ethernet based data acquisition components available (quick example).

  • Where does node-red fit ?

  • If you MUST use modbus - why serial (RTU) and not Modbus TCP? then you would not need any USB->Serial components at all!

Hi Steve. I'm really not very good using Red Node. I'm just trying to make this app on Node Red because I don't know of any other programming platform like this. I didn't know that I can use Red Node instead of ModbusPoll. Can you give me more details on this point?

  • what does any of this have to do with node-red?
    R.- Because all the interface I have done in Node network, however I have not been able to make an RTU Server with any library or Node-network node.

    • the code you have posted is python. are you running the python from inside node-red?
      R.- Yes, I am running the python from inside node-red.
  • Why are you using Modbus RTU

    • is it to access the sensors? or to communicate to node-red?
      R.- The STU PCB only have RS485 Modbus Port. We have also been asked to include a Modbus RTU RS232 / 485 port in the system.

If you MUST use modbus - why serial (RTU) and not Modbus TCP? then you would not need any USB->Serial components at all!
R.- They ask me to include both options.

Where does node-red fit ?
R.- I did all the programming of the panel in Node-red, so I thought that all these Modbus communication requirements could be solved with nodes, such as:
node-red-contrib-modbus

Well I will start by saying - you can do A LOT in node-red.
If you start writing python you will lose that flexibility.

You should probably aim to get data into an MQTT broker and instead of providing a Modbus interface to the user, present a nice dashboard & an Ethernet connection where they can get values from the broker.

ok - I understand this - however your first post was a whole bunch of python (not NODE)

It might be the customer is not aware of better options.

In my opinion, this could be simplified greatly...

  • NanoPC-T4
    • run node-red
      • access data from the Ethernet based data acquisition
      • provide a dashboard
    • run an MQTT broker (mosquito)
  • a local network switch (cheap / non managed)
  • Ethernet based data acquisition

Thats it. No serial, no USB converters.

customer gets access to all variables in the broker.

With node-red, you can even provide the customer REST endpoints (like http://NanoPC/getdata) or OPCUA access to data (by using OPCUA nodes)

If you have to, you can even have node-red run as a Modbus-TCP server to provide even more client connectivity.

Final words...

The things I describe above are something I could develop a PROOF of CONCEPT in about 3 days.
Perhaps (depending on complexity) an 80% complete DEMO in about 2 weeks.
However, if you need to learn everything it will take you more like 5 ~ 10 weeks. BUT it is all possible to do.

Oh, and MQTT takes about 20 minutes to learn (it is very easy and you will gain so much capability and flexibility for your 20 minutes)


Start here to get an idea of how easy this all is...

Watch all the videos (will take you about 30 minutes) - definitely worth it.

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.