El protocolo MODBUS
Jordi Bartolomé 1-2011

1-Introducción
El protocolo de comunicaciones industriales MODBUS fue desarrollado en 1979 por la empresa norteamericana MODICON y debido a que es público, relativamente sencillo de implementar y flexible se ha convertido en uno de los protocolos de comunicaciones más populares en sistemas de automatización y control. A parte de que muchos fabricantes utilizan este protocolo en sus dispositivos, existen también versiones con pequeñas modificaciones o adaptadas para otros entornos ( como p.ej JBUS o MODBUS II )

MODBUS especifica el procedimiento que el controlador y el esclavo utilizan para intercambiar datos, el formato de estos datos, y como se tratan los errores. No especifica estrictamente el el tipo de red de comunicaciones a utilizar, por lo que se puede implementar sobre redes basadas en Ethernet , RS-485, RS-232 etc.

Este documento explica la especificación MODBUS de forma general, sin entrar en mucho detalle en algunas de sus particularidades, no obstante su contenido ha de ser más que suficiente para aquellos que deseen comprender el funcionamiento general de este estándar. Por otro lado, quien desee realizar una implementación precisa de MODBUS deberá recurrir a la documentación oficial de MODICON o a la documentación especifica del fabricante de los equipos con los que va a comunicar.

2-Descripción general
MODBUS funciona siempre en modo maestro-esclavo ( cliente - servidor ), siendo el maestro ( cliente ) quien controla en todo momento las comunicaciones con los esclavos que pueden ser hasta 247 (@1d a @247d ) . Los esclavos ( servidores ) se limitan a retornar los datos solicitados o a ejecutar la acción indicada por el maestro. La comunicación del maestro hacia los esclavos puede ser de dos tipos:

- “peer to peer”: en que se establece comunicación “maestro - esclavo” , el maestro solicita información y el esclavo responde ( se envía el comando a un dispositivo comprendido entre las direcciones 1d i 247d ).
-“broadcast”: en que se establece comunicación “maestro - todos los esclavos” , el maestro envía un comando a todos los esclavos de la red sin esperar respuesta ( se envía a la dirección @0d ).

Como se puede ver, la secuencia básica en las comunicaciones MODBUS consiste siempre en una trama de pregunta, seguida de su correspondiente trama de respuesta:

- Pregunta: con el código de función que indica al esclavo que operación ha de realizar, y los bytes necesarios ( datos, comprobación … ) para su ejecución.
- Respuesta: con la confirmación o datos resultantes de la ejecución de la función.

Existe algún caso concreto, en que hay más de una trama de respuesta para una trama de pregunta, como p.ej. cuando el maestro envía una operación cuya respuesta puede llevar al esclavo un tiempo elaborar. En estas situaciones el esclavo envía una primera respuesta indicando que aún no tiene los datos y tardará un tiempo en disponer de ellos, y otra segunda con los datos o confirmación de la operación.

Además las comunicaciones MODBUS se pueden realizar en modo ASCII o en modo RTU. En modo ASCII los bytes se envían codificados en ASCII, es decir, que por cada byte a transmitir se envian dos caracteres ASCII ( 2 bytes ) con su representación hexadecimal ( esto permite leer las tramas con un simple editor de texto ). En modo RTU se envían en binario, tal cual. En el modo ASCII las tramas comienzan por 3AH (carácter ':'), y terminan en 0DH-0AH (CR LF Carrier Return Line Feed) y cada byte se envía como dos caracteres ASCII. En modo RTU no se utiliza indicador de inicio y final de trama.

  Modo ASCII Modo RTU
Carácteres ASCII ‘0’…’9’,’A’….’F’ Binario 0…255
Comprob. Error LRC Longitudinal Redundancy check   CRC Cyclic Redundancy Check
Inicio de trama Carater ‘:’ 3.5 veces t de carácter
Final de trama Character CR/CL 3.5 veces t de carácter
Distancia max. entre caracteres   1 seg 1.5 veces t de carácter
Bit de inicio 1 1
Bits de datos 7 8
Paridad Par / Impar / Ninguna Par / Impar / Ninguna
Bits de parada 1 si hay paridad 2 si ninguna 1 si hay paridad 2 si ninguna

