Mostrando las entradas con la etiqueta python. Mostrar todas las entradas
Mostrando las entradas con la etiqueta python. Mostrar todas las entradas

viernes, noviembre 18, 2016

Pymodbus3 usando puertos seriales

Estas son algunas de las lecciones aprendidas usando la librer铆a pymodbus con python 3.4 y puertos seriales en lugar de usar una conexi贸n TCP/IP.

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.



mi茅rcoles, octubre 05, 2016

Leyendo datos con pymodbus3

Uno de los protocolos m谩s populares y viejos del mundo de la automatizaci贸n industrial es Modbus. Es un protocolo sencillo que nos permite leer datos de una mir铆ada de dispositivos industriales tales como controladores de procesos, PLC's y sensores y medidores de todo tipo. Modbus ha estado ya unas cuantas d茅cadas y ha evolucionado en lo que yo llamo tres sabores principales: ASCII, RTU y TCP. Los dos primeros funcionan sobre conexiones seriales tipo RS-232, RS-422 o RS-485 y el 煤ltimo, el TCP, funciona usando Ethernet como medio de conexi贸n.

Pymodbus3 es una biblioteca, o librer铆a como tambi茅n la llamamos, de Python que nos permite usar el protocolo a alto nivel sin entrar en los detalles de programaci贸n de bajo nivel.

Supongo que si est谩n leyendo esto ya de alguna manera conocen el protocolo y saben algo de Python. As铆 que al grano. Vamos a hacer un peque帽o programa que lea datos y los escriba a alg煤n lugar, por ejemplo un archivo texto.

Lo primero es asegurarnos que tengamos Python instalado, por ejemplo python 3.4 para que sea compatible con pymodbus3. Luego instalamos pymodbus3 con pip de la manera usual.

Las primeras l铆neas del programa ser铆an algo as铆:

from pymodbus3.client.sync import ModbusTcpClient as ModbusClient

client = ModbusClient('localhost', port=502)
client.connect()

El script supone que estoy usando el protocolo ModbusTCP, por lo que el cliente en cuesti贸n estar铆a leyendo de un PLC, o servidor Modbus, ubicado en este caso en mi pc (localhost). ModbusTCP usa el puerto TCP 502, as铆 que eso es lo que significa el segundo par谩metro del constructor de la clase.

Para poder simular una conexi贸n ModbusTCP uso mod_RSsim. Este simulador si lo instale en mi pc puede emular un PLC sin problemas y me conecto v铆a el puerto 502.

Luego de creado el cliente podemos leer de esta manera.

lectura = client.read_holding_registers(450, 10)

Esto guardar铆a en la variable lectura una lista de 10 valores a partir del holding register con direcci贸n 450. Pymodbus3 tiene funciones para leer y escribir todo tipo de variables Modbus y podemos ver un ejemplo para un cliente as铆ncrono en la documentaci贸n.

Quedar铆a empaquetar el c贸digo de manera que podamos interactuar con el programa, guardar los datos en alg煤n lado y a帽adir el manejo de excepciones por si hay alg煤n problema de comunicaciones. Pero eso ser铆a materia de otro post.



Python en automatizaci贸n industrial, un caso concreto

Una de las cosas que hago para ganarme la vida es servir de consultor en automatizaci贸n industrial. Justo estaba en esos menesteres hace poco cuando me top茅 con un problema de esos a que nos tiene acostumbrados la crisis econ贸mica de nuestros golpeados clientes. Nuestro cliente en cuesti贸n sufri贸 una falla irrecuperable de un peque帽o sistema scada que ten铆an conectado a una red de controladores PLC en su planta de energ铆a. Sin el scada funcionando, sin recursos como para poner en funcionamiento el ahora muy costoso sistema de adquisici贸n de datos se vieron en la necesidad de empezar a buscar alternativas que al menos pudieran devolverles algo de la funcionalidad perdida. Y aqu铆 es donde la imaginaci贸n y tecnolog铆as libres como la de python vienen a jugar un papel importante.

