Como converter Arduino em um dispositivo Modbus

Cómo convertir Arduino a un dispositivo Modbus

Modbus es un protocolo de comunicación ampliamente utilizado y un estándar de redes industriales de código abierto. Desarrollado en 1979 por Modicon (ahora Schneider Electric), Modbus se ha convertido en un estándar en las industrias de automatización y sistemas de control industrial (ICS).

El protocolo de comunicación es conocido por su simplicidad y su función de resolución de problemas fácil de seguir. Utiliza un modelo de comunicación maestro-esclavo o cliente-servidor, donde un dispositivo maestro o cliente inicia solicitudes para leer o escribir datos en dispositivos o servidores esclavos.

El protocolo estándar es independiente del hardware, lo que significa que se puede implementar en múltiples dispositivos y plataformas, incluidos diferentes tipos de microcontroladores (incluido Arduino) y sistemas operativos. Modbus admite varios tipos de datos, incluidas entradas discretas, bobinas (salidas digitales), registros de entrada y registros de retención (datos analógicos). Maneja datos analógicos y digitales.

Modbus se ha utilizado de manera confiable en entornos industriales durante décadas para automatización, gestión de energía, automatización de edificios, sistemas SCADA, monitoreo agrícola, sistemas de control de bombas y motores, y más. Las unidades terminales remotas (RTU) a menudo lo utilizan para transmitir datos a un centro de control central. Modbus también se puede adaptar fácilmente a requisitos de aplicaciones específicas cuando se utilizan otros protocolos industriales o estándares de comunicación.

Una ventaja de utilizar Modbus en Arduino es su capacidad para manejar comunicaciones de datos complejas a largas distancias. Por ejemplo, Arduino puede comunicarse con software/aplicaciones, interfaces hombre-máquina, dispositivos periféricos o microcontroladores. Modbus es adecuado para aplicaciones de automatización pequeñas y medianas e ideal para proyectos centrados en costos.

Los protocolos Modbus tienen tres tipos: Modbus ASCII, Modbus RTU y Modbus TCP. En este artículo, convertiremos Arduino en un dispositivo Modbus utilizando Modbus ASCII/RTU y Modbus TCP. Para ello configuraremos la comunicación entre dos placas Arduino en Modbus.

¿Qué es Modbus?
Modbus es un popular protocolo de comunicación en serie, abierto y de baja velocidad, comúnmente utilizado en la industria de la automatización y mantenido por la organización Modbus. Sirve como enlace entre los PLC y los dispositivos de automatización inteligentes.

Con la ayuda del protocolo serie, que se basa en una configuración maestro-esclavo, un cliente Modbus puede establecer contacto con hasta 247 servidores Modbus. Los puertos estándar RS-485 o RS-232 facilitan la interfaz física. El bus incluye un par de cables trenzados, aislados o no, con ambos extremos terminados en 150 ohmios. El cable se puede conectar rápidamente a dispositivos mediante conectores RJ-45, terminales de tornillo o conectores tipo D de 9 pines.

El cliente Modbus suele ser una computadora supervisora ​​dentro de una interfaz hombre-máquina (HMI) o un sistema de control de supervisión y adquisición de datos (SCADA). Las unidades terminales remotas (RTU), como módulos de sensores, controladores lógicos programables (PLC) o controladores de automatización programables (PAC), son los servidores Modbus. Para obtener más información sobre el protocolo Modbus, consulte este enlace .

¿Por qué Modbus?
Modbus es un protocolo versátil y confiable. Actualmente es el dispositivo más utilizado para la automatización industrial. Es el estándar de comunicación para conectar y controlar dispositivos como PLC, sensores, actuadores y HMI. También puede recopilar datos de medidores de energía, monitorear el consumo de energía y controlar sistemas HVAC (calefacción, ventilación y aire acondicionado). También puede integrar múltiples subsistemas de edificios, incluidos iluminación, HVAC, seguridad y control de acceso.

Modus es ideal para aplicaciones de telemetría y monitoreo remoto, incluido el monitoreo de condiciones ambientales, niveles de agua o estado de equipos en ubicaciones remotas. Debido a que el protocolo puede manejar datos analógicos y digitales de manera eficiente, también es ideal para adquirir datos de sensores e instrumentos en entornos de laboratorio, investigación y pruebas.

