System-Voraussetzungen
Produkt-links
Software :
SPS-Programmiersoftware (Windows) : https://document.technique-achat.com/industrial-shields/arduino-1.8.6-windows.zip
]SPS-Programmiersoftware (MacOs) : https://document.technique-achat.com/industrial-shields/arduino-1.8.6-macosx.zip
(Setup-Tutorial für die SPS-Programmiersoftware: https://blog.technic-achat.com/?p=5671&preview=true)
Iview-Programmiersoftware (Windows) : https://document.technique-achat.com/IMO/HMI/IVIEW/iview_developer_v4_0_3_31.zip
Arduino-Libraries : https://github.com/IndustrialShields/arduino-Tools40
(Wie man eine Bibliothek in einem Arduino-Programm hinzufügt)
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:
![1](https://blog.easi-spare.de/wp-content/uploads/2020/07/1.jpg)
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).
![2](https://blog.easi-spare.de/wp-content/uploads/2020/07/2-1.png)
Software-Konfiguration
Kommunikation-Einrichtung auf GUI-Seite
In der Iview-Programmiersoftware muss die Kommunikation wie folgt konfiguriert werden :
![3](https://blog.easi-spare.de/wp-content/uploads/2020/07/3-1.png)
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
![4](https://blog.easi-spare.de/wp-content/uploads/2020/07/4-1.png)
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:
![5](https://blog.easi-spare.de/wp-content/uploads/2020/07/5-1.png)
Um den Status eines Analogeingangs zu anzuzeigen, kann man z. B. einen Balkendiagramm erstellen und wie folgt programmieren:
![6](https://blog.easi-spare.de/wp-content/uploads/2020/07/6.png)
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