UNIVERSIDAD TECNOLÓGICA DE SAN JUAN DEL RÍO MANUAL DEL PROTOCOLO MODBUS EMPRESA

48
UNIVERSIDAD TECNOLÓGICA DE SAN JUAN DEL RÍO INNOVACIÓN PARA EL DESARROLLO REPORTE MANUAL DEL PROTOCOLO MODBUS EMPRESA: COMPRESIÓN BAJÍO. PRESENTA: DEL ÁNGEL PÉREZ CARLOS ALFREDO. ASESOR EMPRESA ASESOR TÉCNICO ING. RAFAEL MARTINEZ LIC. JAQUELINA ADRIANA TREJO OCAMPO. MARTÍNEZ. SAN JUAN DEL RÍO, QRO. AGOSTO 2014.

Transcript of UNIVERSIDAD TECNOLÓGICA DE SAN JUAN DEL RÍO MANUAL DEL PROTOCOLO MODBUS EMPRESA

UNIVERSIDAD TECNOLÓGICA DE SAN JUAN DEL RÍO

INNOVACIÓN PARA EL DESARROLLO

REPORTE

MANUAL DEL PROTOCOLO MODBUS

EMPRESA:

COMPRESIÓN BAJÍO.

PRESENTA:

DEL ÁNGEL PÉREZ CARLOS ALFREDO.

ASESOR EMPRESA ASESOR TÉCNICO

ING. RAFAEL MARTINEZ LIC. JAQUELINA ADRIANA TREJO

OCAMPO. MARTÍNEZ.

SAN JUAN DEL RÍO, QRO. AGOSTO 2014.

1

INDICE

PROTOCOLO MODBUS ........................................................................................................................ 2

1.- SISTEMA DE NUMERACIÓN HEXADECIMAL. .................................................................................. 2

1.1.- Conversión de decimal a hexadecimal. ................................................................................... 3

1.2.- Conversión de hexadecimal a decimal. ................................................................................... 4

2.- Punto flotante ................................................................................................................................ 4

2.1.- Estándar IEEE-754 para representación de punto flotante. ................................................... 5

2.2.- Precisión simple. ..................................................................................................................... 5

2.3.- Precisión doble ........................................................................................................................ 7

3.- Comunicación serial. ...................................................................................................................... 8

3.1. Transmisión de información de forma serial. ........................................................................ 10

3.2.- Bit de datos. .......................................................................................................................... 10

3.3.- Bit de inicio (start) y bit de paro (stop). ................................................................................ 11

3.4.- Bit de paridad. ....................................................................................................................... 12

3.5.- Velocidad de transmisión. ..................................................................................................... 12

4.- Protocolos de comunicación serial. ............................................................................................. 13

4.1.- RS-232 (Estándar ANSI/EIA-232). .......................................................................................... 13

4.2.- RS-422 (Estándar EIA RS-422-A). ........................................................................................... 14

5.- RS-485. ......................................................................................................................................... 14

5.1.- Comunicación RS-485 a cuatro hilos (full-duplex). ............................................................... 14

5.2.- Comunicación RS-485 a dos hilos (half-duplex). ................................................................... 15

6.- Protocolo ModBus ....................................................................................................................... 17

6.1.- Modos de Transmisión del MODBUS .................................................................................... 17

6.2.- Almacenamiento de datos en ModBus estándar. ................................................................. 18

6.3.- Función ModBus o código de operación. .............................................................................. 20

6.3.1.- Descripción detallada de los comandos ............................................................................. 21

6.3.2.- Respuestas de excepción ModBus. .................................................................................... 44

2

PROTOCOLO MODBUS

En este manual explicaremos lo que es el protocolo de comunicación ModBus, pero para

poder entender mejor el funcionamiento y el desarrollo de este es necesario conocer

algunos conceptos:

Sistema hexadecimal.

Punto flotante.

Comunicación serial.

Comunicación RS-485.

1.- SISTEMA DE NUMERACIÓN HEXADECIMAL.

Es un sistema de base 16. Igual que en el sistema decimal, cada vez que teníamos 10

unidades de un determinado nivel, obteníamos una unidad del nivel superior (diez

unidades: una decena, diez decenas: una centena, etc.) en el hexadecimal cada vez que

juntamos 16 unidades de un nivel obtenemos una unidad del nivel superior. En un sistema

hexadecimal debe haber por tanto 16 dígitos distintos.

Como solo disponemos de diez dígitos (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) necesitamos ampliar esa

cantidad y se hace mediante letras, con la siguiente relación en sistema decimal:

Hexadecimal Decimal Hexadecimal Decimal

A 10 D 13

B 11 E 14

C 12 F 15 Tabla 1.- Valores decimal-hexadecimal

Este sistema de numeración es muy utilizado en informática porque simplifica la expresión

binaria de los objetos. En informática se utiliza el byte como unidad básica de información.

Un byte está compuesto de 8 bits, es decir, un conjunto de ocho ceros y/o unos, con un byte

se puede codificar desde el hasta el . Es decir:

= + + + + + + + = 0

= 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 = 128 + 64 +32 +

16 +8 + 4 + 2 + 1 = 255

3

Por lo tanto con un byte podemos comparar los sistemas: hexadecimal, decimal y binario

para que veamos la ventaja de utilizar menor cantidad de dígitos.

Decimal Binario Hexadecimal Decimal Binario Hexadecimal

0 0000 0 8 1000 8

1 0001 1 9 1001 9

2 0010 2 10 1010 A

3 0011 3 11 1011 B

4 0100 4 12 1100 C

5 0101 5 13 1101 D

6 0110 6 14 1110 E

7 0111 7 15 1111 F Tabla 2.- Valores binario-decimal-hexadecimal.

1.1.- Conversión de decimal a hexadecimal.

Como en los restantes sistemas de numeración, la forma de pasar a hexadecimal es

dividiendo entre la base del sistema, en este caso 16. Veamos un ejemplo:

=????

Entonces 7059 lo dividimos entre la base, en este caso 16.

Entonces 7059/16=441.1875

Solo debemos tener en cuenta el número entero, el cociente de la división es lo que nos hará

formar parte de la conversión, en este caso es 3, seguimos dividiendo ahora 441/16 y asi

sucesivamente de tal manera que quede así:

7059/16 Cociente

441/16 3

27/16 9

1/16 B

0/16 1 Tabla 3.- Ejemplo de conversión hexadecimal-decimal.

Para formar el número hexadecimal tomamos los cocientes de las divisiones

acomodándolos de derecha a izquierda empezando desde el número de abajo hacia arriba:

4

1.2.- Conversión de hexadecimal a decimal.

El paso contrario consiste en escribir el hexadecimal como potencias de base 16 y calcular. En esta

ocasión hay que sustituir las letras que haya por su equivalente valor decimal.

Por ejemplo, convertir 3AF en decimal.

El número sería:

2.- Punto flotante

En 1985, el IEEE (Institute of Electrical and Electronics Engineers) publicó la norma IEEE

754. Una especificación relativa a la precisión y formato de los números de “punto

flotante”. Incluye una lista de las operaciones que pueden realizarse con dichos números.

Muchas aplicaciones requieren trabajar con números que no son enteros. Existen varias

formas de representar números no enteros. Una de ellas es usando un punto o coma fijo.

Este tipo de representación ubica siempre el punto o coma en alguna posición a la derecha

del digito menos significativo.

Otra alternativa comúnmente usada es la que se conoce como representación en punto

flotante. Bajo este esquema, un número puede ser expresado mediante un exponente y una

mantisa. Por ejemplo el número 10.75 puede ser expresado como:

10.75 X 1.075 X mantisa exponente

Para poder representar un número en punto flotante se necesita:

El signo del número.

El signo del exponente.

Dígitos para el exponente.

Dígitos para la mantisa.

Dado que un número en punto flotante puede expresarse de distintas formas que son

equivalentes, es necesario establecer una única representación. Es por ello que se trabaja

con números normalizados.

5

Decimos que un número está normalizado si el digito a la izquierda del punto o coma está

entre 0 y la base (0< digito a la izquierda del punto <b). En particular, decimos que un

número binario está normalizado si el digito a la izquierda del punto es igual a 1.

1.00 X Normalizado

0.01 X No normalizado