3-Campos de las tramas MODBUS
El número de campos de las tramas MODBUS varía ligeramente dependiendo de si utilizamos la codificación ASCII o RTU:

Codificación ASCII ( formato texto ):
-Inicio de trama: 2 caracteres ASCII ( que representan 1 byte ) codificando el caracter “:” (0x3A)
-NºEsclavo: 2 caracteres ASCII ( que representan 1 byte ) codificando la dirección del esclavo destino ( o origen ) de la trama
-Código Operación: 2 caracteres ASCII ( que representan 1 byte ) con el código de operación
-Dirección, datos y subfunciones Datos: con los parámetros necesarios para realizar la operación.
-LRC(16): H L
-Final de trama: 4 caracteres ASCII ( que representan 2 bytes ) con los caracteres CR (0x0D) - LF (0x0A)

Codificación RTU (en el formato binario, el inicio de trama debería ser tras 3.5 tiempo de carácter):
-NºEsclavo: 1 byte con la dirección del esclavo destino ( o origen ) de la trama
-Código Operación: 1 byte con el código de operación
-Subfunciones Datos: con los parámetros necesarios para realizar la operación.
-CRC(16): H L.

4-Descripción de los campos de las tramas MODBUS

- Número de Esclavo (1byte): En el caso de las tramas enviadas por el máster, el campo de número de esclavo indica la dirección del destinatario de esta trama. Permite direccionar hasta 247 esclavos, con las direcciones de 1d a 247d (0x00 a 0xF7). El 0x00 es para los mensajes de Broadcast, así el primer esclavo comienza con la dirección 1 ( de 1 a 247 ). En el caso de las tramas enviadas por los esclavos, este byte sirve para indicar al máster a quién pertenece la respuesta. Es decir, cada vez que un esclavo responde, sitúa su propia dirección en el byte de dirección lo que permite saber al maestro a que equipo corresponde cada respuesta. Las tramas broadcast, no tienen asociada respuesta, y algunas implementaciones de MODBUS no admiten la trama de broadcast.

- Código de Operación o Función ( 1byte): Indica el tipo de operación que queremos realizar sobre el esclavo. Las operaciones se pueden clasificar en dos tipos:

- De lectura / escritura en memoria: para consultar o modificar el estado de los registros del mapa de memoria del esclavo.
- Ordenes de control del esclavo: para realizar alguna actuación sobre el esclavo.

El código de operación puede tomar cualquier valor comprendido entre el 0 y el 127 ( el bit de más peso se reserva para indicar error ). Cada código se corresponde con una determinada operación. Algunos de estos códigos se consideran estándar y son aceptados e interpretados por igual por todos los dispositivos que dicen ser compatibles con MODBUS, mientras que otros códigos son implementaciones propias de cada fabricante. Es decir que algunos fabricantes realizan implementaciones propias de estos códigos “no estándar”.

Es también mediante el código de función que el esclavo confirma si la operación se ha ejecutado correctamente o no. Si ha ido bien responde con el mismo código de operación que se le ha enviado, mientras que si se ha producido algún error, responde también con el mismo código de operación pero con su bit de más peso a 1 ( 0x80 ) y un byte en el campo de datos indicando el código de error que ha tenido lugar.

- Dirección, datos y subfunciones (n bytes): Este campo contiene la información necesaria para realizar la operación indicada en el código de operación. Cada operación necesitará de unos parámetros u otros, por lo que el número de bytes de este campo variará según la operación a realizar. En el caso del esclavo, este puede responder con tramas con o sin campo de datos dependiendo de la operación. En los casos en que se produzca algún error es posible que el esclavo responda con un byte extra para especificar el código de error.

