python communication MODBUS TCP/IP raspberry pi and HMI - write value

Antoine Potinière picture Antoine Potinière · Aug 18, 2018 · Viewed 12.1k times · Source

I'm French student and i need your help in Python for my program.

I've got a program in my rapsberry in Python which acquire datas from temperature and hygrometry sensors.

I need to communicate these values to an Human Machine Interface supervisor by the MODBUS TCP/IP PROTOCOL to display and made some graphics of these values in my HMI

The IP adress of the raspberry : 172.16.0.2
The IP adress of the HMI : 172.16.0.10

I think I need to use package like pyModbusTCP or things like that but I don't understand how to use it.

Could you help me to understand how I made the communication between my Rpi and my HMI and for example how I could write the integer value 100 at the address index 1?

Thanks for all!
Antoine

Answer

ralf htp picture ralf htp · Aug 18, 2018

MODBUS is a single-master protocol, meaning that there can only be one master, the rest of attached devices are slaves ( http://www.ni.com/white-paper/52134/en/ , similar to USB protocol, called host and device there ). In addition in MODBUS protocol a slave never starts a communications, slaves only answer to requests. Consequentially the machine on that your HMI runs has to be the MODBUS master /client ( this naming convention is a bit senseless )

For a quick general overview read this https://www.reddit.com/r/PLC/comments/7bqppu/using_raspberry_pi_as_modbus_slave_and/ and http://www.simplymodbus.ca/TCP.htm

pymodbus client / master on HMI machine

From this master / client you can send requests to the RPi ( MODBUS slave / server ) with its sensors using the following code ( if one of the sensors stores its data in a register that is presented to the bus as coil 1 by the pymodbus server that runs on the RPi, see below ). This is only an example there are other data blocks in MODBUS, namely Coils, Discrete Inputs, Input Registers, Holding Registers which of them you use depends on how you configure the MODBUS server on the RPi, normally Discrete Inputs and Input Registers are rarely used :

client = ModbusTcpClient('172.16.0.2')
client.write_coil(1, True)
result = client.read_coils(1,1)
print(result.bits[0])
client.close()

https://github.com/riptideio/pymodbus

pymodbus server / slave on Rpi

For this to work on the RPi has to run software ( pymodbus server ) that enables it as MODBUS slave / server and the sensors have to write their values into specific memory locations that are presented to MODBUS as coils / registers. How this can be done is in https://www.youtube.com/watch?v=p3Dgd0PDjnU and https://jacekhryniewicz.wixsite.com/website/raspberry-pi-with-modbus-tcp ( is a bit outdated )

In https://github.com/riptideio/pymodbus/blob/master/examples/common/asynchronous_server.py is a working example of a MODBUS server that has to run onthe RPi ( read the comments, especially the lines following # initialize your data store )

The word coils has its origin in the past of MODBUS protocol which was developed when electromechanical relays with coils were used in automation technology