2.1.- Estándar IEEE-754 para representación de punto flotante.

Este estándar se desarrolló para facilitar la portabilidad de los programas de un procesador

a otro y para alentar el desarrollo de programas numéricos sofisticados.

Este estándar se ha sido ampliamente adoptado y se utiliza prácticamente en todos los

procesadores y coprocesadores aritméticos actuales. El estándar IEEE define el formato

para precisión simple de 32 bits y para precisión doble de 64 bits.

2.2.- Precisión simple.

El formato para los números de precisión simple es de 32 bits.

Signo Exponente con signo Mantisa

1 8 23

La representación de un número en precisión simple en el formato IEEE-754 consta de las

siguientes partes:

Signo: se encuentra en el bit más significativo. De manera que si hay un “1” es negativo

pero si se encuentra un “0”.

Exponente con signo: Está conformado por los siguientes ocho bits. Esta ubicación del

exponente en la palabra facilita las comparaciones de números.

Si los números se encuentran normalizados, comparamos los exponentes. Si son iguales

pasamos a comparar las mantisas. Pero si hacemos las comparaciones con números

negativos y positivos se hará una confusión debido a que los negativos se parecerían más

grandes que los positivos como por ejemplo: “11111111” esto es igual a -1, para

demostrarlo utilizaremos lo que es el complemento a 2, que consiste en cambiar todos los

“1’s” por “0’s” y viceversa después se le suma un 1 a todo el byte:

11111111 Se cambia 1’s por 0000000

6

0’s

Se le suma un 1 a todo el byte 00000000 + 1

00000001

De igual manera si se quiere pasar un número positivo a negativo se usa el mismo método.

Es importante tener en cuenta de que el valor negativo es el mismo que el positivo, es decir

el uno que utilizamos en el ejemplo anterior convertido a negativo es igual a menos 1. Ya

explicado cómo funciona el complemento a 2 seguiremos con la explicación de las

comparaciones, para evitar las confusiones entre números positivos y negativos se utiliza

una representación en exceso N de forma que el exponente más negativo posible queda en

“00000001” y el más grande de los positivos en “11111110”

El estándar IEEE 754 usa como exceso 127 para precisión simple:

Exponente más negativo representable:

X+127=0000 0001

X=-126

Exponente más grande representable:

X+127=1111 1110

X=127

Mantisa: Está formado por el resto de los bits (23). Como los números se representan de

manera normalizada entonces siempre tendremos un uno a la izquierda del punto. Por lo

tanto este digito no es necesario almacenarlo en la palabra y se tiene de manera implícita: la

mantisa consiste en 24 bits de precisión.

Bien ahora para dejar más claro todo utilizaremos un ejemplo para demostrar lo ya visto,

para ello representaremos según el estándar de coma o punto flotante el 21:

Primero convertimos el 21 en número binario.

Lo siguiente es poner el punto flotante después del uno que se encuentre en el bit más

significativo.

7

1.0101

Al igual que hacemos en sistema decimal colocamos la base a la que se representa, es decir

el número de dígitos al que se recorrió el punto, pero utilizando como base el sistema

actual.

1.0101 *

Ya tenemos el signo, que es positivo lo que equivale a un “0” tenemos la mantisa, que es el

valor después del punto o coma flotante, lo que falta es tener el exponente para obtenerlo

solamente sumamos el exceso a N, y como recordaremos la norma trabaja con 127,

entonces:

4+127 = 131

Convertido a binario.

131 = 1000 0011

Y de esta manera obtenemos el exponente ya con el exceso, teniendo el número

normalizado de la siguiente manera:

0 10000011 01010000000000000000000

Signo Exponente en exceso Mantisa

Como se puede observar la mantisa solo estaba formada por cuatro dígitos, entonces lo que

se hace es rellenar con ceros el total de bits recordando que la mantisa está compuesta por

23.

2.3.- Precisión doble

La representación de un número en precisión doble en el formato IEEE-754 consta de las

siguientes partes:

Signo: Se encuentra en el bit más significativo

Exponente en exceso: Está conformado por los siguientes 11 bits. Se utiliza una

representación en exceso 1023 de forma que el exponente más negativo posible queda en

000 0000 0001 y el más grande de los positivos en 111 1111 1110.

Mantisa: Está formado por 52 bits más el bit implícito (53).

8

Signo Exponente con signo Mantisa

1 bit 11 bits 52 bits.

3.- Comunicación serial.

La comunicación serial es un protocolo muy común (no hay que confundirlo con el Bus

Serial de Comunicación, o USB) para comunicación entre dispositivos que se incluye de

manera estándar en prácticamente cualquier computadora.

El concepto de comunicación serial es sencillo. Consiste en él envió secuencial de un bit a

la vez de información entre dos o más dispositivos. Se sabe que esta forma de

comunicación es lenta si la comparamos con la comunicación en paralelo, que permite la

transmisión de un byte completo por vez, este método de comunicación es más sencillo

pero tiene la desventaja que la longitud de cables entre dispositivos no puede ser mayor a

20 metros, esto por la especificación IEEE 448, al contrario que la serial que permite hasta

1200 metros de distancia, de manera que implica que para la transmisión de datos es

necesario un solo cable entre los dispositivos y una referencia o tierra.

Fig. 3.1.- representación simple de la comunicación.

Como se puede observar en la imagen, la señal es por solo un cable, lo que implica que solo

halla dos valores, denotados en electrónica digital por un 1 o un 0, pero si se hace de esta

manera no hay forma que el dispositivo 2 regrese información al dispositivo 1, obviamente

es mejor la transmisión con dos cables.

9

Fig. 3.2.- Representación de comunicación con dos cables.

Así de esta forma es posible transmitir de forma serial los datos del dispositivo 1 al

dispositivo 2 y viceversa. Entonces, la comunicación serial utiliza tres líneas de

transmisión: (1) Tierra (o referencia), (2) Transmitir, (3) Recibir. El transmisor es el cable

que envía los datos a otro dispositivo, generalmente se representa como Tx, y el otro cable

es el receptor que se le representa con Rx, y es el encargado de recibir la información.

Tx (Manda)

Rx (Recibe)

Fig. 3.3.- representación de la comunicación Tx y Rx.

Como se puede observar en la imagen el transmisor (Tx) de un dispositivo se conecta al

receptor (Rx) del otro, los datos que se envían de un dispositivo a otro es un bit a la vez,

juntos esos bits forman datos. Para cada línea de datos solo hay dos posibles valores y es

que el dato enviado es un “0” o es “1”.

Es importante mencionar que si se quiere el correcto funcionamiento de la transmisión de

unos y ceros los dos dispositivos deben de tener las siguientes características iguales:

10

Los bits de datos

Bits de paridad

Bits de inicio (start) y paro (stop)

Velocidad de transmisión.

3.1. Transmisión de información de forma serial.

Serialmente podemos enviar cualquier dato, por ejemplo: enviar la letra “A” de un

dispositivo a otro, cuando son letras las que se envían generalmente se usa el código ASCII

de la letra, en este caso tenemos la letra “A” entonces en el código ASCII le corresponde es

el 65, que convertido a código binario (unos y ceros) es “1000001”, entonces para enviar la

letra “A” se envía una trama de bits, tal y como se muestra en la siguiente figura:

Fig. 3.4.- Trama de información enviada.

Notas:

1. Se envía siempre, del bit menos significativo al bit más significativo.

2. Él envió de datos es a una velocidad previamente establecida por los dispositivos.

De esta forma se puede enviar información, de cualquier tipo, ya sea letras, números y

caracteres. Se puede enviar el código ASCII de una letra seguida de otra y así

sucesivamente.

3.2.- Bit de datos.

Esto se refiere a la cantidad de bits que se están transmitiendo. Las cantidades más comunes

que se envían por paquete son de 5,7 y 8 bits. El número de bits que se envían dependen del

tipo de información que se está transmitiendo. En el ejemplo anterior se colocó un cero

después del bit más significativo debido a que el código ASCII trabaja generalmente con 8

bits y como la letra “A” solo contiene 7 bits se usó el cero para completar el bloque de

datos. Un paquete se refiere a una transferencia de byte, incluyendo los bits de

11

inicio/parada, bits de datos, y paridad. Debido a que el número actual de bits depende en el

