PLC S7 Esclavos ARDUINO 7- (MultiNodo)

Proyecto PLC WinAC RTX  comunicando con nodos I/O esclavos basados en ARDUINO.

Esta es la séptima entrada de la categoría PLC Software, en esta ocasión muestro un proyecto completo donde se comunican distintos esclavos basados en Arduino y el PLC de Siemens WinAc RTX.

El proyecto es una recopilación y ampliación de las diferentes entradas anteriores de la categoría PLC Software.

En esta ocasión tendremos el PLC instalado en un PC portátil con el entorno de programación STEP7 y tres tarjetas de entradas/salidas descentralizadas, una de ellas wifi.

7.1-La primera tarjeta está basada en el proyecto personal Arduino PLC, el cual está detallado en entradas anteriores y al cual le ha añadido una tarjeta de comunicación Ethernet.

7.2-La segunda tarjeta está basada en el popular Arduino UNO y en el Shield Ethernet W5100.

7.3-La tercera tarjeta está basada en el controlador ESP8266, el cual ya fue tratado en entradas anteriores.

Está basado en una procesador con comunicación Wifi, con una salida a Relé y una entrada optoacoplada.

7.4-Programa STEP-7 (PLC Siemens), es el programa de PLC donde se explica la configuración para hacer posible el intercambio de información desde los esclavos Arduinos al PLC.

Para el enlace Ethernet, he utilizado un viejo Router al cual se conectan los nodos por cable y Wifi. Pero no detallo la configuración del Router ya que existe mucha información al respecto y difiere en función de cada modelo.

7.1-Tarjeta E/S basada en (PLC Arduino)

Esta entrada es una continuación de la Entrada ARDUINO PLC donde explicaba la forma de crear un PLC DiY.

Simplemente dotaremos al hardware PLC de una tarjeta Ethernet basada en el controlador W5100.

W5100

Para facilitar la realización del proyecto, he utilizado un Hardware Ethernet de libre disposición en las principales plataformas de venta Online.

Como ya fue previsto en su diseño inicial, únicamente debemos unir la PCU y la tarjeta Ethernet por un cable plano de 10 vías. Después mecanizamos la caja para alojar la nueva tarjeta.

Conexión Ethernet

Con esta simple modificación, ahora solo deberemos cargar el programa del Arduino, convirtiendo el PLC Arduino en un esclavo del PLC Siemens, y de esta forma es una tarjeta esclava de 8 bits de entradas optoacopladas y 4 bit de salida a Relé.

Nuestro Programa:

Ejecutamos el entorno de programación Arduino V1.8.7. e introducimos el programa. Anteriormente deberemos haber descargado la librería (Settimino), la cual incorpora el protocolo de comunicación de Siemens a nuestro proyecto Arduino.

/*----------------------------------------------------------------------
 Modulo IO Arduino 8 Inputs 4 Outputs
 Funciona perfecto sin ningún fallo de comunicación.
 Compilado con Arduino IDE 1.8.7
 JColl Jul.2019
----------------------------------------------------------------------*/
#define E0_0   A0   // Nº de Pin entrada digital.
#define E0_1   A1   // Nº de Pin entrada digital.
#define E0_2   A2   // Nº de Pin entrada digital.
#define E0_3   A3   // Nº de Pin entrada digital.
#define E0_6   8    // Nº de Pin entrada digital.
#define E0_7   7    // Nº de Pin entrada digital. 

//Estas dos entradas son analógicas y se deben tratar de tal forma
#define E0_4   A6   // Pin correspondiente a la entrada Analógica.
#define E0_5   A7   // Pin correspondiente a la entrada Analógica. 
#define A0_0   3    // Nº de Pin Salida digital.
#define A0_1   4    // Nº de Pin Salida digital.
#define A0_2   5    // Nº de Pin Salida digital.
#define A0_3   6    // Nº de Pin Salida digital.

void software_Reset(){   asm volatile ("  jmp 0");  } 
void(* resetFunc) (void) = 0; //declare reset function at address 0

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

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {0x90, 0xA2, 0xDA, 0x0F, 0x08, 0xE1};