Al establecer la dirección de una variable u otro elemento en el mapa de direcciones MODBUS, direccionamos con 1 unidad menos a la del registro al que queremos acceder, de manera que si p.ej. quisiéramos acceder al relé @ 127d, lo haríamos situando el valor 126d en el byte del campo de dirección. Otros ejemplos:

- El relé número 1 de un controlador se direccionaría con el valor 0000 en el campo de dirección de un mensaje MODBUS.
- El relé 0x007F (127d ) de un controlador se direccionaría con el valor 0x007E ( 126d ) en el campo de dirección de un mensaje MODBUS.
- El Holding Register 40001 se accedería situando el valor 0000 en el campo de dirección del mensaje. Como se puede ver el código de función de acceso a los Holding Registers lleva implícito el acceso a la dirección ‘4XXXX’.
- El Holding Register 40108 es accedido leiendo de la dirección 0x006B ( 107d )

Generalmente en MODBUS cada tipo de dato se mapea en un rango de memoria concreto:

@1-10000 (DOs - digital outputs): 1 bit por dirección para indicar el estado de una salida, mando o relé ( 0 desactivado, 1 activado ). Las direcciones de este rango se suelen acceder mediante las funciones 1 (lectura), 5 (escritura), 15 (escritura múltiple).

@10001-20000 (DIs - digital inputs): 1 bit por dirección para leer el estado de una entrada digital ( 0 desactivada, 1 activada ) también denominadas DIs ( Digital Inputs ). Las direcciones de este rango se suelen acceder con la función 2 (lectura) y llevan implícita la dirección 10001 como dirección base ( para acceder a una dirección bastará con especificar la distancia entre esta y la dirección base ).

@20001-30000: el protocolo MODBUS estándar no hace uso de este rango de direcciones.

@30001-40000 (AIs - analog inputs): 16 bits por dirección con el estado de las medidas o entradas analógicas también denominadas AIs ( Analog Inputs ). Dependiendo del dispositivo este puede hacer uso de más de un registro para almacenar la información de la medida, así con 2 registros consecutivos podríamos almacenar medidas de 32 bits. Las direcciones de este rango se acceden mediante la función 4 (lectura) y llevan implícita la dirección 30001 como dirección base ( para acceder a una dirección bastará con especificar la distancia entre esta y la dirección base ).

@40001-50000 (AOs - analog outputs): 16 bits con los registros de salidas analógicas o de propósito general ( Output Registers – Holding Registers). Se acceden con las funciones 3 ( lectura ), 6 ( escritura ) o 16 ( escritura múltiple ) y llevan implícita la dirección 40001 como dirección base ( para acceder a una dirección bastará con especificar la distancia entre esta y la dirección base ).

Algunos fabricantes expresan la dirección de forma compuesta, separando la dirección de palabra y la dirección de bit: p.ej word 0x30 bit 1

Como se cita en el apartado de “Código de Operación o Función”, cuando se produce un error en la ejecución de un comando en el esclavo, este responde poniendo a 1 el bit de más peso del codigo de función ( 0x80 ). Con este bit el maestro sabe que se ha producido un error, pero para obtener mas detalle sobre el tipo de error, ha de comprobar el campo de datos:

Codigo Nombre Significado
01 ILLEGAL FUNCTION El código de función recibido no se corresponde a ningún comando disponible en el esclavo
02 ILEGAL DATA ADRESS La dirección indicada en la trama no se corresponde a ninguna dirección válida del esclavo
03 ILLEGAL DATA VALUE El valor enviado al esclavo no es válido
04 SLAVE DEVICE FAILURE El esclavo ha recibido la trama y la ha comenzado a procesar, pero se ha producido algún error y no ha podido termina la tarea.
05 ACKNOWLEDGE El esclavo ha recibido la trama y la está procesando pero esto le llevará un periodo un poco largo. Mediante esta respuesta se evita que el máster considere un error de timeout. El máster podrá enviar más tarde una trama una trama de tipo Poll Program Complete para verificar si ha completado el comando
06 SLAVE DEVICE BUSY El esclavo está ocupado realizando otra tarea y no puede atender a esa petición en ese instante por lo que el máster tendrá que reintentarlo más adelante.


