PLC S7 Slaves ARDUINO 7- (MultiNode)

 WinAC RTX PLC project communicating with ARDUINO-based slave I/O nodes.

 This is the seventh entry of the PLC Software category, this time I show a complete project where different slaves based on Arduino and the SIEMENS WinAc RTX PLC communicate.

 The project is a compilation and expansion of the previous entries of the PLC Software category.

 This time we will have the PLC installed on a portable PC with the STEP7 programming environment and three decentralized input/output cards, one of them wifi.

7.1-The first card is based on the personal Arduino PLC project, which is detailed in previous entries and to which you have added an Ethernet communication card.

7.2-The second card is based on the popular Arduino UNO and the W5100 Ethernet Shield.

7.3-The third card is based on the ESP8266 controller, which has already been discussed in previous entries.

 It is based on a processor with Wifi communication, with an output to Relay and an optocoupled input.

7.4-STEP-7 Program (PLC Siemens), is the PLC program where the configuration is explained to make it possible to exchange information from Arduinos slaves to PLC.

  For the Ethernet link, I used an old Router to which the wired and Wifi nodes are connected. But I do not detail the configuration of the router as there is a lot of information about it and it differs depending on each model.

 7.1-Based I/O Card (PLC Arduino)

 This entry is a continuation of the ARDUINO PLC Entry where it explained how to create a DiY PLC.

 We will simply equip the PLC hardware with an Ethernet card based on the W5100 controller.

 

 To facilitate the realization of the project, I have used an open-fault Ethernet Hardware on the main online sales platforms.

  As already envisaged in its initial design, we only have to join the PCU and the Ethernet card by a 10-way flat cable. Then we machine the box to accommodate the new card.

 

 With this simple modification, we will now only have to load the Arduino program, turning the Arduino PLC into a slave of the Siemens PLC, and thus it is an 8-bit slave card of optocoupled inputs and 4 bit output to Relay.

 Our Program:

   We run the Arduino V1.8.7 programming environment. and we introduce the program. Previously we must have downloaded the library (Settimino), which incorporates the Communication Protocol of Siemens to our Arduino project.

/*----------------------------------------------------------------------
 Modulo IO Arduino 8 Inputs 4 Outputs
 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. 

 As you can see we enter the data of our network:

 Introducing local IP 192.168.1.45 and WinAc RTX PLC 192.168.1.51

 Enter in Node number 1 .

 We select rack 0 Slot 2.

 We select the type of controller we are using(Arduino NANO).

 Connect the board to the PC via USB cable and press the Build and Transfer icon.

 End of this section…

 7.2-Based I/O Card (Arduino UNO)

  This entry is very similar to the previous point, with the difference that when compiling the processor differs being Arduino UNO. The program is also something different.

 

 In this case we will have to adapt the program to the input and output ports of the Arduino that we want to use.

 Our Program:

   We run the Arduino V1.8.7 programming environment. and we introduce the program. Previously we must have downloaded the library (Settimino), which incorporates the Communication Protocol of Siemens to our Arduino project.

/*----------------------------------------------------------------------
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. 
}

 As you can see we enter the data of our network:

 Introducing local IP 192.168.1.10 and WinAc RTX PLC 192.168.1.51

 Enter in node number 10.

 We select rack 0 Slot 2.

 We select the type of controller we are using (Arduino UNO).

 Connect the board to the PC via USB cable and press the Build and Transfer icon.

 

 End of this section…

 7.3-Based I/O Card (ESP8266 Wifi)

 In this entry we will cover the ESP8266 controller, which was already in previous entries in the Relay controlled from the Internet project.

 

 It is a PCB equipped with Wifi communication with an opto-coupled input and a relay output.

 This card does not have a USB port to be programmed and therefore we must have a USB to TTL serial port adapter to be able to charge the program.

 Our Program:

   We run the Arduino V1.8.7 programming environment. and we introduce the program. Previously we must have downloaded the library (Settimino) and have the ESP8266 driver drivers installed in the Arduino IDE.

/*----------------------------------------------------------------------
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. 
}

 As you can see we enter the data of our network:

 Introducing local IP 192.168.1.11 and WinAc RTX PLC 192.168.1.51

 Enter in node number 11.

 We configure the Wifi network name of our Router and the password.

 We select rack 0 Slot 2.

 We select the type of controller we are using (ESP8266).

 Connect the board to the PC via the USB to TTL serial port adapter.

  We put the jumper on the screen-printed pins as BOOT and feed the board to 12V. This forces the programming mode.

  Click the Build and Transfer icon. At the end we must remove the BOOT jumper to exit programming mode.

 End of this section…

 7.4-Programa STEP-7 (PLC Siemens)

 This project works by communicating with the PLC through a module created for this purpose and allows the WinAC PLC to communicate with ARDUINO slaves.

 Programming the PLC part using STEP7 V5.5 software

  Here I show a small program that does the functions of interconnection with the information of the DB1 database, which is being the link with the Arduino. As we can see we have a first array of Bytes needed for the internal function, then an array 0..25 type “Node” which is a template created for each possible Node of our network.

 

 The UDT or template is:

 

  Where we can see the total bytes used by each node. FC1: Function for updating the image of inputs and outputs based on the data of the DB1.

 

 OB1: Main program block, where the first call is made to the FC1 function, where the Inputs/Outputs area of each Node is updated and allows to continue programming as if the IO card were a native PLC card.

 Parameterized data:

  W_Dog = 30 WatchDog of 3seconds. Before indicating lost communication

 NumNode-1 Single node number, must be declared the same on the Arduino card

  TX_WordTM AW0 Sends the status of the output word 0. (Our card uses byte AB0).

  RX_WordTM EW0 Captures the status of the input word 0. (Our card uses byte EB0).

 Connect 1 tells us if the WatchDog is inactive.

  Error-0 Tells us if any parameters are out of range. We will make as many calls to FC1 as we have available in our network.

 

 OB1 main program listing:

S7-OB1

 List of the main program FC1:

S7-FC1

 Note: The configuration of the PLC and its Hardware must not be altered to incorporate this card.

  That is, the PLC will not monitor the presence and proper functioning of this card. We will only monitor with the WatchDog the cadence between communications, and will indicate with the Conect bit when the time exceeds the configured one.

 Under no circumstances will the PLC go to Stop for loss of communication.

 Under no circumstances will the PLC go to Stop for loss of communication. From here we can develop our custom input and output hardware for learning projects.

 End of procedure…