IPAddress Local(192,168,1,45); // Local Address
IPAddress PLC(192,168,1,51);   // PLC Address
IPAddress Subnet(255,255,255,0);
int intentos =5; //Intentos de comunicar antes de hacer reset.

int DBNum = 1; // This DB must be present in your PLC
byte Buffer[8];
int Nodo = 1; // Indicar aqui el número de Nodo de la tarjeta (1-25)

S7Client Client(_S7WIRED);

unsigned long Elapsed; // To calc the execution time
//----------------------------------------------------------------------
// Setup : Init Ethernet and Serial port
//----------------------------------------------------------------------
void setup() {
    // Open serial communications and wait for port to open:
    Serial.begin(115200);
     while (!Serial) {
      ; // wait for serial port to connect. Needed for Leonardo only
    }
    
//---------------------Wired Ethernet Shield Initialization    
    // Start the Ethernet Library
    Ethernet.begin(mac, Local);
    delay(2000); 
    Serial.println("");
    Serial.println("Cable connected");  
    Serial.print("Local IP address : ");
    Serial.println(Ethernet.localIP());

    pinMode(E0_0, INPUT_PULLUP);  //Configura Pin entrada digital
    pinMode(E0_1, INPUT_PULLUP);  //Configura Pin entrada digital
    pinMode(E0_2, INPUT_PULLUP);  //Configura Pin entrada digital
    pinMode(E0_3, INPUT_PULLUP);  //Configura Pin entrada digital
    pinMode(E0_4, INPUT_PULLUP);  //Configura Pin entrada digital
    pinMode(E0_5, INPUT_PULLUP);  //Configura Pin entrada digital
    pinMode(E0_6, INPUT_PULLUP);  //Configura Pin entrada digital
    pinMode(E0_7, INPUT_PULLUP);  //Configura Pin entrada digital

    pinMode(A0_0, OUTPUT);  //Configura Pin salida digital
    pinMode(A0_1, OUTPUT);  //Configura Pin salida digital
    pinMode(A0_2, OUTPUT);  //Configura Pin salida digital
    pinMode(A0_3, OUTPUT);  //Configura Pin salida digital
}
//----------------------------------------------------------------------
// Connects to the PLC
//----------------------------------------------------------------------
bool Connect()
{
    int Result=Client.ConnectTo(PLC, 
                                  0,  // Rack (see the doc.)
                                  2); // Slot (see the doc.)
    Serial.print("Connecting to ");Serial.println(PLC);  
    if (Result==0) 
    {
      Serial.print("Connected ! PDU Length = ");
      Serial.println(Client.GetPDULength());
    }
    else
      Serial.println("Connection error");
    return Result==0;
}
//----------------------------------------------------------------------
// Main Loop
//----------------------------------------------------------------------
void loop() 
{
  int Result;
  void *Target;
   
  Target = NULL; // Uses the internal Buffer (PDU.DATA[])
  
  // Connection
  while (!Client.Connected)
  {
    if (!Connect()){
      delay(150);
      if (intentos<1) resetFunc(); //software_Reset();
      intentos--; //Intentos de comunicar antes de hacer reset.
    }
  }
  
  Result=Client.ReadArea(S7AreaDB, // We are requesting DB access
                         DBNum,    // DB Number
                         Nodo*10,  // primer byte nodo 1=10
                         10,       // We need "Size" bytes
                         Target);  // Put them into our target 
  if (Result==0)  //Comunicación OK.
    {
    //Actualiza valores del área de salida "OUTPUTS" recibidos del PLC:
    //Lee bit 0 de lo recibido en Parte Baja TX_Word (FC1)
    digitalWrite(A0_0, bitRead(PDU.DATA[4], 0)); 
    digitalWrite(A0_1, bitRead(PDU.DATA[4], 1)); 
    digitalWrite(A0_2, bitRead(PDU.DATA[4], 2)); 
    digitalWrite(A0_3, bitRead(PDU.DATA[4], 3)); 

    //Actualiza valores del área de entradas "INPUTS" a enviar al PLC:
    //Envía estado negado de la entrada al bit x del RX_Word (FC1)
    bitWrite( PDU.DATA[6] , 0, !digitalRead(E0_0));  
    bitWrite( PDU.DATA[6] , 1, !digitalRead(E0_1));  
    bitWrite( PDU.DATA[6] , 2, !digitalRead(E0_2));  
    bitWrite( PDU.DATA[6] , 3, !digitalRead(E0_3));  
    bitWrite( PDU.DATA[6] , 6, !digitalRead(E0_6));  
    bitWrite( PDU.DATA[6] , 7, !digitalRead(E0_7));  

    //Estas dos entradas son Analógicas y se deben tratar de tal forma
    if(analogRead(E0_4) > 800)  bitWrite( PDU.DATA[6] , 4, LOW);
                        else  bitWrite( PDU.DATA[6] , 4, HIGH);

    if(analogRead(E0_5) > 800)  bitWrite( PDU.DATA[6] , 5, LOW);
                        else  bitWrite( PDU.DATA[6] , 5, HIGH);

    //Activa a 1 el bit2 DB1.DBX xx8.2, indica al PLC Buffer_Entrada=1.
    bitWrite(PDU.DATA[8], 2, 1);  //Activa a 1 el bit2 DB1.DBX xx8.2
    
    Client.WriteArea(S7AreaDB,     // We are requesting DB access
                         DBNum,    // DB Number
                         Nodo*10,  // primer byte nodo 1=10
                         10,       // We need "Size" bytes
                         Target);  // Put them into our target 
    }
  delay(50); //Pruebas de tiempo cada 50ms. por cable va perfecto. 
}