protocolo que se seleccione, el término paquete se usar para referirse a todos los casos.

3.3.- Bit de inicio (start) y bit de paro (stop).

A la trama de 8 bits que envía datos siempre se agregan dos bits más, uno al inicio y otro al

final, esto con la finalidad de indicarle al receptor cuando inicia el dato (bit de start) y

cuando termina (bit de stop). Los valores más típicos para el bit de paro son 1, 1.5 o 2 bits.

Debido a que los dos dispositivos llegan a tener una pequeña diferencia de tiempo esto es a

consecuencia de que cada uno de ellos tiene su propio reloj. Por lo tanto, los bits de parada

no sólo indican el fin de la transmisión sino además dan un margen de tolerancia para esa

diferencia de los relojes. Mientras más bits de parada se usen, mayor será la tolerancia a la

sincronía de los relojes, sin embargo la transmisión será más lenta.

La representación del bit de inicio es con un “0” y el bit de paro es con un “1”, de esta

manera los dispositivos saben reconocer cual es el bit “stop” y cual el “start”, para ilustrar

esto utilizaremos el ejemplo anterior de la letra “A”:

Fig. 3.5.- trama de datos con bit de inicio y paro.

Siempre que se envíen datos generalmente llevan este formato, por ejemplo si se envía la

palabra “HOLA” serialmente seria de la siguiente manera:

12

Fig. 3.6.- Palabra “HOLA” enviada por comunicación serial.

Como se puede observar en la imagen para cada letra se pone un bit de start y un bit de

stop.

3.4.- Bit de paridad.

La paridad es una forma sencilla de verificar si hay errores en la transmisión serial. Existen

cuatro tipos de paridad: par, impar, marcada y espaciada. La opción de no usar paridad

alguna también está disponible.

Entonces el bit de paridad sirve para la detección de errores, haciendo un total de bits cuyo

valor sea 1 en par o impar. Ejemplo:

Si enviamos este código: “0101100” podemos observar que el total de 1’s (unos) es tres

pero si estamos trabajando con paridad par entonces le agregamos un “1” más para poder

hacer que el total de 1’s sea par.

Fig.3.7.- Bit de paridad.

El bit de paridad puede ir al inicio o al final del código dependiendo del diseño del sistema,

de igual manera este puede funcionar con paridad par o impar, pero solo puede ser con una,

no con las dos al mismo tiempo.

3.5.- Velocidad de transmisión.

Debemos de tener en cuenta que la velocidad a la que se envían los bits serialmente, ya que

es de suma importancia que ambos dispositivos deben de tener la misma velocidad para

13

transmitir y recibir bits, de lo contrario simplemente la transmisión serial no sería la

correcta.

La velocidad de transmisión o también llamada “Baud rate” indica el número de bits por

segundo que se transfieren, y se mide en baudios (bauds). Por ejemplo, 300 baudios

representan 300 bits por segundo. Cuando se hace referencia a los ciclos de reloj se está

hablando de la velocidad de transmisión. Por ejemplo, si el protocolo hace una llamada a

4800 ciclos de reloj, entonces el reloj está corriendo a 4800 Hz, lo que significa que el

puerto serial está muestreando las líneas de transmisión a 4800 Hz. Algunas velocidades de

transmisión que son muy usadas son: 1200, 2400, 9600 y 19200.

4.- Protocolos de comunicación serial.

Para poder hacer la comunicación serial hay varios protocolos por los cuales se puede hacer como:

el RS-232, RS-422 y el RS-485, pero como estamos enfocándonos al ModBus entonces nos

concentraremos al protocolo por el cual trabaja el RS-485, pero dando una pequeña explicación de

los otros dos.

4.1.- RS-232 (Estándar ANSI/EIA-232).

Es el conector serial hallado en las PC’s IBM y compatibles. Es utilizado para una gran

variedad de propósitos, como conectar un ratón, impresora o modem, así como

instrumentación industrial. Gracias a las mejoras que se han ido desarrollando en las líneas

de transmisión y en los cables, existen aplicaciones en las que se aumenta el desempeño de

RS-232 en lo que respecta a la distancia y velocidad del estándar. RS-232 está limitado a

comunicaciones de punto a punto entre los dispositivos y el puerto serial de la

computadora. El hardware de RS-232 se puede utilizar para comunicaciones seriales en

distancias de hasta 50 pies.

Pines del conector DB-9

--------------

\ 1 2 3 4 5 /

\ 6 7 8 9 /

---------

Funciones de los pines en RS-232:

14

Datos: TXD (pin 3), RXD (pin 2)

Handshake: RTS (pin 7), CTS (pin 8), DSR (pin 6), DCD (pin 1), DTR (pin 4)

Tierra: GND (pin 5)

Otros: RI (pin 9)

4.2.- RS-422 (Estándar EIA RS-422-A).

Es el conector serial utilizado en las computadoras Apple de Macintosh. RS-422 usa

señales eléctricas diferenciales, en comparación con señales referenciadas a tierra como en

RS-232. La transmisión diferencial, que utiliza dos líneas para transmitir y recibir, tiene la

ventaja que es más inmune al ruido y puede lograr mayores distancias que RS-232. La

inmunidad al ruido y la distancia son dos puntos clave para ambientes y aplicaciones

industriales.

5.- RS-485.

Es un protocolo de comunicación serial, qué a la fecha es un estándar, es usado como

sistema de interconexión entre dispositivos a grandes distancias y funciona en ambientes

eléctricamente ruidosos sin problema alguno. Existen dos opciones para crear una red RS-

485:

Usando 4 cables, llamada en ingles full-duplex.

Usando 2 cables, llamada half-duplex.

A continuación se detallarán cada una de ellas:

5.1.- Comunicación RS-485 a cuatro hilos (full-duplex).

Como se vio que dos dispositivos pueden comunicarse serialmente usando dos cables Rx y

Tx, para poder hacer la comunicación full-duplex solo basta con agregar un dispositivo

electrónico llamado transceptor (transceiver) para protocolo RS-485. Este chip es un

dispositivo que cuenta con un transmisor y un receptor que comparten parte de la circuitería

o se encuentran dentro de la misma caja y manejan los niveles de voltaje requeridos en la

especificación que se definió para el protocolo RS-485.

Como se puede observar, el transceptor se conecta a las terminales Tx y Rx de un

dispositivo serial, para así tener lista la conexión RS-485 a 4 hilos.

15

Fig. 5.1.- Transmisión a 4 hilos.

Ahora si bien conectamos dos dispositivos utilizando lo que denominamos como full-

duplex seria de esta manera:

Fig.5.2.- Transmisión full-dúplex

Este es el hardware necesario para la comunicación RS485 a 4 hilos, el transmisor y

receptor son totalmente independientes, en un instante ambos pueden estar transmitiendo y

recibiendo información, por eso es llamado “full-duplex” pues es más rápida este tipo de

conexión que su contraparte, la conexión RS-485 a 2 hilos.

5.2.- Comunicación RS-485 a dos hilos (half-duplex).

La otra conexión posible es la de dos hilos, la diferencia, es que a dos hilos, el transmisor y

el receptor nunca están funcionando en el mismo instante, o el dispositivo transmite

información o la recibe, pero nunca al mismo tiempo. Este tipo de conexión, es más lenta

que usando la conexión RS-485 a 4 hilos, pero solo requerimos de dos simples cables, esa

16

es una ventaja que hay que tener en cuenta, a la hora de diseñar el hardware. La figura

siguiente muestra dos dispositivos conectados para funcionar con la especificación RS-485

a dos hilos.

Fig.5.3.- Transmisión half-duplex.

Ventajas del RS-485.

Soporta grandes distancias entre un dispositivo maestro y otros dispositivos.

Es económico.

Usa solo dos cables para su conexión, con ellos puedo conectar muchos

dispositivos, reduciendo los costos del cableado.

Esta última se refiere a que puedo conectar a los dos hilos del RS-485 una gran cantidad de

dispositivos electrónicos. Generalmente cuando se conectan en la red varios componentes

uno de ellos es llamado maestro y los otros esclavos. Por ejemplo podríamos hacerlo así:

Fig. 5.4.- Red maestro-esclavo.

17

En la figura no se muestran los transceptores pero hay que dar por hecho que ya lo están

