Modbus TCP/IP Entre Arduino y PLC Logo

Que tal buenas noches, una disculpa de antemano si por alguna razón cometo un error, soy nuevo en esto de los foros pero requiero de su apoyo.
Estoy realizando un proyecto en el cual necesito establecer una comunicación entre un PLC LOGO y Arduino, mediante el protocolo TCP/IP. El Logo se usara para controlar un compresor industrial, dicho compresor tiene una válvula que se encarga de la "Carga" y "Descarga" de aire comprimido, y esta válvula no es mas que un motor a pasos y un encoder. Como con el Logo no puedo manejar el motor a pasos (hasta donde yo se), requiero de la ayuda de un Arduino. En fin, sin tanto rollo, anexare capturas de la programación de ambos controladores.

Este es el código para el Arduino, en el cual lo que busco es poder transmitirle valores análogos (En este caso solo 1 como método de prueba) al Logo, y a su vez poder recibir o leer ordenes del PLC, esto como si el Arduino estuviera reportando posición del encoder y que al mismo tiempo el PLC pueda decirle al Arduino girar el Motor a pasos hacia un lado o hacia el otro para abrir o cerrar la válvula, en este caso lo simulo con un potenciómetro conectado al A0, para entregar un valor analogo al PLC y un Led conectado al pin 9 para poder encenderlo y apagarlo según mande el LOGO.

#include <SPI.h>
#include <Ethernet.h>
#include <Modbus.h>
#include <ModbusIP.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };  
byte ip[] = { 192, 168, 1, 22 };

//Modbus Registers Offsets (0-9999)
const int SENSOR_IREG = 50; 
const int sensorPin = A0;

const int LED_COIL = 30;
const int PinLed = 9;

int Sensor1 = 0;
int coil = 0;

//ModbusIP object
ModbusIP mb;

long ts;

void setup() {
    Serial.begin(115200);
    mb.config(mac, ip);
    pinMode(PinLed,OUTPUT);
    // Add SENSOR_IREG register - Use addIreg() for analog Inputs
    mb.addIreg(SENSOR_IREG);
    delay(500);
    mb.addCoil(LED_COIL);
    ts = millis();
}

void loop() {
   //Call once inside loop() - all magic here
   mb.task();
   Sensor1 = analogRead(sensorPin);
   coil = mb.Coil(LED_COIL);
   digitalWrite(PinLed, coil);
   if (millis() > ts + 150) {
      mb.task();   
       mb.Ireg(SENSOR_IREG, Sensor1);
       Serial.print("Valor Enviado por IREG 50 :"); Serial.println(Sensor1);
       Serial.print("Valor Recibido por COIL 30 :"); Serial.println(coil);
       ts = millis();
   }
}

Ahora bien, lo siguiente es una captura del Logo Soft comfort, en donde leo el registro de entrada IR mandado por el Arduino con el valor análogo en el registro 50 (51 en Logo ya que su base es diferente al del Arduino), y busco que al mismo tiempo el PLC pueda escribir en un Coil, ya sea un 1 o un 0, con la intención de que el Arduino prenda o apague el led.

Ahora bien, así como esta en la imágenes, logro recibir perfectamente el valor del potenciómetro en el Logo, pero al activar la salida de red en el Logo, no recibo nada en el Arduino. Cabe mencionar que cuando quito la entrada analoga de red (IR) en el programa del Logo, y dejo solo la salida (Coil), en ese momento si la puedo recibir en el Arduino, osease, solo logo leer un registro a la vez, y no ambos simultáneamente.

No se si logre explicarme, agradecería mucho su apoyo. Saludos.

1 Like

Moderador:
Bienvenido al Foro Arduino en Español.
Por favor, lee las Normas del foro y edita tu código usando etiquetas de código.
Ve a edición, luego selecciona todo el error que has publicado, lo cortas y click en </>


Pero entonces tu mismo lo has dicho, es un problema de LOGO no de Arduino.
En tu comentario

se deduce que no alteras nada en Arduino y el problema esta en tu programación de LOGO en la cual yo personalmente no puedo ayudarte, y sería tema para otro foro.

NOTA: no respondas sin editar lo que te he pedido!

