Busca en nuestro Blog. Encontrarás múltiples aplicaciones, soluciones, ejemplos de código. Navega utilizando la nube de etiquetas o busca utilizando criterios específicos

Cómo conectar los PLCs basados en Arduino usando Modbus TCP/IP

Configuración maestro/esclavo

Introducción

Modbus es un estándar muy útil que nos permite comunicar varios dispositivos de diferentes fabricantes en la misma red. Además Modbus TCP/IP se transfiere a través de Ethernet que es uno de los protocolos más fiables del mercado

En este post, te enseñamos cómo configurar dos PLCs industriales basados en Arduino,  M-Duinos, uno funcionando como maestro y el otro como esclavo.

Modbus

Requisitos

Controlador industrial basado en Arduino Modbus TCPs TCP/IP Master/Slave ejemplos:

Sigue la publicación anterior para ver el código esclavo que hemos utilizado en este ejemplo: 

Cómo usar la biblioteca Modbus TCP Slave con un controlador PLC Arduino      Lee el post >>

También echa un vistazo a la publicación maestra para ver cómo utilizar la biblioteca Modbus, pero para el maestro hemos cambiado el código un poco con el fin de hacerlo más interactivo con el usuario:

Modbus TCP Master con PLCs basados en Arduino industrial     Lee el post >>

Arquitectura de aplicaciones

M-Duino master tiene un menú serie interactivo que permite al usuario controlar la aplicación.El menú tiene 6 opciones. Las primeras cuatro opciones son controlar dos salidas del esclavo,la quinta opción es obtener las entradas analógicas o registros del esclavo y la última opción,es obtener las entradas digitales o entradas discretas del esclavo.

Usamos las funciones use writeSingleCoil(), readInputRegisters() y readDiscreteInputs() para comunicarnos con el esclavo.  A continuación, simplemente ejecutando un corto  loop dependiendo del mensaje que hayamos enviado, leemos los valores usando  response.getRegister() o response.isDiscreteInputSet().

El resto del código es solo configuraciones Ethernet y comandos Serial para depurar y hacer que la aplicación sea más interactiva.


Software

/*
   Copyright (c) 2018 Boot&Work Corp., S.L. All rights reserved
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Lesser General Public License for more details.
   You should have received a copy of the GNU Lesser General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include <ModbusTCPMaster.h>
#if defined(MDUINO_PLUS)
#include <Ethernet2.h>
#else
#include <Ethernet.h>
#endif
// Ethernet configuration values
uint8_t mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(10, 10, 10, 3);
IPAddress slaveIp(10, 10, 10, 4);
uint16_t slavePort = 502;
// Define the ModbusTCPMaster object
ModbusTCPMaster modbus;
//
bool registerSet = 0;
bool discreteSet = 0;
// Ethernet client object used to connect to the slave
EthernetClient slave;
uint32_t lastSentTime = 0UL;
uint32_t lastSentTimeReadInputs = 0UL;
////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
  Serial.begin(9600UL);
  // Begin Ethernet
  Ethernet.begin(mac, ip);
  Serial.println(Ethernet.localIP());
// NOTE: it is not necessary to start the modbus master object
mainUI();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void loop() {
  // Connect to slave if not connected
  // The ethernet connection is managed by the application, not by the library
  // In this case the connection is opened once
  if (!slave.connected()) {
    Serial.println("Slave not connected");
    slave.stop();
    slave.connect(slaveIp, slavePort);
    if (slave.connected()) {
      Serial.println("Reconnected");
    }
  }
  // Send a request every 1000ms if connected to slave
  if (slave.connected()) {
    //Serial.println("Slave connected");
  if (Serial.available()) {
      byte chosenOption= Serial.read();
  bool value;
  byte address;
  switch(chosenOption){
      case '1': //set Q0_0 to high
          value = 1;
          address = 0;
          if (!(modbus.writeSingleCoil(slave, 0, address, value))) {
            // Failure treatment
            Serial.println("Request fail");
          }
          Serial.println("Q0_0 set to HIGH");
          break; 
      case '2': //set Q0_0 to low
          value = 0;
          address = 0;
          if (!(modbus.writeSingleCoil(slave, 0, address, value))) {
            // Failure treatment
            Serial.println("Request fail");
          }
          Serial.println("Q0_0 set to LOW");
          break;
      case '3': //set Q0_1 to high
          value = 1;
          address = 1;
          if (!(modbus.writeSingleCoil(slave, 0, address, value))) {
            // Failure treatment
            Serial.println("Request fail");
          }
          Serial.println("Q0_1 set to HIGH");
          break;
      case '4':
          value = 0;
          address= 1;
          if (!(modbus.writeSingleCoil(slave, 0, address, value))) {
            // Failure treatment
            Serial.println("Request fail");
          }
          Serial.println("Q0_1 set to LOW");
          break;
      case '5':
          if (!modbus.readInputRegisters(slave, 0, 0, 6)) {
            // Failure treatment
            Serial.println("Error requesting registers");
          }else{registerSet = true;}
          break;
      case '6':
          if (!modbus.readDiscreteInputs(slave, 0, 0, 7)) {
          // Failure treatment
          Serial.println("Error requesting discrete input");
          }else{discreteSet = true;} 
          break;
  }
mainUI();
    }
    if (modbus.isWaitingResponse()) {
      ModbusResponse response = modbus.available();
      if (response) {
        if (response.hasError()) {
          // Response failure treatment. You can use response.getErrorCode()
          // to get the error code.
        }else if (registerSet){
          // Get the input registers values from the response
          Serial.print("Input registers values: ");
          for (int i = 0; i < 6; ++i) {
            Serial.print(response.getRegister(i));
            Serial.print(',');
          }
          registerSet = false; 
        } else if(discreteSet) {
          // Get the input registers values from the response
          Serial.print("Input discrete values: [");
          for (int i = 0; i < 7; ++i) {
            Serial.print(response.isDiscreteInputSet(i));
            Serial.print(',');
          }
          Serial.println(']');
          discreteSet = false;
        }
      }
    }
  }
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void mainUI(){
    Serial.println("********************Modbus Test*********************");
    Serial.println("Chose an option:");
    Serial.println("1. Set Q0_0 to HIGH");
    Serial.println("2. Set Q0_0 to LOW");
    Serial.println("3. Set Q0_1 to HIGH");
    Serial.println("4. Set Q0_1 to LOW");
    Serial.println("5. Print slave input analog values");
    Serial.println("6. Print slave input digital values");
    Serial.println("****************************************************");

 
 


¿Buscas más ejemplos de automatización industrial?

Revisa nuestros Casos de Estudio sobre automatización, control y monitorización.


¿Quieres más informacion? 

¡Solo llena el formulario! 

¡Quiero saber más!  Por favor, llene el formulario correctamente.