Como se puede observar introducimos los datos de nuestra red:

Introducimos la IP local 192.168.1.45 y la del PLC WinAc RTX 192.168.1.51

Introducimos en número de Nodo=1.

Seleccionamos bastidor 0 Slot 2.

Seleccionamos el tipo de controlador que estamos utilizando(Arduino NANO).

Conectamos la placa al PC por cable USB y pulsamos el icono Compilar y transferir.

Fin de este apartado…

7.2-Tarjeta E/S basada en (Arduino UNO)

Esta entrada es muy similar al punto anterior, con la diferencia que al compilar el procesador difiere siendo Arduino UNO. El programa también es algo diferente.

Arduino uno

En este caso deberemos adaptar el programa a los puertos de entrada y salida del Arduino que queramos utilizar.

Nuestro Programa:

Ejecutamos el entorno de programación Arduino V1.8.7. e introducimos el programa. Anteriormente deberemos haber descargado la librería (Settimino), la cual incorpora el protocolo de comunicación de Siemens a nuestro proyecto Arduino.

/*----------------------------------------------------------------------
Modulo IO Arduino UNO
Probado por Cable Ethernet en placa (Arduino UNO) mas Shield Wiznet

Compilado con Arduino IDE 1.8.7
JColl Agosto.2019

 Agosto 2019: El número de IP está sujeto al Número de nodo.
              IP es = 192.168.1.NODO
              Compilado para Arduino UNO + W5100
----------------------------------------------------------------------*/
#define E0_0   A0   // Nº de Pin correspondiente a la entrada digital.
#define E0_1   A1   // Nº de Pin correspondiente a la entrada digital.
#define E0_2   A2   // Nº de Pin correspondiente a la entrada digital.
#define E0_3   A3   // Nº de Pin correspondiente a la entrada digital.
#define E0_6   8    // Nº de Pin correspondiente a la entrada digital.
#define E0_7   7    // Nº de Pin correspondiente a la entrada digital. 

//Estas dos entradas son únicamente Analógicas
#define E0_4   A6   // Nº de Pin correspondiente a la entrada Analógica.
#define E0_5   A7   // Nº de Pin correspondiente a la entrada Analógica.

#define A0_0   3    // Nº de Pin correspondiente a la Salida digital.
#define A0_1   4    // Nº de Pin correspondiente a la Salida digital.
#define A0_2   5    // Nº de Pin correspondiente a la Salida digital.
#define A0_3   6    // Nº de Pin correspondiente a la Salida digital.