El protocolo se utiliza a menudo como protocolo de comunicación en sistemas SCADA para recopilar datos de dispositivos de campo remotos.

Modbus es versátil y confiable para prácticamente cualquier tipo de aplicación de automatización, ya sea pequeña o mediana. Permite comunicación half y full-duplex a largas distancias. Modbus RTU puede extenderse hasta 1200 metros (en RS-485), mientras que Modbus TCP no tiene límite de alcance. Modbus también permite la comunicación bidireccional entre dispositivos y se conecta a múltiples dispositivos en una red.

¿Cuándo utilizar Modbus con Arduino?
Si Arduino necesita interactuar con un PLC, HMI o dispositivo periférico, Modbus es la opción obvia. Permite a Arduino comunicarse con cualquier microcontrolador o dispositivo en un rango extendido.

Las aplicaciones de automatización del hogar o de la oficina pueden beneficiarse del protocolo, ya que permite que el maestro y el esclavo se comuniquen en ambas direcciones.

Los protocolos de comunicación típicos como UART, I2C y SPI disponibles en microcontroladores (incluido Arduino) tienen sus propias limitaciones. Cuando una red se vuelve muy compleja y varios dispositivos necesitan comunicarse bidireccionalmente, Modbus es el protocolo de comunicación ideal para manejar esta complejidad sin complicar los circuitos o el código.

Para las redes de sensores en Arduino, Modbus nuevamente garantiza una comunicación confiable, de largo alcance, centralizada y bien administrada.

¿Cómo funciona Modbus?
Una red Modbus puede tener uno o más dispositivos maestros y varios dispositivos esclavos. El dispositivo maestro se denomina cliente Modbus y los esclavos son servidores Modbus.

En las versiones serie de Modbus, un dispositivo maestro puede comunicarse con hasta 247 dispositivos. La versión Ethernet permite que un maestro se comunique con cientos de dispositivos en un único segmento de red Ethernet.

La comunicación se basa en un método de solicitud-respuesta. El maestro envía una solicitud a uno o más dispositivos esclavos, especificando el tipo de operación (lectura o escritura) y la dirección de los datos a los que desea acceder. Los tipos de datos que se pueden leer o escribir incluyen entradas discretas (datos binarios), bobinas (salidas binarias), registros de entrada (datos analógicos) y registros de retención (datos analógicos).

Cada punto de datos en una red Modbus tiene una dirección única. El maestro especifica la dirección de los datos a los que desea acceder en la solicitud cuando se comunica con un esclavo. Por ejemplo, un dispositivo Modbus puede tener entradas discretas que comienzan en la dirección 1, bobinas que comienzan en la dirección 10001, registros de entrada que comienzan en la dirección 30001 y registros de retención que comienzan en la dirección 40001.

Para una solicitud Modbus, el tipo de operación se especifica mediante un código de función. Los códigos de función comunes incluyen F01 (Leer entradas discretas), F02 (Leer bobinas), F03 (Leer registros de entrada analógica), F04 (Leer registros de retención de salida analógica), F05 (Escribir bobina única), F06 (Escribir registro de retención única), F15 (Escribir múltiples bobinas) y F16 (Escribir múltiples registros de retención). Cuando un dispositivo esclavo recibe una solicitud válida, procesa la solicitud y envía una respuesta al maestro. La respuesta contiene los datos solicitados o una confirmación de una operación de escritura exitosa. El maestro normalmente sondea los dispositivos esclavos a intervalos regulares para recopilar datos o emitir comandos.

Existen mecanismos de verificación de errores como CRC o LRC para garantizar la integridad de los datos durante la transmisión. La respuesta proporciona códigos de error para indicar problemas como solicitudes no válidas o problemas de comunicación. Para obtener más información sobre cómo funciona Modbus, consulte este enlace .

Modbus RTU/ASCII y Modbus TCP
Hay tres tipos populares de Modbus: Modbus RTU, Modbus ASCII y Modbus TCP. Aunque Modbus RTU y Modbus ASCII son versiones de protocolo diferentes, ambos se utilizan en entornos de comunicación en serie como RS-232, RS-422 y RS-485.