por simplicidad. Y de esta manera es como funciona tan como la comunicación serial como

el RS-485.

Ahora que a conocemos estos conceptos vamos a entrar a ver el protocolo ModBus y sus

principales funciones.

6.- Protocolo ModBus

La designación ModBus Modicon corresponde a una marca registrada por Gould Inc.

Como en tantos otros casos, la designación corresponde propiamente al estándar de red,

incluyendo todos los aspectos desde el nivel físico hasta el de aplicación, si no a un

protocolo de enlace (nivel OSI 2 del modelo de interconexión de sistemas abiertos:

ISO/IEC 7498-1). Puede, por tanto, implementarse con diversos tipos de conexión física y

cada fabricante suele suministrar un software de aplicación propio, que permite

parametrizar sus productos.

El ModBus es un protocolo de comunicación serial, por lo que comúnmente se implementa

sobre redes de comunicación RE-485, pero también sobre redes que usan la comunicación

serial RS-232, incluso se puede implementar vía TCP/IP sobre una red Ethernet. Este

protocolo ésta basado en el modelo maestro/esclavo y puede estar conformado por

elementos de diferente naturaleza: sensores de temperatura, humedad, variadores de

frecuencia, etcétera.

6.1.- Modos de Transmisión del MODBUS

Los modos de transmisión definen como se envían los paquetes de datos entre maestros y

esclavos, el protocolo MODBUS define dos principales modos de transmisión:

MODBUS RTU (Remote Terminl Unit). La comunicación entre dispositivos se

realiza por medio de datos binarios.

MODBUS ASCII (American Standard Code for Information Interchange). La

comunicación entre dispositivos se hace por medio de caracteres ASCII.

18

Ambas implementaciones del protocolo son del tipo comunicación serie. Pero nosotros nos

concentraremos en el modo RTU.

Fig. 6.1.- Trama de envío de datos con y sin error.

6.1.1.- Hexadecimal.

Las largas cadenas de unos y ceros son difíciles de leer, por lo que los bits se combinan y se

muestran en hexadecimal. Cada bloque de 4 bits está representado por uno de los dieciséis

caracteres de 0 a F.

Cada bloque de 8 bits (llamado un byte) está representado por uno de los 256 pares de

caracteres de 00 a FF.

6.2.- Almacenamiento de datos en ModBus estándar.

La información es almacenada en el esclavo en cuatro diferentes tablas. Dos tablas almacenan los

valores discretos on /off (bobinas) y las otras dos almacenan valores numéricos (registros). Los

registros y las bobinas tienen cada una tabla de solo lectura y una de escritura-lectura.

Cada tabla tiene 9999 valores. Cada bobina o contacto es un bit y se le asignará una dirección de

datos entre 0000 y 270E. Cada registro es una palabra (16 bits = 2 bytes) y también tiene una

dirección de datos entre 0000 y 270E.

19

Bobina / Registro Dirección de datos Tipo Nombre de la tabla

1-9999 0000 to 270E Lectura-Escritura Bobinas de salida discreta.

10001-19999 0000 to 270E Solo lectura Contactos de entrada discreta.

30001-39999 0000 to 270E Solo lectura Registros de entrada analógica.

40001-49999 0000 to 270E Lectura-Escritura Salida analógica de

registros de

retención

Bobina / Registro pueden ser considerados como nombres de ubicación, ya que no aparecen

en los mensajes reales. Las direcciones de datos se utilizan en los mensajes.

6.2.1.- Estructura de red.

Medio físico.

El medio físico de conexión puede ser en bus semidúplex (half duplex) (RS-485 o fibra

óptica) o dúplex (full duplex) (RS-422, CB 0-20 mA o fibra óptica).

La comunicación es asíncrona y las velocidades de transmisión previstas van desde los 75

baudios a 19200 baudios. La máxima distancia entre estaciones depende del nivel físico,

pudiendo alcanzar hasta los 1200 m sin repetidores.

Acceso al medio.

La estructura lógica es del tipo maestro-esclavo, como se mencionó anteriormente, con

acceso al medio controlado por el maestro. El número máximo de estaciones previsto es de

247 esclavos más una estación maestra.

Los intercambios de mensajes pueden ser de dos tipos:

Intercambios punto a punto, que compartan siempre dos mensajes: una demanda del

maestro y una respuesta del esclavo (puede ser simplemente un reconocimiento).

Mensajes difundidos. Estos consisten en una comunicación unidireccional del

maestro a todos los esclavos. Este tipo de mensajes no tiene respuesta por parte de

los esclavos y se suele emplear para mandar datos comunes de configuración, reset,

etc.

20

El protocolo ModBus RTU sigue una estructura de trama bien definida por campos. Así

pues la estructura básica de una trama de este tipo, tanto de lectura como escritura, es la que

se muestra a continuación.

Dirección Esclavo Función Modbus Bytes de Datos Comprobación de Errores

1 Byte 1 Byte N Bytes 2 Bytes

6.2.2.- Número de esclavo (1 byte).

Este es el campo que de manera directa limita el número de esclavos que podemos tener

conectados de forma correcta al bus serie ModBus. Dado que existen direcciones

reservadas para propósitos especiales como el broadcast el valor puede ir de 1 a 247.

Valor comprendido entre 1-247.

No se ve afectado por si se trata de una trama de escritura o lectura.

Cuando el master pregunta al esclavo este campo contiene la dirección del esclavo

al que va dirigido. Cuando se trata de una trama de respuesta de un esclavo al

maestro este campo contiene también la dirección del esclavo indicando quién es el

que responde.

6.3.- Función ModBus o código de operación.

Con este campo se especifica que acción requiere el maestro del esclavo al que va dirigida

la trama.

Cada función permite transmitir datos u órdenes al esclavo. Existen dos tipos básicos de

órdenes.

Ordenes de lectura/escritura de datos en los registros o en la memoria del esclavo.

Ordenes de control del esclavo y propio sistema de comunicaciones (RUN/STOP,

carga y descarga de programas, verificación de contadores de intercambio, etc.)

La siguiente tabla muestra la lista de funciones disponibles en el protocolo ModBus con sus

correspondientes códigos de operación.

Función Código Acción Descripción

01 01H Lectura Bobinas de salida discreta 05 05H Solo escritura Bobinas de salida discreta 15 0FH Escritura

múltiple Bobinas de salida discreta

02 02H Lectura Contactos de entrada discreta

21

04 04H Lectura Registros de entrada analógica 03 03H Lectura Salida analógica de registros de retención 06 06H Solo escritura Salida analógica de registros de retención 16 10H Escritura

múltiple Salida analógica de registros de retención

6.3.1.- Descripción detallada de los comandos

A continuación se otorga un detalle de cada uno de los comandos implementados, de sus

variantes y de los argumentos necesarios en cada caso. Los formatos y ejemplos numéricos

se otorgan en Hexadecimal.

6.3.1.1.- 01 (0x01) Read Coils (Lectura de bobinas).

Este código de función es usado para leer desde 1 a 2000 estados contiguos de una bobina

en un dispositivo remoto. La petición especifica la dirección inicial, es decir, la dirección

de la primera bobina especificada, y el número de bobinas. Las bobinas de la unidad de

datos de protocolo son direccionadas a partir de cero. Por lo tanto si las bobinas están

numeradas del 1 al 16 estas son direccionadas como 0 a 15.

Las bobinas en el mensaje de respuesta empaqueta cada una de las bobinas por bit del

campo de datos. Los estados son indicados como 1=ON y 0=OFF. El bit menos

significativo del primer byte de datos contiene la salida abordado en la consulta. Las otra

bobinas siguen en el orden de bajo a alto en el byte, de igual manera lo hacen en bytes

subsiguientes.

Si la magnitud de salida devuelta no es un múltiplo de ocho, entonces los bits restantes del

byte de datos se rellenan con ceros. El contador de bytes especifica la cantidad de bytes de

datos completos.

Petición.

Código de función 1 Byte 0x01

Dirección inicial 2 Bytes 0x0000 a 0xFFFF

Cantidad de bobinas 2 Bytes 1 a 2000 (0x7D0)

22

Respuesta

Código de función 1 Byte 0x01

Contador de bytes 1 Byte

Estado de las bobinas. N Byte N = N o N+1