void software_Reset(){   asm volatile ("  jmp 0");  } 
void(* resetFunc) (void) = 0; //declare reset function at address 0

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

int DBNum = 1; // This DB must be present in your PLC
byte Buffer[8];
int Nodo = 10; // Indicar aqui el número de Nodo de la tarjeta (1-25)

byte mac[] = {0x90, 0xA2, 0xDA, 0x0F, 0x08, Nodo};

IPAddress Local(192,168,1,Nodo); // Local Address fixed Node num.
IPAddress PLC(192,168,1,51);   // PLC Address
IPAddress Subnet(255,255,255,0);
int intentos =5; //Intentos de comunicar antes de hacer reset.

S7Client Client(_S7WIRED);

unsigned long Elapsed; // To calc the execution time
//----------------------------------------------------------------------
// Setup : Init Ethernet and Serial port
//----------------------------------------------------------------------
void setup() {
    // Open serial communications and wait for port to open:
    Serial.begin(115200);
     while (!Serial) {
      ; // wait for serial port to connect. Needed for Leonardo only
    }
    
//--------------------------------Wired Ethernet Shield Initialization    
    // Start the Ethernet Library
    Ethernet.begin(mac, Local);
    delay(2000); 
    Serial.println("");
    Serial.println("Cable connected");  
    Serial.print("Local IP address : ");
    Serial.println(Ethernet.localIP());

    pinMode(E0_0, INPUT_PULLUP);  //Configura Pin entrada digital
    pinMode(E0_1, INPUT_PULLUP);  //Configura Pin entrada digital
    pinMode(E0_2, INPUT_PULLUP);  //Configura Pin entrada digital
    pinMode(E0_3, INPUT_PULLUP);  //Configura Pin entrada digital
    pinMode(E0_4, INPUT_PULLUP);  //Configura Pin entrada digital
    pinMode(E0_5, INPUT_PULLUP);  //Configura Pin entrada digital
    pinMode(E0_6, INPUT_PULLUP);  //Configura Pin entrada digital
    pinMode(E0_7, INPUT_PULLUP);  //Configura Pin entrada digital

    pinMode(A0_0, OUTPUT);  //Configura Pin salida digital
    pinMode(A0_1, OUTPUT);  //Configura Pin salida digital
    pinMode(A0_2, OUTPUT);  //Configura Pin salida digital
    pinMode(A0_3, OUTPUT);  //Configura Pin salida digital
}
//----------------------------------------------------------------------
// Connects to the PLC
//----------------------------------------------------------------------
bool Connect()
{
    int Result=Client.ConnectTo(PLC, 
                                  0,  // Rack (see the doc.)
                                  2); // Slot (see the doc.)
    Serial.print("Connecting to ");Serial.println(PLC);  
    if (Result==0) 
    {
      Serial.print("Connected ! PDU Length = ");
       Serial.println(Client.GetPDULength());
    }
    else
      Serial.println("Connection error");
    return Result==0;
}
//----------------------------------------------------------------------
// Main Loop
//----------------------------------------------------------------------
void loop() 
{
  int Result;
  void *Target;
   
  Target = NULL; // Uses the internal Buffer (PDU.DATA[])
  
  // Connection
  while (!Client.Connected)
  {
    if (!Connect()){
      delay(150);
      if (intentos<1) resetFunc(); //software_Reset();
      intentos--; //Intentos de comunicar antes de hacer reset.
    }
  }
  
  Result=Client.ReadArea(S7AreaDB, // We are requesting DB access
                         DBNum,    // DB Number
                         Nodo*10,  // primer byte nodo 1=10
                         10,       // We need "Size" bytes
                         Target);  // Put them into our target
  if (Result==0)  //Comunicación OK.
    {
    //Actualiza valores del área de salida "OUTPUTS" recibidos del PLC:
    digitalWrite(A0_0, bitRead(PDU.DATA[4], 0)); 
    digitalWrite(A0_1, bitRead(PDU.DATA[4], 1)); 
    digitalWrite(A0_2, bitRead(PDU.DATA[4], 2)); 
    digitalWrite(A0_3, bitRead(PDU.DATA[4], 3)); 

    //Actualiza valores del área de entradas "INPUTS" a enviar al PLC:
    //Envía estado negado de la entrada digital al bit x de la Parte baja RX_Word (FC1)
    bitWrite( PDU.DATA[6] , 0, !digitalRead(E0_0));  
    bitWrite( PDU.DATA[6] , 1, !digitalRead(E0_1));  
    bitWrite( PDU.DATA[6] , 2, !digitalRead(E0_2));  
    bitWrite( PDU.DATA[6] , 3, !digitalRead(E0_3));  
    bitWrite( PDU.DATA[6] , 6, !digitalRead(E0_6)); 
    bitWrite( PDU.DATA[6] , 7, !digitalRead(E0_7));  

 //Estas dos entradas son únicamente Analógicas
    if(analogRead(E0_4) > 800)  bitWrite( PDU.DATA[6] , 4, LOW);
                        else  bitWrite( PDU.DATA[6] , 4, HIGH);

    if(analogRead(E0_5) > 800)  bitWrite( PDU.DATA[6] , 5, LOW);
                        else  bitWrite( PDU.DATA[6] , 5, HIGH);

    //Activa a 1 el bit2 DB1.DBX xx8.2, indica al PLC Buffer_Entrada=1.
    bitWrite(PDU.DATA[8], 2, 1);  //Activa a 1 el bit2 DB1.DBX xx8.2
    
    Client.WriteArea(S7AreaDB,     // We are requesting DB access
                         DBNum,    // DB Number
                         Nodo*10,  // primer byte nodo 1=10
                         10,       // We need "Size" bytes
                         Target);  // Put them into our target 
  }
  delay(50); //Pruebas de tiempo cada 50ms. por cable va perfecto. 
}