Modbus RTU se asocia más comúnmente con RS-485 debido a su naturaleza binaria. Muchos dispositivos admiten Modbus ASCII y Modbus RTU. Modbus ASCII y Modbus RTU se pueden implementar con el mismo hardware en Arduino. Sin embargo, es importante distinguir entre ellos.

  • Modbus RTU representa datos en formato binario como valores binarios sin formato de 8 bits, mientras que para Modbus ASCII, los datos se transmiten como caracteres ASCII, donde dos caracteres ASCII representan cada byte.
  • Las tramas Modbus RTU constan de datos binarios con bits de inicio y parada para sincronización, mientras que las tramas Modbus ASCII comienzan con dos puntos (“:”) y terminan con un retorno de carro y una secuencia de avance de línea (“\ r\n”).
  • Modbus RTU utiliza verificación de redundancia cíclica (CRC) para la detección de errores en la trama de datos, mientras que Modbus ASCII usa LRC (verificación de redundancia longitudinal) para la detección de errores. Modbus RTU se utiliza comúnmente en aplicaciones industriales, especialmente en entornos que requieren comunicación de alta velocidad.
  • Se prefiere Modbus ASCII cuando la comunicación legible o la resolución de problemas son esenciales. Un microcontrolador debe utilizar Modbus RTU cuando se comunica con módulos de sensores. Pero cuando se comunica con dispositivos HMI, Modbus ASCII es una mejor solución.
  • Modbus TCP opera en redes Ethernet utilizando el conjunto de protocolos TCP/IP. Modbus RTU/ASCII son los más adecuados para redes serie punto a punto o multipunto. Modbus TCP está diseñado para redes de área local (LAN) basadas en Ethernet y puede comunicarse a distancias más largas utilizando equipos de red estándar.
  • Modbus TCP utiliza tramas Ethernet estándar, que difieren de las tramas de datos Modbus RTU/ASCII. Se basa en TCP/IP para un transporte de datos fiable. Modbus RTU/ASCII requiere topologías de red punto a punto o multipunto. Modbus TCP es muy flexible y permite topologías de red como configuraciones en estrella, bus o anillo.
  • Modbus RTU/ASCII solo admite transacciones individuales. Cuando un maestro envía una solicitud a través de Modbus RTU/ASCII, debe esperar una respuesta Modbus o un tiempo de espera antes de enviar otra solicitud. Sin embargo, Modbus TCP admite múltiples transacciones, por lo que un maestro puede enviar múltiples solicitudes en Modbus TCP y no necesita esperar una respuesta o un tiempo de espera de Modbus. La respuesta a una solicitud se identifica mediante un ID de transacción, donde el ID de transacción sigue siendo el mismo para la solicitud y la respuesta.
  • Aunque Modbus RTU/ASCII se utiliza comúnmente en sistemas de control y automatización industrial donde predomina la comunicación en serie, Modbus TCP es más adecuado para redes industriales modernas y automatización de edificios.

Convertir Arduino en un dispositivo Modbus
Si Arduino necesita comunicarse con un PLC o dispositivo HMI, primero debe convertir Arduino en un dispositivo Modbus. El Arduino se puede configurar fácilmente para participar en redes Modbus RTU/ASCII/TCP. Para ello, se necesitan componentes de hardware y software.

Para implementar Modbus RTU/ASCII, Arduino debe comunicarse a través de los puertos RS-485, RS-422 o RS-232. RS-485 es el puerto más popular de utilizar. Esto requiere conectar el Arduino con un convertidor RS-485 a TTL. También se requiere la biblioteca Arduino Modbus.

Para implementar Modbus TCP, Arduino debe comunicarse a través de la pila TCP/IP. Esto requiere un escudo Ethernet sobre Arduino. Se requiere la biblioteca Arduino Modbus, que se puede descargar desde este enlace de Github .

Convertidor RS485 a TTL
Para convertir el Arduino a una red Modbus RTU/ASCII como maestro o esclavo, se requiere un transceptor RS485 o un conversor RS485 a TTL. Uno de estos transceptores basados ​​en el chip MAX485 se muestra en la imagen a continuación.

