Problem mit Modbus über WiFi

Hallo,

habe mich so eben in diesem Forum angemeldet weil ich seit heute Probleme mit der Modbus Verbindung habe.

Erst lief alles einwandfrei.
Heute wollte ich an meinem Projekt weiter arbeiten und musste feststellen, dass die Modbus Verbindung nicht mehr läuft.

Als Modbus Client verwende ich einen Arduino Mega 2560 mit WIFI shield.
Der Modbus Server läuft auf einer Phoenix SPS ILC 171 ETH.

Was merkwürdig ist, das ich alle 3 - 4 Minuten die Meldung vom Arduino bekomme das der Modbus nicht aktiv ist.
Darauf folgt dann umgehend die Meldung, dass er wieder aktiv ist.
Das hatte ich beim letzten testen so nicht.

#include <MudbusWiFi.h>
#include <SPI.h>

#define RE(signal, state) (state=(state<<1)|(signal&1)&3)==1

char ssid[] = "PxC";
int status = WL_IDLE_STATUS;
MudbusWiFi Mb;

int in22 = 22;
int in23 = 23;
int out24 = 24;
int out25 = 25;
int state;




void setup()
{
  Serial.begin(9600);
 
  if (WiFi.status() == WL_NO_SHIELD)
  {
    Serial.println("WiFi shield not present");
    while (true); // don't continue
  }
  else
  {
    Serial.println(WiFi.localIP());
    status = WiFi.begin(ssid);
    if (status != WL_CONNECTED)
    {
      Serial.println("nicht verbunden");
      while (true);
    }
    else
    {
      Serial.println("Verbunden");
      Serial.println(WiFi.localIP());
    }
    pinMode(in22, INPUT);
    pinMode(in23, INPUT);
    pinMode(out24, OUTPUT);
    pinMode(out25, OUTPUT);
  }
}

void loop()
{

  Mb.Run();

  Mb.R[11] =  Mb.R[10];
  //Mb.R[13] = Mb.R[12];
  Mb.C[0] = digitalRead(in22);
  Mb.C[1] = digitalRead(in23);
  if (RE(digitalRead(in22), state))

 digitalWrite(out24, bitRead(Mb.R[11], 0));

}

Vieleicht habt Ihr ja eine Idee.

Falls Ihr mehr Infos braucht, werde ich diese gerne liefern.

Besten Dank schon mal

Mit "nicht aktiv" meinst du "nicht verbunden" ??
Wenn ja, die Meldung kann nur im setup() ausgegeben werden also beim Starten des Arduino. Dann ist alle 3-4 Minuten eine Situation vorhanden die den Arduino neustartet.

Gruß

Die Meldung ob der Modbus läuft oder nicht kommt meiner Meinung nach aus dem Mb.run();

Hier kleiner auszug aus der Lib.