Como se puede observar introducimos los datos de nuestra red:

Introducimos la IP local 192.168.1.10 y la del PLC WinAc RTX 192.168.1.51

Introducimos en número de Nodo=10.

Seleccionamos bastidor 0 Slot 2.

Seleccionamos el tipo de controlador que estamos utilizando (Arduino UNO).

Conectamos la placa al PC por cable USB y pulsamos el icono Compilar y transferir.

Arduino uno + Shield

Fin de este apartado…

7.3-Tarjeta E/S basada en (ESP8266 Wifi)

En esta entrada trataremos el controlador ESP8266, el cual ya fue en entradas anteriores en el proyecto Relé controlado desde Internet.

ESP8266 + USB converter

Se trata de una PCB dotada de comunicación Wifi con una entrada opto-acoplada y una salida a relé.

Esta tarjeta no dispone de puerto USB para ser programada y por tanto deberemos tener un adaptador USB a puerto serie TTL para poder cargar el programa.

Nuestro Programa:

Ejecutamos el entorno de programación Arduino V1.8.7. e introducimos el programa. anteriormente deberemos haber descargado la librería (Settimino) y tener instalado los drivers del controlador ESP8266 en el IDE de Arduino.

/*----------------------------------------------------------------------
Modulo IO Arduino 1 Input 2 Outputs

MicroProcesador ESP8266 con WIFI 802.11b/g/n

 La comunicación depende de la cobertura y saturación del Wifi.
 Compilado con Arduino IDE 1.8.7
 JColl Agosto.2019

 15 Agosto 2019: El número de IP está sujeto al Número de nodo.
                 IP es = 192.168.1.NODO
                 Compilado para placa (Generic ESP8266 Module) 
----------------------------------------------------------------------*/

#define E0_0   5    // Nº de Pin de la entrada digital Opto-acoplada.
#define A0_0   4    // Nº de Pin de la Salida del RELE.
#define LED    2    // Nº de Pin de la Salida LED Azul.