En un Modbus, un '0' binario está representado por un nivel de voltaje de +2 a +6V. El '1' binario está representado por un nivel de voltaje de -2 a -6 V. Arduino opera en niveles lógicos TTL, por lo que se requiere un convertidor lógico como se muestra arriba.

Un transceptor RS485 tiene el siguiente diagrama de pines.

La configuración de pines del transceptor RS-485 se describe en la siguiente tabla.

Para utilizar el módulo como transmisor, conecte los pines RE y DE a 5V y conecte el pin DI al pin TX del Arduino. Los datos se envían desde el pin TX del Arduino al pin DI del módulo, que luego se envía a través del AB.

Para usar el módulo como receptor, conecte los pines RE y DE a tierra y conecte el pin RO al pin RX del Arduino. Los datos recibidos por el AB se envían al pin RO, que está conectado al pin RX del Arduino; por lo tanto, el Arduino lee los datos.

Biblioteca Modbus Arduino
ArduinoModbus es una biblioteca gratuita y de código abierto para que las placas Arduino se comuniquen con dispositivos Modbus a través de conexiones serie (RS485) y de red (TCP). Se basa en la biblioteca libmodbus, pero se ha modificado para utilizar las API Arduino Serial/RS485 y Client. Es una API fácil de usar para enviar y recibir mensajes Modbus, manejar tramas Modbus y comprobar errores. También admite todos los códigos de función Modbus.

La biblioteca es compatible con las arquitecturas megaavr, samd, mbed_nano, mbed_portenta y mbed_opta y se puede utilizar en Arduino Uno, Arduino Nano, Arduino Mega, Arduino Due, Arduino MKR Zero, Arduino MKR 1000, Arduino MKR WiFi 1010, Arduino MKR WAN 1310. , Arduino MKR FOX 1200, Arduino MKR GSM 1400, Arduino MKR NB 1500, Arduino Portenta H7, Arduino Nano 33 IoT y Arduino Nano RP2040 Connect.

También se puede utilizar en otras placas compatibles con Arduino como Genuino M100 y Adafruit Feather M0. La biblioteca se puede instalar a través del administrador de bibliotecas Arduino IDE o descargar desde este enlace de Github.

La biblioteca proporciona el siguiente método para configurar Arduino como cliente Modbus RTU.

modbusRTUClient.begin:

La función inicia el cliente Modbus RTU con los parámetros especificados. La función devuelve '1' en caso de éxito y '0' en caso de error. Tiene la sintaxis siguiente.

ModbusRTUClient.begin(velocidad en baudios);
ModbusRTUClient.begin(velocidad en baudios, configuración);

La biblioteca proporciona los siguientes métodos para configurar Arduino como cliente Modbus TCP.

ModbusTCPClient: el método crea un cliente Modbus TCP utilizando el cliente proporcionado para el transporte. El método tiene la siguiente sintaxis:

ModbusTCPCliente(cliente);

modbusTCPClient.begin: el método inicia el cliente Modbus TCP con los parámetros especificados. Tiene esta sintaxis:

modbusTCPClient.begin(ip,puerto);

modbusTCPClient.connected: el método devuelve el estado de la conexión. Tiene esta sintaxis:

modbusTCPClient.conectado;

modbusTCPClient.stop: El método desconecta el servidor. Tiene esta sintaxis:

modbusTCPClient.stop;

La biblioteca proporciona el siguiente método para configurar Arduino como un servidor Modbus RTU.

modbusRTUServer.begin: el método inicia el servidor Modbus RTU con los parámetros especificados. La función devuelve '1' en caso de éxito o '0' en caso de error. Tiene la siguiente sintaxis:

ModbusRTUServer.begin(id, velocidad en baudios);
ModbusRTUServer.begin(id, velocidad en baudios, configuración);

La biblioteca proporciona los siguientes métodos para configurar Arduino como un servidor Modbus TCP.

ModbusTCPServer: el método crea un servidor Modbus TCP. Tiene la siguiente sintaxis.

Servidor ModbusTCPSer;