El problema se centraba en leer datos a trav茅s de una interfaz serial RS-232 usando el protocolo Modbus RTU, luego guardar esos datos, o m谩s bien guardarlos solamente si alguno de esos datos cambiaba de estado, y finalmente tener alguna herramienta que pudiera analizar los datos guardados para graficar algunas cosas y hacer algunos c谩lculos de 铆ndices de mantenimiento que ten铆an que ver con las m谩quinas que controlaban los PLC.

Debido a que no eran muchos los datos a leer y a que era solamente una tabla de un solo PLC decidimos desarrollar unos scripts en python para rapidamente tener un prototipo funcional para mostrarlo al cliente.

Un rato en google y desarrollamos un ambiente de desarrollo en una laptop en windows de esta manera:
  1. instalamos python 3.4 (esta versi贸n es la que mejor funciona con todo lo que uso en este proyecto)
  2. con pip le agregamos virtualenv para crear un ambiente virtual limpio, en mi caso tengo varias versiones de python instaladas y lo m谩s sano es usar virtualenv.
  3. ya con virtualenv creamos el directorio de trabajo y activamos.
  4. instalamos pymodbus3 usando pip.
  5. instalamos tambi茅n pymongo para la base de datos usando pip
  6. finalmente instalamos PyGObject for Windows que por cierto a la fecha solamente funciona con python 3.4, por eso es que uso esta versi贸n y no la 煤ltima.
La arquitectura de mi peque帽o sistema es muy sencilla. No es m谩s que un script que interroga al PLC usando pymodbus3 y que escribe a MongoDB si detecta alg煤n cambio. En MongoDB lo que se guardar谩n son eventos, es decir documentos con la informaci贸n del estado de la variable y la fecha y hora del evento. Siendo MongoDB una base de datos NoSQL facilita la interacci贸n r谩pida con los eventos sin mucho esfuerzo.

La otra parte de la ecuaci贸n es una peque帽a aplicaci贸n que me permita leer los eventos almacenados en MongoDB y que le permita a los operadores interactuar con los datos. Hay dos caminos para hacer dicha aplicaci贸n. Pudiera ser una aplicaci贸n con una interfaz web, lo cual requiere alguito m谩s de esfuerzo en el desarrollo gr谩fico y todo eso, o pudi茅ramos usar una cl谩sica aplicaci贸n de ventanas lo cual es m谩s r谩pido. Nos decidimos por lo segundo por aquello de la rapidez.

De todos los entornos gr谩ficos de ventanas para python que hay por ah铆 el que nos parece m谩s s贸lido es el que usa Glade para desarrollar las ventanas y Gtk+ para cargarlas al script python. Hay en la red muchos tutoriales, aunque creo que el mejor es el Python Gtk+3 Tutorial. El tutorial es bastante claro sobre como usar Gtk+ primero y por 煤ltimo como usar Glade. Lo bueno es que podemos tener Glade abierto y hacer cambios en la ventana y correr el script y de inmediato ver que pas贸. Glade solamente crea un archivo xml que lo lee el script para crear los objetos que le pasar谩 a Gtk+ para que los dibuje en pantalla y maneje los eventos.

En resumen, Python ofrece un sistema r谩pido de desarrollo para problemas como el descrito. Las librer铆as de funciones son extensas y el soporte en la red por parte de los desarrolladores es bastante bueno. Los scripts desarrollados en este proyecto en particular son bastante s贸lidos, manejan todo tipo de excepciones que sabemos que pueden presentarse (como fallas de comunicaci贸n porque se rompi贸 el cable que va al PLC) y pueden modificarse en la misma planta ya que el c贸digo es abierto y un buen programador debiera poder entenderlo sin mucho problema por su gran legibilidad.

Hasta aqu铆 por hoy. Si tienen dudas p贸nganlas en los comentarios.