// CONFIGURACION DEL WIFI 
char ssid[] = "MiRouter";   // SSID (name)
char pass[] = "12345678";         //  password 
int DBNum = 1; // This DB must be present in your PLC
int Nodo = 11; // Indicar aqui el número de Nodo de la tarjeta (1-25)

void(* resetFunc) (void) = 0; //declare reset function at address 0

#include <SPI.h>
#include <Ethernet.h>
#include <ESP8266WiFi.h> //Incluye la librería ESP8266WiFi
#include "Settimino.h"

byte mac[] = {0x90, 0xA2, 0xDA, 0x0F, 0x08,Nodo};

IPAddress Local(192,168,1,Nodo); // Local Address
IPAddress PLC(192,168,1,51);   // PLC Address

IPAddress Gateway(192,168,1,1);
IPAddress Subnet(255,255,255,0);

byte Buffer[8];
S7Client Client(_S7WIFI);

int intentos; //Intentos de comunicar antes de hacer reset.
//----------------------------------------------------------------------
// Setup : Init Ethernet and Serial port
//----------------------------------------------------------------------
void setup() {
    // Open serial communications and wait for port to open:
    Serial.begin(115200);
     while (!Serial) {;}

    Serial.print("Conectando al WIFI ");
    WiFi.begin(ssid, pass);
    WiFi.config(Local, Gateway, Subnet);
    while (WiFi.status() != WL_CONNECTED) 
    {
        delay(500);
        Serial.print(".");
    }
    Serial.println("");
    Serial.println("WiFi conectado a IP:");  
    Serial.println(WiFi.localIP());

    pinMode(E0_0, INPUT);  //Configura Pin entrada digital
    pinMode(A0_0, OUTPUT);  //Configura Pin salida digital
    pinMode(LED, OUTPUT);   //Configura Pin salida digital
}
//----------------------------------------------------------------------
// Connects to the PLC
//----------------------------------------------------------------------
bool Connect()
{
    int Result=Client.ConnectTo(PLC, 
                                  0,  // Rack (see the doc.)
                                  2); // Slot (see the doc.)
    if (Result==0) 
       Serial.print("Conectado OK!");
       else
        Serial.println("Error No conectado.....");
    return Result==0;
}

//----------------------------------------------------------------------
// Prints the Error number
//----------------------------------------------------------------------
void CheckError(int ErrNo)
{
  Serial.print("Error No. 0x");
  Serial.println(ErrNo, HEX);
  
  // Checks if it's a Severe Error => we need to disconnect
  if (ErrNo & 0x00FF)
  {
    Serial.println("SEVERE ERROR, disconnecting.");
    Client.Disconnect(); 
  }
}
//----------------------------------------------------------------------
// Main Loop
//----------------------------------------------------------------------
void loop() 
{
  int Result;
  void *Target;

  intentos =25; //Intentos de comunicar antes de hacer reset.
  digitalWrite(LED, HIGH); //Reset Indicación Led Azul 

  // Connection
  while (!Client.Connected)
  {
    if (!Connect()){
      delay(295);
      if (intentos<1) resetFunc(); //software_Reset();
      intentos--; //Intentos de comunicar antes de hacer reset.
    }
  }
  Target = NULL; // Uses the internal Buffer (PDU.DATA[]) 
  Result=Client.ReadArea(S7AreaDB, // We are requesting DB access
                         DBNum,    // DB Number
                         Nodo*10,  // primer byte nodo 1=10
                         10,       // We need "Size" bytes
                         NULL);    // Uses the internal Buffer (PDU.DATA[])
 
  if (Result==0)  //Comunicación OK.
    {
    //Actualiza valores del área de salida "OUTPUTS" recibidos del PLC:
    digitalWrite(A0_0, bitRead(PDU.DATA[4], 0));  
    //Actualiza valores del área de entradas "INPUTS" a enviar al PLC:
    //Envía estado negado de la entrada digital al bit x (FC1)
    bitWrite( PDU.DATA[6] , 0, !digitalRead(E0_0));    
    //Activa a 1 el bit2 DB1.DBX xx8.2, indica al PLC Buffer_Entrada=1.
    bitWrite(PDU.DATA[8], 2, 1);  //Activa a 1 el bit2 DB1.DBX xx8.2

    Result=Client.WriteArea(S7AreaDB,  // We are requesting DB access
                         DBNum,    // DB Number
                         Nodo*10,  // primer byte nodo 1=10
                         10,       // We need "Size" bytes
                         NULL);    // Uses the internal Buffer (PDU.DATA[])
    if (Result==0)  //Comunicación OK.
      {
       Serial.println("Fin comunicacion OK TOTAL --->"); 
       digitalWrite(LED, LOW); //Led Azul finalización de una trama OK.
      }else CheckError(Result);// Evalúa el tipo de error.
    }else CheckError(Result);// Evalúa el tipo de error.
    
  delay(200); //Pruebas de tiempo cada 200ms. por Wifi es aceptable. 
}