modbusTCPServer.begin: el método inicia el servidor Modbus. Puede requerir que se pase el ID del esclavo como argumento. Si no se proporciona ningún ID, el valor predeterminado es 0xFF (TCP). Tiene esta sintaxis:

modbusTCPserver.begin;
modbusTCPserver.begin(id);

modbusTCPServer.accept: el método acepta una conexión de cliente. Tiene esta sintaxis:

modbusTCPserver.accept(cliente);

La biblioteca proporciona los siguientes métodos para operar como cliente Modbus.

client.coilRead: el método realiza una operación de "Lectura de bobinas" para la dirección especificada para una sola bobina. Toma ID de esclavo y/o dirección como argumentos. Tiene esta sintaxis:

int coilRead (dirección interna);
int coilRead(int id, int dirección);

client.discreteInputRead: el método realiza una operación de “Leer entradas discretas” para la dirección especificada para una única entrada discreta. Toma ID de esclavo y/o dirección como argumentos. Tiene esta sintaxis:

int discreteInputRead(dirección int);
int discreteInputRead(int id, dirección interna);

client.holdingRegisterRead: el método realiza una operación de "Leer registros retenidos" para un único registro retenido. Toma ID de esclavo y/o dirección como argumentos. Tiene esta sintaxis:

retención prolongadaRegisterRead(dirección int);
retención largaRegisterRead(int id, int dirección);

client.inputRegisterRead: el método realiza una operación de "Leer registros de entrada" para un único registro de entrada. Toma ID de esclavo y/o dirección como argumentos. Tiene esta sintaxis:

inputRegisterRead long (dirección int);
inputRegisterRead long (int id, dirección interna);

client.coilWrite: el método realiza una operación de “Escribir bobina única” en la dirección y el valor especificados. La identificación del esclavo de destino, la dirección de operación y el valor de la bobina deben escribirse como argumentos. Tiene esta sintaxis:

int coilWrite(dirección int, valor uint8_t);
int coilWrite(int id, int dirección, valor uint8_t);

client.holdingRegisterWrite: el método realiza una operación de "Escribir registro de retención único" en la dirección y el valor especificados. Se necesitan el ID del esclavo de destino, la dirección de operación y el valor del registro de retención para escribir como argumentos. Tiene esta sintaxis:

int holdingRegisterWrite(dirección int, valor uint16_t);
int holdingRegisterWrite(int id, int dirección, valor uint16_t);

client.registerMaskWrite: el método realiza una operación de “Registros de escritura de máscara” para la dirección especificada, máscara AND y máscara OR. Toma como argumentos el ID del esclavo de destino, la dirección de operación, la máscara AND para usar en la operación y la máscara OR para usar en la operación. Tiene esta sintaxis:

int RegisterMaskWrite(dirección int, uint16_t eMask, uint16_t ouMask);
int RegisterMaskWrite(int id, int dirección, uint16_t yMask, uint16_t oMask);

client.beginTransmission: el método inicia el proceso de grabación de varios carretes o retención de registros. Toma el ID del esclavo de destino, el tipo de grabación a realizar (COILS o HOLDING_REGISTERS), la dirección de la operación y la cantidad de valores a escribir como argumentos. Tiene esta sintaxis:

int startTransmission(int tipo, int dirección, int nb);
int startTransmission(int id, int tipo, int dirección, int nb);

client.write: el método establece los valores de una operación de escritura iniciada por beginTransmission. Se necesita valor para escribir como argumento. El método devuelve '1' en caso de éxito o '0' en caso de error. Tiene esta sintaxis:

escritura int (valor int sin signo);

client.endTransmission: el método finaliza el proceso de grabación de varios carretes o retención de registros. Devuelve '1' en caso de éxito o '0' en caso de error. Tiene esta sintaxis:

int endTransmisión;

client.requestFrom: el método lee múltiples bobinas, entradas discretas, registros de retención o valores de registros de entrada. Utiliza disponible y leído para procesar los valores leídos. Toma el ID del esclavo de destino, el tipo de lectura a realizar (COILS, DISCRETE_INPUTS, HOLDING_REGISTERS o INPUT_REGISTERS), la dirección inicial a utilizar para la operación y el número de valores a leer como argumentos. Tiene esta sintaxis:

int requestFrom(int tipo, int dirección, int nb);
int requestFrom(int id, int tipo, int dirección, int nb);

client.available: el método consulta la cantidad de valores disponibles para leer después de llamar a requestFrom. Tiene la siguiente sintaxis.

int disponible;

client.read: el método lee un valor después de llamar a requestFrom. Devuelve -1 en caso de error y un valor en caso de éxito. Tiene esta sintaxis:

lectura larga;

client.lastError: el método lee el motivo del último error como una cadena. Tiene esta sintaxis:

const char* últimoError;

client.end: el método detiene el cliente y realiza la limpieza. Tiene esta sintaxis:

extremo vacío;

La biblioteca proporciona los siguientes métodos para operar como servidor Modbus.

modbusServer.configureCoils: el método configura las bobinas del servidor. Se requiere la dirección inicial de las bobinas y el número de bobinas a configurar como argumentos. Tiene la siguiente sintaxis:

int configureCoils(int dirección de inicio, int nb);

modbusServer.configureDiscreteInputs: el método configura las entradas discretas del servidor. Devuelve '0' en caso de éxito o '1' en caso de error. Se requiere el inicio de la dirección de las entradas discretas y el número de entradas discretas a configurar como argumentos. Tiene esta sintaxis:

int configureDiscreteInputs(int startAddress, int nb);

modbusServer.configureHoldingRegisters: el método configura los registros de tenencia del servidor. Se necesita el comienzo de la dirección de los registros de retención y el número de registros de retención para configurar como argumentos. Tiene esta sintaxis:

int configureHoldingRegisters(int dirección de inicio, int nb);

modbusServer.configureInputRegisters: el método configura los registros de entrada del servidor. Se necesita el comienzo de la dirección de los registros de entrada y el número de registros de entrada para configurar como argumentos. Tiene esta sintaxis:

int configureInputRegisters(int dirección de inicio, int nb);

modbusServer.coilRead: el método realiza una operación de "lectura de bobinas" para la dirección especificada para una sola bobina. Necesita el ID y/o la dirección del esclavo de destino para utilizarlo en la operación como argumentos. Tiene esta sintaxis:

int coilRead (dirección interna);
int coilRead(int id, int dirección);

modbusServer.discreteInputRead: el método realiza una operación de “Leer entradas discretas” para la dirección especificada para una única entrada discreta. Necesita el ID y/o la dirección del esclavo de destino para utilizarlo en la operación como argumentos. Tiene esta sintaxis:

int discreteInputRead(dirección int);
int discreteInputRead(int id, dirección interna);

modbusServer.holdingRegisterRead: el método realiza una operación de "Leer registros retenidos" para un único registro retenido. Toma como argumentos el ID del esclavo de destino y el inicio de la dirección a utilizar en la operación. Tiene esta sintaxis:

retención prolongadaRegisterRead(dirección int);
retención largaRegisterRead(int id, int dirección);

modbusServer.inputRegisterRead: el método realiza una operación de "Leer registros de entrada" para un único registro de entrada. El ID del esclavo de destino y la dirección que se utilizará en la operación se requieren como argumentos. Tiene esta sintaxis:

inputRegisterRead long (dirección int);
inputRegisterRead long (int id, dirección interna);

modbusServer.coilWrite: el método realiza una operación de “Escribir bobina única” para la dirección y el valor especificados. Se requiere el ID del esclavo de destino, la dirección que se utilizará para la operación y el valor de la bobina que se escribirá como argumentos. Tiene esta sintaxis:

int coilWrite(dirección int, valor uint8_t);
int coilWrite(int id, int dirección, valor uint8_t);

modbusServer.holdingRegisterWrite: el método realiza una operación de “Escribir registro de retención único” en la dirección y el valor especificados. Toma el ID del esclavo de destino, la dirección que se utilizará para la operación y el valor del registro de retención para escribir como argumentos. Tiene esta sintaxis:

int holdingRegisterWrite(dirección int, valor uint16_t);
int holdingRegisterWrite(int id, int dirección, valor uint16_t);