- Control de errores LRC o CRC: Se utiliza un sistema de detección de errores diferente dependiendo del tipo de codificación utilizado ( ASCII o RTU ) . En el caso de la codificación ASCII  es el checksum ( o  Longitud Redundancy Check LRC ) en módulo 16 expresado en ASCII ( 2 caracteres representan 1 byte ), sin considerar el ":" ni el “CR LF” de la trama. En la codificación RTU se utiliza el método de CRC ( Cyclical Redundancy Check ) codificado en 2 bytes (16  bits).

Para calcular el CRC se carga un registro de 16 bits todo con '1's , se hace OR con cada uno de los caracteres de 8 bits con el contenido de cada byte y el resultado se desplaza una bit a la izquierda insertando un 0 en la posición de menos peso ( la de la derecha ). El de la izquierda se extrae y se examina: si es 1 se vuelve a hacer OR con un valor prefijado, si es 0 no se hace ninguna OR... y el proceso se repite hasta que se han hecho los 8 shifts del byte. La siguiente es una implementación en C de la función de cálculo del CRC ( modo RTU ):

“…
#definePOLY0xA001
unsignedcrc16(char*buf,intlen)
{
     char i;
     unsigned crc;
    

     for(crc=0xFFFF;len!=0;len--){
            crc^=*buf++;
            for(i=0;i<8;i++){
                  if(crc&0x0001){
                     crc=(crc>>1)^POLY;
                  }else{
                     crc>>=1;
                  }
            }
      }
      return(crc);
}
…”

En C#:


“…
uint crc16(byte [ ] buf , uint len)
{
     uint POLY=0xA001;
     int crc;
     uint i;
     uint j;
 
      j = 0;
      for (crc = 0xFFFF; len != 0; len --){
             crc ^= buf[j];
             j++;
             for (i = 0; i < 8; i ++){
                 if ((crc & 0x0001)>0){
                     crc = (crc >> 1) ^ POLY;
                  }else{   
                     crc >>= 1;
                  }   
              }
        }
        return (crc);     
}
…”

El siguiente es un ejemplo en modo ASCII y RTU de petición de lectura de 3 registros del esclavo y la correspondiente respuesta :

-PETICION de 3 datos:
Nombre del campo Ejemplo ( HEX )  Caracteres ASCII  8bits modo RTU
Cabecera   : Ninguno
Dirección esclavo 06 “06” 0000 0110
Función 03 “03” 0000 0011
Direccion inicio Hi 00 “00” 0000 0000
Direccion inicio Lo 6B “6B” 0110 1011
Num de Registros Hi   00 “00” 0000 0000
Num de Registros Lo   03 “03” 0000 0011
Error Check   LRC ( 2 caracteres ) CRC (16 bits)
Fin de trama   CR LF Ninguno
Total:   17 bytes 8 bytes

-RESPUESTA con los 3 datos:
Nombre del campo Ejemplo (HEX)  Caracteres ASCII 8bits modo RTU
Cabecera   : Ninguno
Dirección esclavo 06 “06” 0000 0110
Función 03 “03” 0000 0011
Numero de bytes de datos  06 “06” 0000 0110
Dato 0 Hi 02 “02” 0000 0010
Dato 0 Lo 2B “2B” 0010 1011
Dato 1 Hi 00 “00” 0000 0000
Dato 1 Lo 00 “00” 0000 0000
Dato 2 Hi 00 “00” 0000 0000
Dato 2 Lo 63 “63” 0110 0011
Error Check   LRC (2 caracteres )   CRC (16 bits)
Fin de trama   CR LF ninguno
Total:   23 bytes 11 bytes