= Cantidad de salidas/8, si el resto es diferente de cero.

Código de función 1 Byte Código de función + 0x80

Código de excepción. 1 Byte 01 o 02 o 03 o 04

Para dejar más claro el concepto veamos el siguiente ejemplo donde se pide una lectura de

las salidas discretas, específicamente de la 20 a 38.

Petición Respuesta

Nombre del campo Hex Nombre del campo Hex

Código de función 01 Código de función 01

Dirección inicial (Hi) 00 Contador de bytes 03

Dirección inicial (Lo) 13 Estado de las salidas 27-20

CD

Cantidad de salidas máximas

00 Estado de las salidas 35-28

6B

Cantidad de salidas mínimas

13 Estado de las salidas 38-36

05

Petición: como se puede observar primero se envía el código de función, en este caso como

pedimos una simple lectura de bobinas utilizamos el código 01, recordando que todos los

datos los enviamos en hexadecimal. Enseguida enviamos la dirección inicial y final de la

primera bobina a leer, en este caso pedimos leer a partir de la bobina 20, para poder decir

cuál es la bobina restamos una unidad al número de bobina que queremos leer, así que

restamos uno a 20, dando como resultado 19 pero está en decimal por lo tanto necesitamos

convertirlo a hexadecimal.

19/16 Cociente

1/16 3

0/16 1

23

, entonces el dato que enviamos para definir desde que bobina empezar a

contar es 0013, lo siguiente es enviar el rango de bobinas que queremos contar, en este caso

estamos contando desde la bobina 20 a la 38, si restamos 38-20 es igual a 18, pero también

estamos solicitando el estado de la bobina 20 así que también la tomamos en cuenta 18+1 =

19, de igual manera lo convertimos en hexadecimal.

19/16 Cociente

1/16 3

0/16 1

Es el mismo resultado que el de las direcciones, al enviar estos datos como petición los

visualizaríamos de la siguiente manera:

01 0013 0013

Respuesta: Lo primero que se envía es el código de función, si es que no ocurrió ningún

error, después se manda contador de bytes, este campo manda cuantos bytes son enviados

para declarar el estado de las salidas, como recordaremos un byte está compuesto de 8 bits,

por lo que se hace una separación de 8 bobinas, entonces si nuestro rango de petición de

lectura es de 20 a 38 y el intervalo que entre esos dos es de 19, entonces dividimos 19/8

para hacer el conteo de bytes y nos da como resultado 2.2 pero como válida solo números

enteros entonces lo redondeamos un número más, por lo tanto el contador de bytes manda

03 como el número de bytes, por último se envían los estados de las salidas solicitadas

dentro de la bobina, recordando que 1 significa que están encendidos y 0 que están

apagados, mandando los datos de manera que el bit más significativo de cada byte es el

número de salida más alto, en el ejemplo se muestra que el estado de las salidas 20 a 27 son

las siguientes: 11001101 teniendo en cuenta que el bit más significativo es la salida 27 y el

bit menos significativo es la 20, siguiendo este orden conocemos el estado de las salidas,

pero para poder enviarlas necesitamos convertir el byte en hexadecimal:

Para esto dividimos los 8 bit en paquetes de dos: 1100 y 1101 el primer paquete es igual a

12 lo que equivales a C en hexadecimal, y el segundo paquete es igual 13 que es D, al

volver a juntar estos datos nos queda CD, y este es el resultado que se envía, lo mismo se

hace con el segundo byte, para el tercero que no puede completar los 8 bytes debido a que

solo son 3 salidas (36, 37, 38) se tiene que rellenar con ceros, es decir en este caso tenemos

24

101 para mandar el byte completo debería ser así 00000101 y convertido a hexadecimal nos

da como resultado 05. Y lo que visualizamos en el mensaje de respuesta es este:

01 03 CD6B05

Claro no estamos tomando en cuenta la dirección del esclavo ni la comprobación CRC, esto

fue para que el ejemplo fuera entendible.

Fig.6.2.- Mapa de estados del código de función 01.

25

6.3.1.2.- 02 (0x02) Read Discrete Inputs (Lectura de entradas discretas)

Este código de función es usado para leer desde 1 a 2000 estados de entradas discretas

contiguas en un dispositivo remoto. Las entradas discretas son numeradas del 1 al 16 pero

direccionadas de 0 a 15. El bit menos significativo del primer byte de datos contiene la

entrada pedida de la consulta. La forma de trabajar de esta función es similar a la función

01.

Petición

Código de función 1 Byte 0x02

Dirección inicial 2 Bytes 0x0000 a 0xFFFF

Cantidad de bobinas 2 Bytes 1 a 2000 (0x7D0)

Respuesta

Código de función 1 Byte 0x01

Contador de bytes 1 Byte

Estado de las bobinas. N Byte N = N o N+1

= Cantidad de salidas/8, si el resto es diferente de cero.

Código de función 1 Byte Código de función + 0x82

Código de excepción. 1 Byte 01 o 02 o 03 o 04

De igual manera que en la función anterior vamos a ejemplificarlo para que sea más

entendible, en este caso pediremos leer las entradas discretas 197 a 218.

Petición Respuesta

Nombre del campo Hex Nombre del campo Hex

Código de función 02 Código de función 02

Dirección inicial (Hi) 00 Contador de bytes 03

Dirección inicial (Lo) C4 Estado de las salidas 27-20 AC

Cantidad de salidas máximas 00 Estado de las salidas 35-28 DB

Cantidad de salidas mínimas 16 Estado de las salidas 38-36 35

Petición: En este caso lo primero que enviamos es el número de la función, que es la 02,

enseguida mandamos la dirección inicial de los números de entrada que queremos leer, para

esto le sumamos una unidad a número de la entrada de la cual queremos a empezar a leer,

es decir 197-1=196, este número lo convertimos a hexadecimal:

26

196/16 Cociente

12/16 4

0/16 C

Ya tenemos el direccionamiento de la entrada de la cual queremos empezar a leer, lo

siguiente es saber el rango de las entradas deseadas, es decir cuál va a ser la última entrada

que se leerá. Entonces: 218-197+1=22, sumamos una unidad debido a que también estamos

tomando en cuenta la número 197, ahora lo convertimos en hexadecimal.

22/16 Cociente

1/16 6

0/16 1

De esta manera los datos que estaremos enviando quedarían así:

02 00C4 0016

Respuesta: Primero se envía el mismo código de función que fue solicitado al momento de

hacer la petición por el maestro si es que no se produjo ningún error. Lo siguiente es

mandar el contador de bytes, en este caso son 3, y por último se envían el estado de las

entradas que son mandados en bloques de ocho (1= ON, 0 = OFF), pero esto debe de

mandarse en hexadecimal:

AC=10101100

DB=11011011

35=00110101

Contando el bit más significativo como la entrada más alta en el paquete de datos. Entonces

los datos que se enviarían serían los siguientes:

02 03 ACDB35

Al igual que en el ejemplo anterior no tomamos en cuenta los bytes de dirección del esclavo

ni el de CRC.

27

Fig. 6.3.-Mapa de estados del código de función 02.

6.3.1.3. - 03 (0x03) Read Holding Registers (Lectura de registros).

Este código de función se utiliza para leer el contenido de un bloque contiguo de registros

en un dispositivo remoto. La petición de la unidad maestra especifica la dirección de

partida del registro y el número de registros. Los datos de registro en el mensaje de

respuesta se empaquetan como dos bytes por registro, con el contenido binario justificado a

la derecha dentro de cada byte. Los Registros se abordan a partir de cero. Por lo tanto

registros numerados del 1-16 se tratan como 0-15.

28

Petición

Código de función 1 Byte 0x03

Dirección inicial 2 Bytes 0x0000 a 0xFFFF

Cantidad de bobinas 2 Bytes 1 a 125 (0x7D)

Respuesta

Código de función 1 Byte 0x03

Contador de bytes 1 Byte 2*

Estado de las bobinas. x2 Bytes

= Cantidad de registros.

Error.

Código de función 1 Byte Código de función + 0x83

Código de excepción. 1 Byte 01 o 02 o 03 o 04

Para hacer más claro esto utilizaremos un ejemplo donde pediremos leer los registros 108 a

110.

Petición Respuesta

Nombre del campo Hex Nombre del campo Hex