/****************** Read from socket ****************
  // For Arduino 1.0
  WiFiClient client = MbServer.available();
  if(client.available())
  {
    Reads = 1 + Reads * (Reads < 999);
    int i = 0;
    while(client.available())
    {
      ByteArray[i] = client.read();
      i++;
    }
    SetFC(ByteArray[7]);  //Byte 7 of request is FC
    if(!Active)
    {
      Active = true;
      PreviousActivityTime = millis();
      #ifdef MbDebug
        Serial.println("Mb active");
      #endif
    }
  }
 
if (first == LOW)
 {
   MbServer.begin();
   Serial.println("MbServer Begin");
   first = HIGH;
 } 

  if(millis() > (PreviousActivityTime + 60000))
  {
    if(Active)
    {
      Active = false;
      #ifdef MbDebug
        Serial.println("Mb not active");
      #endif
    }
  }

Funktioniert denn die Verbindung bis zu dem Moment wo die Meldung erscheint?

Nein leider auch das nicht mehr.

Ich hab so garkeinen Plan mehr warum es funktioniert hat und dann nicht mehr.

Hab da leider keine Ahnung davon, sorry. Vorallem kennt man die Gegenseite nich, aber interessant ist das Thema.

#include <MudbusWiFi.h>

Ist das ein Tippfehler oder heisst die Bibliothek wirklich so? Auf jeden Fall solltest Du einen Link auf diese Bibliothek posten, sehr verbreitet scheint sie nicht zu sein.

Hast Du schon überprüft, ob Dein Arduino und Deine SPS im Netz per Ping erreichbar sind?

Hallo,

sorry für die späte Antwort, musste auf Montage.

Nein das ist kein tippfehler, habe mich auch gewundert.
Hier kann man sich die Dateien holen.

GitHub - bonelessc/MudbusWiFi: A ModBUS TCP Library for the Arduino WiFi Shield.

Das überprüfen ob die Geräte im Netz erreichbar sind mach ich bei jedem einschalten einmal, aus macht der Gewohnheit.

Da gibt es keine Probleme bis jetzt >:(

Als Modbus Client verwende ich einen Arduino Mega 2560 mit WIFI shield.
Der Modbus Server läuft auf einer Phoenix SPS ILC 171 ETH.

Die von Dir verwendete Bibliothek unterstützt aber nur den ModBus Server-Teil. Wenn das also grundsätzlich funktioniert, dann ist die Rollenverteilung anders rum.

Die Inaktivitätsmeldung wird von der Bibliothek ausgegeben, wenn vom Client während 60 Sekunden kein Request kam. Das Problem sollte sich also auf der SPS lösen lassen, wenn die öfters Anfragen schickt.

Nach der beschreibung auf der Seite sowie im Kommentar der Dateien ist es eine Slave lib.

Mudbus.h - an Arduino library for a Modbus TCP slave.

A ModBUS TCP Slave Library for the Arduino WiFi Shield based on the Mudbus library Copyright (C) 2011 by Dee Wykoff.

This library utilizes ModBUS to communicate to a ModBUS master by a WiFi connection. All credtis go to Dee Wykoff for the base work, we merely altered the library to use WiFi.

Copyright (C) 2015 by Ton Verra

Nach der beschreibung auf der Seite sowie im Kommentar der Dateien ist es eine Slave lib.

Master und Slave gibt's nur bei ModBus RTU. Bei ModBus TCP heissen die Client und Server, wobei der Server für den Sensor-Node gedacht ist (also bei ModBus RTU einem Slave entspricht), während der Client auf dem Controller läuft (also wiederum bei ModBus RTU einem Master entspricht). Aber auch bei ModBus RTU macht der Master die Anfragen, der Slave antwortet darauf. Es ist nicht immer so, das Master = Server und Slave = Client :).

Wie oft fragt denn Deine SPS den Arduino ab?

Hallo,

die SPS fragt alle 500ms ab.

Dann dürfte die Verbindung so schlecht sein, dass die allermeisten Requests nicht durchkommen. Hast Du die WiFi-Qualität mal überprüft? Was meint ein am gleichen WiFi angeschlossenes WireShark? Sieht es die Requests und werden sie beantwortet?

Hallo,

Problem gelöst.
In dem Code den ich als erstes gepostet habe hat die SPS nur 2 coils abgefragt.
Nun habe ich noch einmal ganz von vorn angefangen.
Und siehe da wenn ich nun ein Register hinzufüge das beschrieben werden kann läuft die ganze Sache wieder.
auch mit dem Code den ich zu Anfang gepostet habe.

Vielen Dank für eure Hilfe

Hier nun der neue Code

#include <SPI.h>
#include <MudbusWiFi.h>
#include <avr/pgmspace.h>
//#include <WiFi.h>
#define RE(signal, state) (state=(state<<1)|(signal&1)&3)==1
MudbusWiFi Mb;



int in22 = 22;
int in23 = 23;
int out24 = 24;
int out25 = 25;
int state;
int total_hit = 0;
uint8_t hex;
const int time_out = 2000;

void setup()
{
  // Mb.setID(1);
  Serial.begin(9600);
  char ssid[] = "PxC";      //  WLAN SSID
  // char pass[] = "12345678";   // Netzwerkschlüssel
  int status = WL_IDLE_STATUS;     

  // WIFI Hardware angeschlossen
  if (WiFi.status() == WL_NO_SHIELD)
  {
    Serial.println("WiFi Hardware nicht erkannt");
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  Serial.println(fv);
  if ( fv != "1.1.0" )
    Serial.println("Firmeware updaten");

  // WIFI Verbindung aufbauen
  while ( status != WL_CONNECTED) {
    Serial.print("Verbindungsaufbau zu: ");
    Serial.println(ssid);
    // SSID

    status = WiFi.begin(ssid);

    // 10 sekunden warten bis Verbindung aufgebaut ist
    delay(10000);
  }



  printWifiData();
  

  pinMode(in22, INPUT);
  pinMode(in23, INPUT);
  pinMode(out24, OUTPUT);
  digitalWrite(out24, LOW);
  pinMode(out25, OUTPUT);
  digitalWrite(out25, LOW);

}

void loop()
{
  Mb.Run(); // Modbus TCP Starten
  Mb.R[11] =  Mb.R[16];
  // Mb.R[13] = Mb.R[12];
  Mb.C[0] = digitalRead(in22);
  Mb.C[1] = digitalRead(in23);


  /*if (RE(digitalRead(in22), state))
    {
    total_hit += 1;
    hex = total_hit;
    word hit_count = total_hit;
    //Mb.R[12] = hex;
    }*/

  digitalWrite(out24, bitRead(Mb.R[11], 1));




}

void printWifiData() {
  // IP
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Adresse: ");
  Serial.println(ip);

  // MAC
  byte mac[6];
  WiFi.macAddress(mac);
  Serial.print("MAC Adresse: ");
  Serial.print(mac[5], HEX);
  Serial.print(":");
  Serial.print(mac[4], HEX);
  Serial.print(":");
  Serial.print(mac[3], HEX);
  Serial.print(":");
  Serial.print(mac[2], HEX);
  Serial.print(":");
  Serial.print(mac[1], HEX);
  Serial.print(":");
  Serial.println(mac[0], HEX);
  // SSID
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // Signalstärke
  long rssi = WiFi.RSSI();
  Serial.print("Signalstärke:");
  Serial.print(rssi);
  Serial.println(" dBm");
}

Danke für die Rückmeldung, hab das Thema auch weiterverfolgt. :slight_smile:

Mich würde noch das Programm interessieren das auf der SPS läuft, wäre es Möglich da einen Blick drauf zu werfen?

Gruß