5-Descripción de los códigos de operación o función más frecuentes
Los siguientes códigos son algunos de los códigos de función MODBUS más extendidos, soportados por todos los dispositivos que cumplen con las especificaciones del estándar ( controladores de MODICON ):

  - Función 1 Read Coil Status
  - Función 2 Read Input Status
  - Función 3 Read Holding Registers
  - Función 4 Read Input Registers
  - Función 5 Force Single Coil
  - Función 6 Preset Single Register
  - Función 7 Read Exception Status
  - Función 8 Diagnostics
  - Función 9 Program 484
  - Función 10 Poll 484
  - Función 11 Fetch Communication Event Counter
  - Función 12 Fetch Communication Event Log
  - Función 13 Program Controller
  - Función 14 Poll Controller
  - Función 15 Force Multiple Coils
  - Función 16 Preset Multiple Registers
  - Función 17 Report Slave ID
  - Función 18 Program 884/M84
  - Función 19 Reset Comm. Link
  - Función 20 Read General Reference
  - Función 21 Write General Reference
  - Función 22 Mask Write 4X Register
  - Función 23 Read/Write 4X Registers
  - Función 24 Read FIFO Queue


Función 1 o 2 ( 1 Read Coil Status - 2 Read Input Status ):
Permite realizar la lectura del estado de las DIs ( @1XXXX el comando 2-Read input status ) o DOs ( @0XXXX el comando 1-Read Coil Status ). Para ello el maestro solicita el número de bits que desea leer a partir de una determinada dirección. Cada dirección se corresponde con un registro de 1 bit con el estado del la entrada digital. El esclavo responde indicando el número de bits que retorna y sus valores. En la trama de respuesta se aprovechan todos los bits del byte, y puede haber hasta 256 bytes.

Petición del máster (modo RTU):
   NºEsclavo
   Código Operación: 0x01 o 0x02
   Dirección del registro ( de 1 bit ) a leer H
   Dirección del registro ( de 1 bit ) a leer L
   Nº de bits que se desea leer H
   Nº de bits que se desea leer L
   CRC(16): H
   CRC(16):

Respuesta del esclavo (modo RTU):
   NºEsclavo
   Código Operación: 0x01 o 0x02
   Nº bytes leidos: 1 byte
   Octetos: max 256 bytes
   CRC(16): H
   CRC(16): L

Función 3 o 4 ( 3 Read Holding Registers – 4 Read Input Registers ) :
Permite realizar la lectura del valor de las AIs ( @4XXXX el comando 3 Read Holding Registers ) o AOs ( @3XXXX el comando 4 Read Input Registers ) . El máster indica la dirección base y número de palabras a leer a partir de esta, mientras que el esclavo indica en la respuesta el número bytes retornados, seguido de estos valores. Aunque en realidad se está escribiendo en el rango de registros o valores numéricos , los registros son direccionados a partir de la dirección 0 ( así el registro @40001 se direcciona 0 )

Petición del máster (modo RTU):
   NºEsclavo
   Código Operación: 0x03 o 0x04
   Dirección del registro :
   Nº de datos que se desea leer: max 128 datos
   CRC(16): H L

Respuesta del esclavo (modo RTU):
   NºEsclavo
   Código Operación: 0x03 o 0x04
   Nº de bytes leidos: 1 byte
   Datos: ¿ max 128 datos ?
   CRC(16): H L

Ej 1:
   P:[01][03][01][00][00][06][C4][34]
   R:[01][03][0C][20][81][00][00][00][00][00][00][00][00][1C][01][76][F1]

Ej 2:
   P:[0A][04][00][00][00][0A][71][76]
   0A numero de periférico
   04 función de lectura
   00 00 registro donde se va a comenzar la lectura
   00 0A numero de registros a leer: 10
   71 76 CRC

   R:[0A][04][14][00][00][08][4D][00][00][23][28][00][00][0F][A0][00][00][00][90][00][00][00][60][CB][2E]
   0A Número del periférico que responde, 10 en decimal
   04 Función de lectura - la que se ha utilizado en la pregunta
   14 Número de bytes recibidos (20).
   00 00 08 4D V1x 10 (registro 00 Hex) con valor en decimal 212,5 V
   00 00 23 28 mA 1, en decimal 9000 mA
   00 00 0F A0 W 1, en decimal 4000 W
   00 00 00 90 varL 1, en decimal 144 varL
   00 00 00 60 PF1 x 100, en decimal 96
   CB 2E CRC