Código de función 03 Código de función 03

Dirección inicial (Hi) 00 Contador de bytes 06

Dirección inicial (Lo) 6B Valor de registro (Hi 108) 02

No. de registros minino 00 Valor de registro (Lo 108) 2B

No. de registros máxima 03 Valor de registro (Hi 109) 00

Valor de registro (Lo 109) 00

Valor de registro (Hi 110) 00

Valor de registro (Lo 110) 64

Petición: lo primero que ser manda es número del código de función (03) enseguida

colocamos la dirección del registro del cual queremos empezar a contar para su lectura para

saber cuál es el número que se debe de enviar a 108 (número de dirección del registro del

que deseamos partir para la lectura) le restamos una unidad. 108-1=107 y esto lo

convertimos a hexadecimal.

107/16 Cociente

6/16 B

0/16 6

29

Como resultado tenemos 6B, que enviaremos como 006B tomando en cuenta la dirección

inicial Hi, es por eso que se colocan los dos primeros ceros. Después mandamos el

intervalo de registros que queremos leer, para esto restamos el límite superior con el límite

inferior del rango y a esto le sumamos una unidad. En este caso sería así: 110-108+1=3. Se

le suma una unidad debido a que también se toma en cuenta el registro 108 a leer, pero

continuando al tener ya el intervalo lo convertimos a hexadecimal quedando como 03.

Entonces la petición sería de esta manera:

03 006B 0003

Respuesta: Lo primero que se manda es el código de función con el que fue solicitado, en

este ejemplo hablamos del 03, entonces ese es el código que debe de mandarse en caso

contrario de que ocurra un error. Lo siguiente es mandar el contador de bytes, en este caso

enviamos 06 debido a que cada uno de los registros es de 16 bits y como ya se había dicho

antes cada paquete de datos debe de enviarse en paquetes de ocho (1 byte) de esta manera

enviamos los datos en valor de registro Hi y Lo es decir la combinación de estos dos nos da

una palabra (1 word=16 bits=2 bytes) “Hi-Lo” de un solo registro, lo mismo sucede con las

otros dos registros que fueron solicitados. El primer estado de registro que se manda es el

del número 108, para saber el orden de los registros debemos recordar que se numeran de 0

a 15, asi que los primeros que se envían como estado Hi son los registros 15 a 8 en el orden

del bit más significativo al menos significativo y en estado Lo se envían del 7 a 0. Entonces

los estados para los registros son los siguientes:

Registro 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

108 0 2 2 B

109 0 0 0 0

110 0 0 6 4

Estado Hi Lo

Entonces lo que nosotros veríamos sería:

03 06 022B 0000 0064

30

Fig.6.4.- Mapa de estados del código de función 03.

6.3.1.4.- 04 (0x04) Read Input Registers (Lectura de registros de entrada)

Este código de función para leer desde 1 a 125 entradas de registros contiguos en un

dispositivo remoto. La petición de la unidad maestra especifica la dirección inicial y el

número de registros a leer, el direccionamiento debe de empezar desde ser, entonces las

entradas son numeradas de 1 a 16 pero son direccionadas de 0 a15.

En la respuesta los datos del registro son empaquetados como dos bytes por registro, con su

debido contenido binario justificando el estado de los registros.

31

Petición

Código de función 1 Byte 0x04

Dirección inicial 2 Bytes 0x0000 a 0xFFFF

Cantidad de bobinas 2 Bytes 0x0001 a 0x007D)

Respuesta

Código de función 1 Byte 0x03

Contador de bytes 1 Byte 2*

Estado de las bobinas. x2 Bytes

= Cantidad de registros.

Error.

Código de función 1 Byte Código de función + 0x84

Código de excepción. 1 Byte 01 o 02 o 03 o 04

Aquí un ejemplo de cómo se utiliza la función de lectura de entradas pidiendo el estado del

registro número 9.

Petición Respuesta

Nombre del campo Hex Nombre del campo Hex

Código de función 04 Código de función 04

Dirección inicial (Hi) 00 Contador de bytes 02

Dirección inicial (Lo) 08 Registro de entrada (Hi) 00

No. de registros (Hi) 00 Registro de entrada (Lo) 0A

No. de registros (Lo) 01

Petición: Manda el número del código de función que se quiere realizar, queremos leer los

registros de entrada así que es la función 04, después colocamos la dirección de la cual se

empezará a contar los registros, como queremos conocer el registro nueve entonces a este

número le restamos una unidad, debido a que el direccionamiento se cuenta a partir de cero,

por lo que el registro 9 es direccionado como 8, pero siempre hay que mandar los datos en

hexadecimal, pero en este caso así que se queda igual, para continuar con la

trama de la respuesta se manda el número de registros que queremos contar, es decir el

intervalo de estos, pero en este caso solo queremos saber el estado del registro 09, y lo que

mandamos es el número 01, que significa solo un registro a leer. Entonces lo que veríamos

seria:

32

04 0008 0001

Respuesta: Lo primero que se envía es el código de función, si es que no ha ocurrido

ningún error se regresa el mismo que fue solicitado, por ejemplo en este ejemplo ocupamos

la lectura de entradas de registros entonces el dato que se envía 04, lo siguiente es enviar el

contador de bytes, como solo es un solo registro entonces el contador de bytes mandará 02,

porque debemos recordar que un registro contiene 16 bits y los datos se envían en paquetes

de 8 entonces hay que separarlos en 2, es por eso que el contador manda 02 como

información, lo siguiente que se debe de mandar son os estados de las entradas, si están

apagadas (0) o si están encendidas (1), como se mencionó se deben de enviar los datos del

registro de la manera Hi-Lo:

Registro 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

09 0 0 0 A

Estado Hi Lo

33

Fig. 6.5.- Mapa de estados del código de función 04.

6.3.1.5.- 05 (0x05) Write Single Coil (Escritura de una sola bobina).

Este código de función es utilizado para escribir en la salida de una bobina ya sea un estado

encendido (ON) o uno apagado (OFF) en un dispositivo remoto.

El estado ON/OFF de la petición está especificado como una constante en la misma, FF 00

significa ON y la constante 00 00 será OFF, cualquier valor diferente de estos dos que se

llegue a mandar no será tomado en cuenta por la función lo que no provocará ningún

cambio en la bobina.

34

La petición de la unidad maestra especifica la dirección de la bobina a la cual se le

cambiara el valor de salida. Todas las bobinas son direccionadas desde cero, entonces la

bobina numerada como uno es direccionada como cero (dirección de bobina = número de

bobina – 1). El estado ON/OFF de la petición se especifica en el campo “valor de la salida”,

utilizando las constantes ya antes mencionadas.

Petición:

Código de función 1 Byte 0x05

Dirección de la salida a escribir 2 Bytes 0x0000 a 0xFFFF

Valor de la salida 2 Bytes 0x0000 o 0xFF00

Respuesta:

Código de función 1 Byte 0x05

Dirección de la salida a escribir 2 Bytes 0x0000 a 0xFFFF

Valor de la salida 2 Bytes 0x0000 o 0xFF00

Error:

Código de error 1 Byte 0x85

Código de excepción 1 Byte 01 o 02 o 03 o 04

Aquí un ejemplo de esta función para mandar activar el estado ON de la salida de la bobina

173.

Petición Respuesta

Nombre del campo Hex Nombre del campo Hex

Código de función 05 Dirección de la bobina Hi 05

Dirección de la bobina Hi 00 Dirección de la bobina Lo 00

Dirección de la bobina Lo AC Valor de la salida Hi AC

Valor de la salida Hi FF Valor de la salida Lo FF

Valor de la salida Lo 00 Dirección de la bobina Hi 00

Petición: Como se puede observar lo primero que se manda es el código de función en este

caso 05 ya que estamos escribiendo un valor de salida en una solo bobina, lo siguiente es

enviar la dirección de la bobina que deseamos escribir pero debemos mandarla en

hexadecimal, de igual manera debemos tomar en cuenta que el direccionamiento de las

35

bobinas comienza desde cero, entonces si tenemos la bobina numerada 173 se debe de

direccionar como 172, y esto lo convertimos a hexadecimal.

172/16 Cociente

10/16 C

0/16 A

Y por último se envía el estado en el cual queremos que la salida se encuentre, en este