modbusServer.registerMaskWrite: el método realiza una operación de “Registros de escritura de máscara” para la dirección especificada, máscara AND y máscara OR. Toma como argumentos el ID del esclavo de destino, la dirección que se utilizará para la operación, la máscara AND que se utilizará para la operación y la máscara OR AND que se utilizará para la operación. Tiene esta sintaxis:

int RegisterMaskWrite(dirección int, uint16_t eMask, uint16_t ouMask);
int registroMaskWrite(int id, int dirección, uint16_t yMask, uint16_t oMask);

modbusServer.discreteInputWrite: el método escribe el valor de entrada discreta del servidor en la dirección y el valor especificados. Necesita una dirección para usar en la operación y un valor discreto para escribir como argumentos. Tiene esta sintaxis:

int discreteInputWrite (dirección int, valor uint8_t);

modbusServer.writeDiscreteInputs: el método escribe valores en las entradas discretas del servidor en la dirección y los valores especificados. Requiere la dirección que se utilizará para la operación, la matriz de valores de entrada discretos que se escribirán y el número de entradas discretas que se escribirán como argumentos. Tiene esta sintaxis:

int writeDiscreteInputs(dirección int, valores uint8_t, int nb);

modbusServer.inputRegisterWrite: el método escribe el valor del registro de entrada del servidor en la dirección y el valor especificados. Se requieren la dirección que se utilizará para la operación y el valor del registro de entrada que se escribirá como argumentos. Tiene esta sintaxis:

int inputRegisterWrite(dirección int, valor uint16_t);

modbusServer.writeInputRegisters: el método escribe valores en los registros de entrada del servidor para la dirección y los valores especificados. Requiere la dirección que se utilizará para la operación, la matriz de valores de registros de entrada que se escribirán y el número de registros de entrada que se escribirán como argumentos. Tiene esta sintaxis:

int writeInputRegisters(dirección int, valores uint16_t, int nb);

modbusServer.poll: el método sondea las solicitudes. Tiene la siguiente sintaxis:

encuesta nula virtual = 0;

modbusServer.end: el método para el servidor. Tiene la siguiente sintaxis:

extremo vacío;

Ejemplo de Arduino Modbus RTU
Para configurar la comunicación entre dos placas Arduino usando Modbus RTU y la biblioteca Arduino Modbus, primero conecte las dos placas Arduino usando un transceptor RS485. Necesitará un par de transceptores RS485: uno para configurar un Arduino como cliente Modbus y otro para configurar otro Arduino como servidor Modbus.

  • Para configurar la primera placa Arduino como transmisor Modbus, conecte los pines RE y DE del módulo a 5 V y conecte el pin DI del módulo al pin TX del Arduino.
  • Para configurar la otra placa Arduino como receptor Modbus, conecte los pines RE y DE del módulo a tierra y conecte el pin RO del módulo al pin RX del Arduino.
  • Luego conecte los pines de 5V y tierra de ambos módulos con la salida de 5V y GND de los respectivos Arduino. Luego conecte los pines de datos B y A de un módulo a los pines de datos B y A del otro módulo.

Las conexiones del circuito se muestran a continuación.

Sube el siguiente boceto al Arduino configurado como transmisor Modbus.

#incluir “ArduinoModbus.h”
Maestro ArduinoModbus;
configuración vacía {
Serie.begin(9600);
maestro.comenzar;
}
bucle vacío {
// Envía una solicitud de lectura Modbus a la dirección de esclavo 1 y lee 10 registros comenzando en la dirección de registro 0
respuesta interna = master.read(1, 0, 10);
//Comprueba la respuesta
si (respuesta == 0) {
// La solicitud fue exitosa, obtiene los valores leídos del buffer de respuesta
valores uint16_t(10);
master.getResponseBuffer(valores, 10);
//Hacer algo con los valores leídos
Serial.println(“Leer valores:”);
para (int i = 0; i < 10; i++) {
Serial.print(valores(i));
Serie.print(" ");
}
Serial.println;
}
otro {
//La solicitud falló
Serial.println(“Error en la solicitud de lectura”);
}
//Espera 1 segundo antes de enviar la siguiente solicitud.
retraso(1000);
}

Sube el siguiente boceto al Arduino configurado como receptor Modbus.