Ej 3:
   P:[01][03][00][30][00][10][44][09]
   Lectura en el esclavo @1 de 16 registros a paritir de la direccion 0x0030

   R:[01][03][20][00][00][00][00][00][00][00][00][00][00][00][00][00][00][00][00][00][00][00][00][00][00][27][0F][16][18][00][00][2E][DF][00][00][42][CF]
   01 direccion del esclavo que responde
   03 Función de lectura
   20 Numero de bytes recibidos
   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 27 0F 16 18 00 00 2E DF 00 00 Respuesta ( 32 bytes a 2 bytes por registro: 16 registros )
   42 CF CRC H L

Función 5 ( Force Single Coil ):
Permite modificar el estado de una DO del esclavo ( mando o relé ) . Es decir mediante este comando podemos modificar algún bit de alguna de las variables internas del esclavo u ordenar la ejecución o activación de un mando. Actúa sobre la zona de memoria de los DOs @0XXXX . El Maestro especifica la dirección del bit o mando que quiere modificar seguido de 0x00 para ponerlo a 0 o 0xFF para ponerlo a 1. El esclavo responde con una trama similar indicando la dirección que ha modificado y el valor que ha establecido en el bit o mando.

Petición del máster (modo RTU):
   NºEsclavo
   Código Operación: 0x05
   Dirección del bit:
   Estado para el bit: 0xXX ( 0x00 : 0 , 0xFF : 1 )
   Byte a 0x00
   CRC(16): H L

Respuesta del esclavo (modo RTU):
   NºEsclavo
   Código Operación: 0x05
   Dirección del bit:
   Estado para el bit: 0xXX ( 0x00 : 0 , 0xFF : 1 )
   Byte a 0x00
   CRC(16): H L

Ej 1 :
   P:[01][05][00][01][FF][00] [DD][FA]
   R:[01][05][00][00][FF][00][8C][3A]

Ej 2:
   P:[01][05][00][00][00][00][CD][CA]
   R:[01][05][00][01][00][00] [9C][0A]

Función 6 ( Preset Single Register ) :
Permite la escritura en las AOs del esclavo ( ya sea una señal o valor interno del equipo ), y por tanto actúa sobre la zona de memoria de las AOs ( @4XXXX ). Deberemos indicar la dirección del valor que queremos modificar y la magnitud que queremos asignarle. Luego el esclavo debería responder con la dirección del dato que ha modificado y el valor que le ha asignado, que debería coincidir con el enviado. Aunque en realidad se está escribiendo en el rango de AOs , los registros son direccionados a partir de la dirección 0 ( así el registro @40001 se direcciona 0 )

Petición del máster (modo RTU):
   NºEsclavo
   Código Operación: 0x06
   Dirección del dato:
   Valor del dato:
   CRC(16): H L

Respuesta del esclavo (modo RTU):
   NºEsclavo
   Código Operación: 0x06
   Dirección del dato:
   Valor del dato:
   CRC(16): H L

Ej:
   P:[01][06][01][F1][00][02][58][04]
   R:[01][06][01][F1][00][02][58][04]

Función 7 ( Read Exception Status ) :
Permite la lectura rápida de un byte fjo de un esclavo, que generalmente es el de excepción y que informa del estado del equipo. No tiene dirección del byte debido a que siempre se lee el mismo byte ( determinado por el propio dispositivo esclavo) :

Petición del master (modo RTU):
   NºEsclavo
   Código Operación: 0x07
   CRC(16): H L

Respuesta del esclavo (modo RTU):
   NºEsclavo
   Código Operación: 0x07
   Valor del octeto:
   CRC(16): H L

