Sonntag, September 8, 2024
Banner Top

Einrichten einer MODBUS RTU-Kommunikation zwischen einer Arduino-SPS und einem Iview-GUI

System-Voraussetzungen

Produkt-links

Software :

Hardware

Folgende Produkte wurden für diesen Blog-Artikel verwendet:

  • SPS ARD_10I08R
  • GUI IV207M-SEAP

Für manche Produkte derselben Baureihe kann die Programmierung und Funktionsweise unter Umständen unterschiedlich sein.

DIP-Switch Setting

Als Erstes müssen die roten DIP-Switches auf der auf der SPS in die geeignete Position gebracht werden.

Das in unserem Fall verwendete Kommunikations-Protokoll ist RS485 in Half-Duplex.

Dazu müssen Sie die Switches wie folgt konfigurieren:

Verdrahtung

Bei Halfduplex werden die Informationen über ein Paar Drähte übertragen. Jedes Gerät übernimmt abwechselnd die Funktion des Senders und dann des Empfängers. Zum Schutz vor Störungen, verwendet man ein verdrilltes Leiterpaar (wie bei einem Ethernet-Kabel).

Software-Konfiguration

Kommunikation-Einrichtung auf GUI-Seite

In der Iview-Programmiersoftware muss die Kommunikation wie folgt konfiguriert werden :

Die Werte „Baudrate“, „Data Bits“, „Parity“ und „Stop Bits“ können auch anders konfiguriert werden. Sie müssen jedoch mit den in der SPS konfigurierten Werten übereinstimmen.

Kommunikations-Einrichtung auf SPS-Seite

Als Erstes rufen wir im Programm die verschiedenen Bibliotheken auf, die wir benötigen.

#include <ModbusRTUMaster.h>

#include <RS485.h>

Da MODBUS RTU ein Software-Kommunikationsprotokoll ist, muss man anschließend das physikalische Protokoll angeben, mit welchem die Daten übertragen werden, in unserem Fall RS485.

//Objekt-Definition ModbusRTUMaster

ModbusRTUMaster master(RS485);

Diese Zeile deklariert ein ModbusRTUMaster-Objekt auf einem RS485-Support, welches wir „Master“ nennen.

.Um die Kommunikationseinrichtung auf Steuerungs-Seite abzuschließen, muss man die Funktion „Setup“ des Programms starten.

void setup() { 

                 // Starten der Verbindung RS485

                 RS485.begin(38400, HALFDUPLEX, SERIAL_8N1);//(8N1 = 8bits, parity = None, bits de stop = 1)

               // Starten des Objekts ModbusRTUMaster

               master.begin(38400);

}

Wenn alle diese Schritte abgeschlossen sind, ist die Kommunikation eingerichtet.

Lesen und Schreiben von Daten

MODBUS arbeitet mit Funktionen, die es ermöglichen, die auszuführende Aktion zu definieren, unabhängig davon, ob es sich um einen Lese- oder Schreibvorgang handelt, und ob bits oder Bytes übertragen werden.

Die 8 Hauptfunktionen sind :

  • Read Coils
  • Read Discrete Inputs
  • Read Holding Registers
  • Read Input Registers
  • Write Single Coil
  • Write Single Register
  • Write Multiple Coils
  • Write Multiple Registers

In unserem Fall beschränkt uns die industrialShield-Software, welche die Verwendung der ARDBOX-Steuerungen ermöglicht, auf die Verwendung von zwei Funktionscodes:

  • Read Coils
  • Write Multiple Registers

Beim Aufruf dieser Funktionen müssen wir Parameter definieren:

ReadCoils() :

//Diese Funktion wird die 3 Bits lesen, die auf das Adressbit 1 von Slave Nr. 1 folgen

//(Slave-Nr., Adresse, Anzahl) ;

master.readCoils(1, 1, 3); //(Slave-Nr., Adresse, Anzahl)

Nachdem diese Funktion gestartet wurde, können Sie die gelesenen Bits in einer Tabelle gespeichern werde,, um sie weiter zu verarbeiten, z. B. :

//Definition der Modbus-Antwort, die auf die ReadCoils()-Anfrage folgt

ModbusResponse response = master.available();

//Auslesen der Bits der Antwort (hier ist das erste gelesene Bit dasjenige mit der Adresse 3 in //Slave. Es wird in Coils[0] gespeichert)

for (int i = 0 ; i < 3 ; i++) {

                               bool coil = response.isCoilSet(i);

                               Coils[i] = coil;

                }

//Aktivierung der Relaisausgänge R4 und R6 entsprechend der Adressbits 3 und 4 im Slave

               digitalWrite(R4, Coils[0]);

               digitalWrite(R6, Coils[1]);

 

