En primer lugar hay que saber que si uno usa pymodbus3 no hay manera de que funcione la conexi贸n al PLC usando un puerto serial. Funciona muy bien en modo TCP pero serial nada. La soluci贸n a este problema es instalar el branch python3 de pymodbus 1.2.0. Podemos bajar el archivo zip de esta p谩gina e instalarlo con pip.
Una vez hecho esto estaremos listos siempre que tengamos un dispositivo conectado a uno de nuestros puertos seriales. Si no lo tenemos podemos usar un simulador de PLC como Mod_RSSIM y un emulador de conexi贸n de puertos seriales como Com0Com. Este emulador nos crea dos puertos seriales virtuales interconectados que usaremos uno para nuestro PLC virtual y otro para nuestro programa usando pymodbus.
Ya una vez que tengamos nuestro PLC de prueba conectado y nuestros puertos seriales funcionando procedemos a programar el cliente Modbus en python.
from pymodbus.client.sync import ModbusSerialClient as ModbusClient client = ModbusClient(method='rtu', port='COM6', stopbits=1, bytesize=8, parity='N', baudrate=19200, timeout=0.4) client.connect()La primera l铆nea importa la clase que necesito de pymodbus. La segunda instancia el objeto client usando el COM6 ya que uso una m谩quina en windows y tengo este puerto libre. Los otros par谩metros que paso al constructor son el m茅todo, rtu en este caso, y las caracter铆sticas t铆picas como tasa de baudios, bit de parada y paridad. Finalmente le paso un par谩metro importante que es el timeout, este dato impacta grandemente la velocidad conque los datos son le铆dos o escritos al PLC.
Una vez instanciado client procedo a leer o escribir datos al PLC. Por ejemplo una lectura de holding registers ser铆a:
lecturas = client.read_holding_registers(10, 16, unit=0x01)Aqu铆 el programa estar铆a leyendo 16 registros a partir del registro 10. La unidad 0x01 indica la direcci贸n del PLC en caso de estar usando RS-485 y que tenga varios PLC's en la misma l铆nea. Si hay un solo PLC podemos usar 0x00 por ejemplo.
Si ponemos al programa a leer y escribir datos al PLC de manera peri贸dica lo mejor es crear un thread diferente para esta funci贸n de lectura/escritura de manera que permita que el hilo correspondiente a la interfaz de usuario corra sin trabarse. No olvidemos tampoco englobar estas lecturas/escrituras en bloques try/except para atrapar cualquier error proveniente de malas lecturas o desconexi贸n del PLC.