ejemplo pedimos que se encienda es por eso que la constante FF00 es enviada, recordando

que si se coloca cualquier otro valor estos serán marcados como inválidos y no afectaran a

las salidas de la bobina.

Respuesta: Si es que no ha ocurrido ningún error entonces los datos que se envían son

exactamente los mismos que se recibieron de la petición de la unidad maestra y en el

mismo orden.

36

Fig. 6.6.- Mapa de estados del código de función 05.

6.3.1.6.- 06 (0x06) Write Single Register (Escritura de un solo registro)

Este código de función se utiliza para escribir un solo registro en una unidad esclava. La

petición especifica la dirección del registro a escribir. Los registros son direccionados desde

cero. La respuesta del esclavo al maestro es la misma petición que este recibe. A diferencia

del código de función anterior, aquí no es necesario escribir dos constantes para poder

poner los estados del registro en ON u OFF, en este caso se mandan los valores binarios

(1=ON, 0=OFF) convertidos en hexadecimal.

37

Petición:

Código de función 1 Byte 0x06

Dirección de la salida a escribir 2 Bytes 0x0000 a 0xFFFF

Valor de la salida 2 Bytes 0x0000 a 0xFFFF

Respuesta:

Código de función 1 Byte 0x06

Dirección de la salida a escribir 2 Bytes 0x0000 a 0xFFFF

Valor de la salida 2 Bytes 0x0000 o 0xFFFF

Error:

Código de error 1 Byte 0x86

Código de excepción 1 Byte 01 o 02 o 03 o 04

Aquí un ejemplo de esta función, escribiendo el registro 2 el valor 00 03 hexadecimal.

Petición Respuesta

Nombre del campo Hex Nombre del campo Hex

Código de función 06 Dirección de la bobina Hi 06

Dirección de la bobina Hi 00 Dirección de la bobina Lo 00

Dirección de la bobina Lo 01 Valor de la salida Hi 01

Valor de la salida Hi 00 Valor de la salida Lo 00

Valor de la salida Lo 03 Dirección de la bobina Hi 03

Petición: Primero se envía el código de función (06) de la operación que se pide a realizar,

enseguida de esto se manda la dirección del registro que se desea escribir, como deseamos

escribir el registro numerado como 2 debemos direccionarlo como 1, debido a que el

direccionamiento de los registros se empieza desde cero, por último enviamos el valor del

registro al que deseamos que se actualicen. En este caso veríamos:

06 0001 0003

Respuesta: Si es que no ha ocurrido ningún error entonces la respuesta son los mismos

datos y en el mismo orden en el que los mando la petición.

38

Fig. 6.7.- Mapa de estados del código de función 06.

6.3.1.7.- 15 (0x0F) Write Multiples Coils (Escritura de múltiples bobinas).

Este código de función escribe en una secuencia de bobinas el estado de las salidas que

debe de tener, ya sea que sean puestas en estado encendido (ON) o en estado (OFF). En la

petición de la unidad maestra esta pone la dirección de la bobina de referencia para

empezar el conteo de las bobinas a las cuales se les forzará a cambiar de estado. Las

bobinas son direccionadas empezando desde cero, entonces la bobina que sea numerada

como 1, tendrá una dirección 0.

39

En la petición se especifica el estado de las bobinas a forzar, tomando como un “1” lógico

encendido (ON) y un “0” como apagado (OFF). Una respuesta normal manda solamente el

código de función que fue solicitado por la unidad maestra en la solicitud, la dirección de

inicio y el número de bobinas que fueron forzadas a cambiar de estado.

Petición.

Código de función 1 Byte 0x0F

Dirección de inicio 2 Bytes 0x0000 a 0xFFFF

Cantidad de bobinas 2 Bytes 0x0001 a 0x07B0

Contador de Bytes 1 Byte

Valor de las bobinas

=Cantidad de salidas entre ocho, si esto no es un número entero entonces el último byte

que no completa el octeto es rellenado con ceros.

Respuesta.

Código de función 1 Byte 0x0F

Dirección de inicio 2 Bytes 0x0000 a 0xFFFF

Cantidad de salidas 2 Bytes 0x0001 a 07B0

Error.

Código de error 1 Byte 0x8F

Código de excepción 1 Byte 01 o 02 o 03 o 04

Para que quede más claro cómo trabaja este código de función daremos un ejemplo

pidiendo cambiar los valores de 10 bobinas empezando a contar desde la número 20. Los

valores que deben de escribirse son: CD 01 hex (1100 1101 0000 0001).

Primero mostraremos la tabla de cómo sería tanto la petición como la respuesta y después

explicare como es que trabaja.

Petición Respuesta

Nombre del campo Hex Nombre del campo Hex

Función 0F Función 0F

Dirección de inicio Hi 00 Dirección de inicio Hi 00

Dirección de inicio Lo 13 Dirección de inicio Lo 13

40

Cantidad de salidas Hi 00 Cantidad de salidas Hi 00

Cantidad de salidas Lo 0A Cantidad de salidas Lo 0A

Contador de bytes 02

Valor de las salidas Hi CD

Valor de las salidas Lo 01

Petición: Para empezar lo primero que tenemos que enviar es la función que queremos

realizar en este caso 0F, enseguida de esto mandamos la dirección de la bobina de

referencia de la cual vamos a empezar a escribir sus nuevos estados, nosotros queremos

empezar desde la bobina numerada como 20 pero debemos recordar que las bobinas son

direccionadas desde 0, entonces al número 20 le restamos una unidad para tener correcta la

dirección y este número lo convertimos a hexadecimal.

19/16 Cociente

1/16 3

0/16 1

Bien, ya tenemos la bobina desde la cual empezaremos a escribir, lo que siguen en nuestro

paquete de datos es enviar el intervalo de las salidas forzadas a cambiar de estado, el

ejemplo nos pide que sean 10 bobinas a escribir, entonces mandamos el número 10

convertido en hexadecimal y tenemos que 10=A, lo siguiente es enviar el contador de

bytes, este campo nos indica el número de bytes que se están mandando para el cambio de

estado de las bobinas, y si bien recordamos cada byte ésta compuesto por 8 bits entonces el

resto de ellos tienen que agruparse en otro paquete de ocho, si estos no logran llenar el byte

entonces se complementa el octeto con ceros, siguiendo esta regla sabemos que tenemos 2

bytes debido que son 10 bobinas las que cambiarán de estados.

Por último enviamos los valores que deberán tomar las salidas de las bobinas, y recordando

lo mencionado en las primeras funciones explicadas, en la respuesta el orden del valor de

los estados de las bobinas eren enviados del bit más significativo al menos significativo y

colocando las primeras bobinas que se leyeron, pues bien aquí es exactamente lo mismo

solo que ahora es en la petición donde se colocan, en este caso tenemos que escribir estados

es las bobinas 20 a 29, entonces la manera de separar estos datos es: 20-27 y 28-29, los

primeros bits de escritura que son enviados en el paquete de datos son 20-27 y enseguida de

41

ellos el restante, esta ocasión el ejemplo nos dice que estas bobinas deben de tener los

siguientes valores : 1100 1101 y 0000 0001 de las salidas 20-27 y 28-29 respectivamente.

Bobina 27 26 25 24 23 22 21 20

Estado 1 1 0 0 1 1 0 1

Bobina - - - - - - 29 28

Estado 0 0 0 0 0 0 0 1

De esta manera podemos ver el orden en el que se envían los valores para las bobinas a las

que se quiere cambiar el estado, tal y como se muestra en las tablas es el orden en el que se

envían los datos, en el segundo octeto solo son dos salidas las que queremos cambiar y

como no se puede completar se rellena con ceros, entonces esta es la razón por la que

observamos en la petición que los valores para cambiar son CD 01 hex (1100 1101 0000

0001). Si se piensa que los otros ceros después del 29 afectarán a las otras salidas es un

error ya que en la misma petición se aclaró el intervalo de salidas a cambiar, de esta manera

el esclavo no les hará caso ya que solo se tomaron para rellenar el byte.

Respuesta: Lo único que debe mandar el esclavo es la función que le fue solicitada, la

dirección inicial o de referencia de las bobinas a leer y el número de ellas, entendiendo que

no halla ocurrido ningún error.

42