Como se puede observar introducimos los datos de nuestra red:

Introducimos la IP local 192.168.1.11 y la del PLC WinAc RTX 192.168.1.51

Introducimos en número de Nodo=11.

Configuramos el nombre de la red Wifi de nuestro Router y la contraseña.

Seleccionamos bastidor 0 Slot 2.

Seleccionamos el tipo de controlador que estamos utilizando (ESP8266).

Conectamos la placa al PC por el adaptador USB a puerto serie TTL.

Ponemos el jumper en los pines serigrafiados como BOOT y alimentamos la placa a 12V. Esto fuerza el modo de programación.

Pulsamos el icono Compilar y transferir. Al finalizar debemos retirar el jumper BOOT para salir del modo de programación.

Fin de este apartado…

7.4-Programa STEP-7 (PLC Siemens)

Este proyecto funciona comunicándose con el PLC a través de un módulo creado para tal fin y permite que el PLC WinAC se comunique con esclavos ARDUINO.

Programando la parte PLC mediante el software STEP7 V5.5

Aquí muestro un pequeño programa que hace las funciones de interconexión con la información de la base de datos DB1, la cual está siendo el enlace con el Arduino. Como podemos ver tenemos un primer array de Bytes necesarios para la función interna, después un array 0..25 tipo “Nodo” que es una plantilla creada para cada posible  Nodo de nuestra red.

DB1

La UDT o plantilla es:

UDT1

Donde podemos ver el total de bytes utilizados por cada nodo. FC1: Función para la actualización de la imagen de entradas y salidas en función de los datos del DB1.

FC1

OB1: Bloque principal del programa, donde la primeramente se hace una llamada a la función FC1, donde se actualiza el área de Entradas/Salidas de cada Nodo y permite continuar programando como si la tarjeta de IO fuera una tarjeta nativa del PLC.

Datos del parametrizado:

W_Dog = 30     WatchDog de 3segundos. Antes de indicar perdida de comunicación

NumNodo=1     Número único de nodo, debe estar declarado igual en la tarjeta Arduino

TX_Word= AW0 Envía el estado de la palabra de salidas 0. (Nuestra tarjeta utiliza el byte AB0).

RX_Word= EW0 Captura el estado de la palabra de entradas 0. (Nuestra tarjeta utiliza el byte EB0).

Conect = 1        Nos indica si el WatchDog está inactivo.

Error=0                        Nos indica si algún parámetro está fuera de rango. Haremos tantas llamadas al FC1 como nodos tengamos disponibles en nuestra red.

OB1

Listado del programa principal OB1:

S7-OB1

Listado del programa principal FC1:

S7-FC1

Nota: La configuración del PLC y su Hardware no se debe alterar para incorporar esta tarjeta.

Es decir el PLC no supervisará la presencia y buen funcionamiento de esta tarjeta. Únicamente supervisaremos con el WatchDog la cadencia entre comunicaciones, y nos indicará con el bit Conect cuando el tiempo supere al configurado.

En ningún caso el PLC pasará a Stop por pérdida de comunicación.

A partir de aquí podemos desarrollar nuestro hardware de entradas y salidas personalizado para proyectos de aprendizaje.

Fin del procedimiento…