#incluir “ArduinoModbus.h”
Esclavo ArduinoModbus(1);
configuración vacía {
//Configura la comunicación serie
Serie.begin(9600);
// Inicializa el esclavo Modbus
esclavo.comenzar;
}
bucle vacío {
// Comprueba las solicitudes Modbus entrantes
solicitud int = esclavo.disponible;
//Si hay una solicitud, la procesamos
si (solicitud > 0) {
// Obtiene el tipo de solicitud
tipo de byte = esclavo.getRequestType(solicitud);
// Si la solicitud es de lectura, envía los valores leídos al maestro
si (tipo == MODBUS_READ) {
// Obtener la dirección del registro y el número de registros para leer
dirección de palabra = esclavo.getRequestAddress (solicitud);
recuento de bytes = esclavo.getRequestCount(solicitud);
//Leer los registros de memoria de Arduino
valores uint16_t (recuento);
para (int i = 0; i < contar; i++) {
valores (i) = esclavo.readRegister (dirección + i);
}
//Envía los valores leídos al maestro
esclavo.sendResponse(solicitud, valores, recuento);
}
}
}

Puede observar los valores transmitidos entre dos Arduino en el monitor serie del IDE de Arduino conectando cualquiera de los Arduino a una computadora.

Ejemplo de Arduino Modbus TCP
Para configurar la comunicación entre las dos placas Arduino utilizando Modbus TCP y la biblioteca Arduino Modbus, instale protectores Ethernet en ambas placas y conecte ambos Arduinos a la misma red mediante cables Ethernet o una conexión WiFi.

Sube el siguiente boceto al Arduino configurado como transmisor Modbus.

#incluir “ArduinoModbus.h”
Maestro ArduinoModbus;
configuración vacía {
//Configura la comunicación serie
Serie.begin(9600);
// Conéctese a la placa Arduino esclava a la dirección IP de su red
master.connect(“DIRECCIÓN_IP”);
}
bucle vacío {
// Envía una solicitud de lectura Modbus a la dirección de esclavo 1 y lee 10 registros comenzando en la dirección de registro 0
respuesta interna = master.read(1, 0, 10);
//Comprueba la respuesta
si (respuesta == 0) {
//La solicitud fue exitosa
// Obtiene los valores leídos del buffer de respuesta
valores uint16_t(10);
master.getResponseBuffer(valores, 10);
//Hacer algo con los valores leídos
Serial.println(“Leer valores:”);
para (int i = 0; i < 10; i++) {
Serial.print(valores(i));
Serie.print(" ");
}
Serial.println;
} otro {
//La solicitud falló
Serial.println(“Error en la solicitud de lectura”);
}
//Espera 1 segundo antes de enviar la siguiente solicitud.
retraso(1000);
}

Sube el siguiente boceto al Arduino configurado como receptor Modbus.

#incluir “ArduinoModbus.h”
Esclavo ArduinoModbus(1);

configuración vacía {
//Configura la comunicación serie
Serie.begin(9600);
//Iniciamos el servidor Modbus
esclavo.beginServer;
}

bucle vacío {
// Comprueba las solicitudes Modbus entrantes
solicitud int = esclavo.disponible;
//Si hay una solicitud, la procesamos
si (solicitud > 0) {
// Obtiene el tipo de solicitud
tipo de byte = esclavo.getRequestType(solicitud);
// Si la solicitud es de lectura, envía los valores leídos al maestro
si (tipo == MODBUS_READ) {
// Obtener la dirección del registro y el número de registros para leer
dirección de palabra = esclavo.getRequestAddress (solicitud);
recuento de bytes = esclavo.getRequestCount(solicitud);
//Leer los registros de memoria de Arduino
valores uint16_t (recuento);
para (int i = 0; i < contar; i++) {
valores (i) = esclavo.readRegister (dirección + i);
}
//Envía los valores leídos al maestro
esclavo.sendResponse(solicitud, valores, recuento);
}
}
}

Puede observar los valores transmitidos entre las dos placas Arduino en el monitor serie del IDE de Arduino conectando cualquiera de las placas a una computadora.

contenido relacionado

Regresar al blog

Deja un comentario

Ten en cuenta que los comentarios deben aprobarse antes de que se publiquen.