Función 15 ( Force Multiple Coils ):
Permite la modificación simultanea de varios bits de DOs en el esclavo, pasándolos a OFF ( ‘0’ ) o a ON ( ‘1’) según convenga. Actúa sobre la zona de memoria de las DOs ( @0XXXX ). Así en el comando se pasan la dirección inicial ( dirección del primer bit o mando a modificar ) y la cantidad y estado de cada uno de los sucesivos mandos ( bits ) a modificar.

Petición del máster (modo RTU):
   NºEsclavo
   Código Operación: 0x0F
   Dirección inicial de los mandos ( bits ) H
   Dirección inicial de los mandos ( bits ) L
   Cantidad de mandos ( bits ) H
   Cantidad de mandos ( bits ) L
   Cantidad de bytes enviados con el estado de los mandos ( bits )
   Estado de los 8 primeros mandos ( bits ) a modificar
   Estado de los 8 siguientes mandos ( bits ) a modificar
...
Estado de los 8 últimos mandos ( bits ) a modificar
CRC(16): H L

Aunque el estado de las DOs se especifica bit a bit, las tramas se componen de bytes, y esto obliga a enviar los estados en grupos de 8. El esclavo no debería hacer caso a los bits sobrantes, es decir, no debería considerar los que queden por encima del último bit indicado en el campo “cantidad de mandos a modificar”. Así, si quisiéramos modificar 12 mandos o relés a partir de la dirección 7, indicaríamos como dirección origen la dirección 7, como cantidad de mandos a modificar 12, y en el campo de estado de mandos: 0x3C , 0x0B ( el esclavo no considerará los que queden por encima del 12o bit )

  Relé: 14 13 12 11 10 09 08 07 - 22 21 20 19 18 17 16 15
  Bits:    0   1   1   1   1   0   0   0     X   X   X   X   1    0  1   1

Respuesta del esclavo (modo RTU):
   NºEsclavo
   Código Operación: 0x0F
   Dirección inicial de los mandos o bits consecutivos H
   Dirección del mando o bit L
   Cantidad de mandos o bits H
   Cantidad de mandos o bits L
   CRC(16): H L

Función 16 ( Preset multiple registers ):
Permite realizar la escritura en un grupo de AOs, y por tanto actúa sobre la zona de AOs ( @4XXXX ). Se debe especificar la dirección a partir de la que queremos comenzar a actualizar valores, el número de valores que queremos actualizar, y la lista de valores que queremos asignar a estos registros. Aunque se está escribiendo en el rango de registros o valores numéricos , los registros son direccionados a partir de la dirección 0 ( es decir el registro @40001 se direcciona 0 )

Petición del máster (modo RTU):
   NºEsclavo
   Código Operación: 0x10
   Dirección base de los datos: 2 bytes
   Número de datos: 2 bytes
   Valor del dato 0: 2 bytes
   Valor del dato 1: 2 bytes
   …
   Valor del dato n: 2 bytes
   CRC(16): H L

Respuesta del esclavo (modo RTU):
   NºEsclavo
   Código Operación: 10H
   Dirección base de los datos: 2 bytes
   Número de datos: 2 bytes
   CRC(16): H L

Función 20 ( Read General Reference ):
Retorna el contenido de los regitros de la Extended Memory ( @6XXXX ). En la trama se envía la dirección del esclavo, el código de función, el número de bytes que se va a leer y los bytes de comprobación de error. En los datos se establece el grupo o grupos o referencias a leer. Cada grupo se define en un campo "sub-request" que contiene:
    - Reference type: 1 byte ( debe ser 6 )
    - Extended Memory file number: 2 bytes ( 0x01 a 0x0A )
    - La direccion del "fichero" a partir de la que queremos comenzar a leer: 2 bytes
    - La cantidad de registros a leer: 2 bytes

Los datos a leer seguidos de los demas campos no debe superar la longitud máxima permitida en los mensajes MODBUS, es decir los 256 bytes.