Auf der Ebene der GUI-Programmierung müssen Sie dann das durch eine Taste aktivierte Bit mit dem in der Funktion readCoils() gesetzten Bit abgleichen

WriteMultipleRegisters() :

//Lesen der digitalen Eingänge der Steuerung und Speicherung in einer Tabelle

               DigitalIn[0] = digitalRead(I0_1);

               DigitalIn[1] = digitalRead(I0_2);

               DigitalIn[2] = digitalRead(I0_3);

 

   

               //Definition eines Zustands-Registers für die digitalen Eingänge

                int Reg_DigitalIn = 0;

               for (int i = 0; i < 3; i++) {

               Reg_DigitalIn = (Reg_DigitalIn + (DigitalIn[i] * (pow(2, i))));

                }

 

                //Ausfüllen der Tabelle welche die zu schreibenden Register enthält

               Reg[0] = Reg_DigitalIn;

               Reg[1] = analogRead(I0_6);

 

   //Versenden der Tabelle

//(Slave-Adresse, Schreibadresse, Werte, Anzahl der Register)

master.writeMultipleRegisters(1, 1, Reg, 2);

 

Um die Zustände der digitalen Eingänge auf der GUI anzuzeigen, müssen Sie Anzeigen erstellen und diese wie folgt programmieren:

Um den Status eines Analogeingangs zu anzuzeigen, kann man z. B. einen Balkendiagramm erstellen und wie folgt programmieren:

Beispiel :

#include <ModbusRTUMaster.h>

#include <RS485.h>

/* Parametrierung Iview207M :

    Modicon 984 Master(RTU) sublink

    38400, 8N1, Panel Address : 1; PLC adress : 1; autre : 0

*/

 

// Definition des ModbusRTUMaster -Objekts, mit RS-485

ModbusRTUMaster master(RS485);

const uint32_t baudrate = 38400UL;

bool DigitalIn[3];

int Reg[3];

int graph = 0;

bool Coils[5];

 

 

 

////////////////////////////////////////////////////////////////////////////////////////////////////

void setup() {

  Serial.begin(9600UL);

  // Definition MODBUS Verbindung

    RS485.begin(baudrate, HALFDUPLEX, SERIAL_8N1);//(8E1 = 8bits, parity = Even, bits de stop = 1)

  // Starten des Modubus Master Objekts

// Die Baudrate kann geählt werden (default: 19200)

  master.begin(baudrate);

}

 

 

////////////////////////////////////////////////////////////////////////////////////////////////////

 

void loop() {

  switch (graph) {

   

    case 0 :

      //Lesen von digitalen Eingängen als Aufzeichnung in einer Tabelle

      DigitalIn[0] = digitalRead(I0_1);

      DigitalIn[1] = digitalRead(I0_2);

      DigitalIn[2] = digitalRead(I0_3);

      graph = 1;

 

    case 1 :

      //Deklaration eines Registers, das die Werte der analogen Eingänge enthält

      int Reg_DigitalIn = 0;

      for (int i = 0; i < 3; i++) {

        Reg_DigitalIn = (Reg_DigitalIn + (DigitalIn[i] * (pow(2, i))));

      }

      //Ausfüllen der Tabelle, welche die zu schreibenden Register enthält

      Reg[0] = Reg_DigitalIn;

      Reg[1] = analogRead(I0_6);

      graph = 2;

 

 

    case 2 :

      delay(5);

      master.readCoils(1, 1, 100);

      ModbusResponse response = master.available();

      if (response.getFC() != 0) {

        graph = 3;

      }

 

    case 3 :

      if (response) {

        if (response.hasError()) {

          Serial.println(„error“);

          // Behandlung von Antwortfehlern. Man kann response.getErrorCode() verwenden

          // um den Fehlercode zu erhalten

        } else {

          // Get the coil value from the response

          for (int i = 0 ; i < 5 ; i++) {

            bool coil = response.isCoilSet(i);

            Coils[i] = coil;

          }

          digitalWrite(R4, Coils[0]);

          digitalWrite(R6, Coils[1]);

        }

        graph = 4;

      }

     

    case 4 :

      delay(5);

      master.writeMultipleRegisters(1, 1, Reg, 5); //(Slave-Adresse,Schreibadresse, Werte, Anzahl der Register)

      ModbusResponse response1 = master.available();

      if (response1.getFC() != 0) {

        graph = 0;

      }    

  }  //fin switch

//fin loopAAF_NRJ1_DIN

Visuel automatisation technic-achat
0 Bemerkungen

Hinterlasse einen Kommentar