Fig. 6.8.- Mapa de estados del código de función 0F.

6.3.1.8.- 16 (0x10) Write Multiple Registers (Escritura de múltiples registros)

Esta función se utiliza para escribir un bloque contiguo de registros (1 a 123 registros), en

la petición se especifica los valores que estos deben de tomar, por cada registro se utilizan 2

bytes. La respuesta normal del esclavo al maestro contiene el código de función, dirección

de inicio, y la cantidad de registros escritos.

Código de función 1 Byte 0x10

Dirección de inicio 2 Bytes 0x0000 a 0xFFFF

Cantidad de registros 2 Bytes 0x0001 a 0x007B

Contador de Bytes 1 Byte 2x

Valor de los registros Valor

43

=Cantidad de salidas entre ocho, si esto no es un número entero entonces el último byte

que no completa el octeto es rellenado con ceros.

Respuesta.

Código de función 1 Byte 0x10

Dirección de inicio 2 Bytes 0x0000 a 0xFFFF

Cantidad de registros 2 Bytes 1 a 123 (0x7B)

Error.

Código de error 1 Byte 0x90

Código de excepción 1 Byte 01 o 02 o 03 o 04

Aquí un ejemplo de una petición donde se deben de escribir comenzando en el registro

número 2 y que los datos a escribir son: 00 0A y 01 02.

Petición Respuesta

Nombre del campo Hex Nombre del campo Hex

Función 10 Función 10

Dirección de inicio Hi 00 Dirección de inicio Hi 00

Dirección de inicio Lo 01 Dirección de inicio Lo 01

Cantidad de registros Hi 00 Cantidad de registros Hi 00

Cantidad de registros Lo 02 Cantidad de registros Lo 02

Contador de bytes 04

Valor de los registros Hi 00

Valor de los registros Lo 0A

Valor de los registros Hi 01

Valor de los registros Lo 02

Petición: Lo primero que se manda es el número del código de función, después sigue la

dirección inicial del registro desde el cual se va a empezar a escribir los valores, el que se

pide es el número dos, pero es direccionado como uno, debido a que los direccionamientos

son a partir de cero, lo siguiente es enviar el número de registros que se deben de escribir,

en este caso son dos, luego se envía el contador de bytes, si recordamos un solo registro

necesita 2 bytes para poder mandar y recibir información, entonces si estamos escribiendo

en dos registros, estos se multiplican por dos y tenemos cuatro bytes que son los que

44

registra el contador y envía en la misma petición, y por último se escriben los valores de los

registros que deseamos forzar a cambiar en ellos.

Respuesta: Está solo contiene la función que pidió el maestro al momento de mandar la

petición, la dirección inicial del registro del cual se tomó referencia para poder escribir y el

número de registros que se escribieron.

Fig. 6.9.- Mapa de estados del código de función 10 hex.

6.3.2.- Respuestas de excepción ModBus.

Cuando una unidad maestra envía una petición a una unidad esclava siempre se espera una

respuesta normal. Siempre que se manda una petición puede ocurrir uno de cuatro eventos.

45

Si el esclavo recibe la petición sin ningún error de comunicación, y puede hacer la

acción requerida, entonces este regresa una respuesta normal.

Si el esclavo no recibe la petición por un error de comunicación, no se devuelve

ninguna respuesta. El programa del esclavo puede procesar una condición de tiempo

de espera para la solicitud.

Si el servidor recibe la petición, pero detecta un error de comunicación (paridad,

LRC, CRC,…..) no se regresa la respuesta. El programa del esclavo puede procesar

una condición de tiempo de espera para la solicitud.

Si el esclavo recibe una petición sin errores de comunicación, pero no puede hacerla

(por ejemplo si la petición es para leer una salida o registro que no existe), el

esclavo regresará una respuesta de excepción informando al maestro la naturaleza

del error.

La respuesta de excepción contiene 2 campos que se diferencian de una respuesta normal.

Campo de código de función: En una respuesta normal, el esclavo escoge el código de

función de la petición original. Todos los códigos de función tienen un bit más significativo

(MSB) de 0 (todos los valores están por debajo de 80 hexadecimal). En una respuesta de

excepción, el esclavo envía el MSB de la función a 1. Esto hace el valor del código de

función en una respuesta de excepción exactamente igual o mayor a 80 hexadecimal, un

valor diferente como lo debería de ser una respuesta normal.

Con el MSB del código de función, el programa del esclavo puede reconocer la respuesta

de excepción y puede examinar los datos para el código de excepción.

Datos: En una respuesta normal el esclavo puede regresar datos o estadísticas (cualquier

información que haya sido pedida por una petición). En una respuesta de excepción, el

esclavo regresa un código de excepción. Esto define al maestro que condición fue la que

causo la excepción.

Ejemplo

Petición Respuesta

Nombre del campo Hex Nombre del campo Hex

Código de función 01 Código de función 81

Dirección de inicio Hi 04 Código de excepción 02

46

Dirección de inicio Lo A1

Cantidad de salidas Hi 00

Cantidad de salidas Lo 01

En este ejemplo, la unidad maestra manda una petición donde se quiere saber el estado de

una sola bobina, la bobina que se pide leer es la bobina direccionada 1185 (04A1), ´pero

esta bobina no existe en la unidad esclava, entonces esta misma regresará el código de

excepción 02 que especifica una dirección invalida para el esclavo.

Aquí una lista de los códigos de excepción.

Códigos de excepción ModBus

Código Nombre Descripción

01 Illegal function (Función no valida) El código de función recibido en la consulta no

es una acción permitida para el esclavo. Esto

puede deberse a que el código de función solo

aplica a los dispositivos más nuevos, y no se

llevó a cabo en la unidad seleccionada.

También puede indicar el esclavo está en un

estado incorrecto para procesar una solicitud de

este tipo.

02 Illegal data address (Dirección invalida) La dirección recibida en la petición no es una

dirección permitida para el esclavo. Más

específico, la combinación de la dirección y el

número a contar va más allá de los limites es

invalido. Por ejemplo, para un controlador con

100 registros, la unidad maestra direcciona el

primer registro como 0 y el último como 99, si se

hace una petición de lectura iniciando en la

dirección 96 con una cantidad de 4 registros,

entonces esta petición se hará con éxito, debido a

que los registros a leer son 96, 97, 98 y 99. Si en

lugar de 4 hubiesen sido 5, entonces ocurre un

error ya que los registros que se piden son 96,

97, 98, 99 y 100 lo que es más de los registros

que se tienen, entonces el esclavo manda el

código de excepción 0x02.

03 Illegal data value Un valor contenido en una petición que no es

permitida para el esclavo. Esto indica un fallo en

la estructura del resto de una petición compleja.

Específicamente no significa que un elemento de

47

datos enviado para su almacenamiento en un

registro tiene un valor fuera de la expectativa del

programa de aplicación, ya que el protocolo

ModBus no comprende el significado de

cualquier valor en particular.

04 Server device failure Se ha producido un error irrecuperable mientras

el servidor intentaba realizar la acción solicitada.

05 Acknowledge Utilización especial junto con los comandos de

programación. El esclavo ha aceptado la

solicitud y está procesando, pero el período de

espera es demasiado largo. Esta respuesta se

envía para evitar un error de tiempo de espera

que se produzcan en el cliente.

06 Server device busy El servidor está ocupado procesando un

comando de programa de larga duración. El

cliente debe retransmitir el mensaje más tarde

cuando el servidor está libre.

08 Memory parity error Utilización especial junto con los códigos de

función 20 y 21 y el tipo de referencia 6, para

indicar que la zona de archivos extendido no

pudo pasar una comprobación de coherencia.

El esclavo intentó leer el archivo de registro,

pero detecta un error de paridad en la memoria.

El maestro puede reintentar la solicitud, pero el

servicio puede ser requerido en la unidad

esclava.

0A Gateway patch unavailable Utilización especial junto a los gateways, indica

que la gateway no ha podido asignar una ruta de

comunicación interna del puerto de entrada al

puerto de salida para el procesamiento de la

solicitud. Por lo general, significa que él gateway

está mal configurado o sobrecargado.

0B Gateway target device failed to respond Indica que no se obtuvo respuesta del dispositivo

de destino. Por lo general, significa que el

dispositivo no está presente en la red.