UNIVERSIDAD TECNOLÓGICA DE SAN JUAN DEL RÍO MANUAL DEL PROTOCOLO MODBUS EMPRESA
-
Upload
independent -
Category
Documents
-
view
1 -
download
0
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.