Petición del máster (modo RTU):
    Slave Address 0x11
    Function 0x14
    Byte Count 0x0E
    Sub–Req 1, Reference Type 0x06
    Sub–Req 1, File Number Hi 0x00
    Sub–Req 1, File Number Lo 0x04
    Sub–Req 1, Starting Addr Hi 0x00
    Sub–Req 1, Starting Addr Lo 0x01
    Sub–Req 1, Register Count Hi 0x00
    Sub–Req 1, Register Count Lo 0x02
    Sub–Req 2, Reference Type 0x06
    Sub–Req 2, File Number Hi 0x00
    Sub–Req 2, File Number Lo 0x03
    Sub–Req 2, Starting Addr Hi 0x00
    Sub–Req 2, Starting Addr Lo 0x09
    Sub–Req 2, Register Count Hi 0x00
    Sub–Req 2, Register Count Lo 0x02
    Error Check (LRC or CRC)--

Respuesta del esclavo (modo RTU):
    Slave Address 0x11
    Function 0x14
    Byte Count 0x0C
    Sub–Res 1, Byte Count 0x05
    Sub–Res 1, Reference Type 0x06
    Sub–Res 1, Register Data Hi 0x0D
    Sub–Res 1, Register Data Lo 0xFE
    Sub–Res 1, Register Data Hi 0x00
    Sub–Res 1, Register Data Lo 0x20
    Sub–Res 2, Byte Count 0x05
    Sub–Res 2, Reference Type 0x06
    Sub–Res 2, Register Data Hi 0x33
    Sub–Res 2, Register Data Lo 0xCD
    Sub–Res 2, Register Data Hi 0x00
    Sub–Res 2, Register Data Lo 0x40
    Error Check (LRC or CRC) ––––

Función 21 ( Write General Reference ):
Modifica el contenido de los registros de la Extended Memory ( 6XXXX ). Esta función permite trabajar en grupos de registros que no tienen porque ser contiguos ( internamente sí que han de ser contiguos ). Cada grupo se define en un campo "sub-request" que contiene:
    - Reference type: 1 byte ( debe ser 6 )
    - Extended Memory file number: 2 bytes ( 0x01 a 0x0A )
    - La direccion del "fichero" a partir de la que queremos comenzar a leer: 2 bytes
    - La cantidad de registros a leer: 2 bytes

Los datos a leer seguidos de los demas campos no debe superar la longitud máxima permitida en los mensajes MODBUS, es decir los 256 bytes.

Petición del máster (modo RTU):
    Slave Address 0x11
    Function 0x5
    Byte Count 0x0D
    Sub–Req 1, Reference Type 0x06
    Sub–Req 1, File Number Hi 0x00
    Sub–Req 1, File Number Lo 0x04
    Sub–Req 1, Starting Addr Hi 0x00
    Sub–Req 1, Starting Addr Lo 0x07
    Sub–Req 1, Register Count Hi 0x00
    Sub–Req 1, Register Count Lo 0x03
    Sub–Req 1, Register Data Hi 0x06
    Sub–Req 1, Register Data Lo 0xAF
    Sub–Req 1, Register Data Hi 0x04
    Sub–Req 1, Register Data Lo 0xBE
    Sub–Req 1, Register Data Hi 0x10
    Sub–Req 1, Register Data Lo 0x0D
    Error Check (LRC or CRC) ––

Respuesta del esclavo (modo RTU):
    Slave Address 0x11
    Function 0x15
    Byte Count 0x0D
    Sub–Req 1, Reference Type 0x06
    Sub–Req 1, File Number Hi 0x00
    Sub–Req 1, File Number Lo 0x04
    Sub–Req 1, Starting Addr Hi 0x00
    Sub–Req 1, Starting Addr Lo 0x07
    Sub–Req 1, Register Count Hi 0x00
    Sub–Req 1, Register Count Lo 0x03
    Sub–Req 1, Register Data Hi 0x06
    Sub–Req 1, Register Data Lo 0xAF
    Sub–Req 1, Register Data Hi 0x04
    Sub–Req 1, Register Data Lo 0xBE
    Sub–Req 1, Register Data Hi 0x10
    Sub–Req 1, Register Data Lo 0x0D
    Error Check (LRC or CRC) ––

 
Regresar al índice de documentos