Muchas gracias por tu respuesta y de ante mano una disculpa por el error. Después de tanta prueba y error utilicé otras librerías para el Arduino y por fin encontré una que me funcionó sin tener que hacer cambios en el LOGO. Les dejo el código que utilice y que me funciono, además con la ventaja de estar haciendo la transmisión de datos en tiempo real sin la necesidad de estar teniendo un tiempo de muestreo en la comunicación.

#include <SPI.h>
#include <Ethernet.h>
#include "MgsModbus.h"

MgsModbus Mb;

// Ethernet settings (depending on MAC and Local network)
byte mac[] = {0x90, 0xA2, 0xDA, 0x0E, 0x94, 0xB5 };
IPAddress ip(192, 168, 1, 22);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);

const int Analog = A0;

const int PinLed = 9;
const int LedCoil = 50;

void setup()
{
  Serial.begin(115200);
  Ethernet.begin(mac, ip, gateway, subnet);   // start etehrnet interface
  Serial.println("Ethernet interface started"); 
  pinMode(PinLed,OUTPUT);
  digitalWrite(PinLed,HIGH);
  // Fill MbData
 //Mb.SetBit(0,false);
  Mb.MbData[0] = 0;   //Holding Reg 1
  Mb.MbData[1] = 0;   //Holding Reg 2
//  Mb.MbData[2] = 0;
//  Mb.MbData[3] = 0;
//  Mb.MbData[4] = 0;
//  Mb.MbData[5] = 0;
//  Mb.MbData[6] = 0;
//  Mb.MbData[7] = 0;
//  Mb.MbData[8] = 0;
//  Mb.MbData[9] = 0;
//  Mb.MbData[10] = 0;
//  Mb.MbData[11] = 0;
  
}

void loop()
{
 Mb.MbData[0] = analogRead(A0);
 digitalWrite(PinLed,Mb.GetBit(LedCoil));
// Serial.print("Dato Enviado por H Registro 1: "); Serial.println(Mb.MbData[0]);
// Serial.print("Dato Recibido por H Registro 2: "); Serial.println(Mb.MbData[1]);
 Serial.print("Dato Recibido por Coil 3: "); Serial.println(Mb.GetBit(LedCoil));
  
//  Mb.MbmRun();
  Mb.MbsRun();
}

Nótese que para poder enviar datos análogos, necesitamos enviarlos mediante Holding registers que utilizan el comando " Mb.MbData[0]", (Puede usarse para Leer o escribir) y para datos digitales podemos usar "Mb.GetBit" o "Mb.SetBit" segun sea el caso.

En la programación del LOGO todo quedaría igual a lo mencionado en la pregunta del tema. Muchas gracias por su tiempo, y espero a alguien mas le sirva el aporte. Saludos.

1 Like

En principio, me alegro que lo hayas resuelto y que claramente tenías razón en que el problema estaba en el Arduino o mejor dicho en como estaba programado el Arduino.
Evidentemente algo se debe modificar en el primer programa y debería funcionar.
Cuando no veo cosas como esta y esto para la próxima duda o consulta:

// ambos ejemplos son imaginarios
#include <Modbus.h>        // https://github.com/arduino-libraries/Modbus
#include <ModbusIP.h>    // https://github.com/arduino-libraries/ModbusIP

Resulta dificil seguir el problema.
Yo tengo simuladores ModBus asi que podría haber probado tu código y cuando vienen consultas de este tipo realmente las disfruto porque de los problemas de otros uno aprende a resolver o evitar los propios.

Bueno, para la próxima ya sabes y de nuevo felicitaciones por resolver el problema.

Buen día, interesante el uso de tu aplicación y quiero realizar la misma conexión tuya entre logo y arduino, pero no sé si irme por el módulo shield Ethernet de Arduino o el módulo ethernet mini me gusta más la estructura del shield pero quisiera basarme con tu código, les agradezco su recomendación para escoger el módulo correcto

Ethernet funcionará en cualquiera de los dos.
Si debes hacer cambios de acuerdo al módulo es algo que no te debería generar problemas.
Repito, resolverás eso rápidamente sea un Shield Ethernet o la versión Mini.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.