ModBus

mailmir

Level-1
Beiträge
75
Reaktionspunkte
3
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

ich nutze Beckhoff-Hardware. Beim aktuellen Projekt haben wir einen CX5120. Hier haben wir einige ModBus-Feldgeräte von Biral und Belimo. Das ist eigentlich auch kein Problem.
Bei meinen bisherigen Projekten habe ich bei der IBS immer wieder festgestellt das bei fehlender Kommunikatio sehr oft die Busleitung das Problem war (falsch angeschlossen usw.)
Gibt es da einen Befehle den alle Modbusteilnehmer, egal von welchem Hersteller beantworten, quasi wie ein PING. Dann könnte ich vorab immer erstmal schauen welche Teilnehmer ich erreiche.

DNAKE schon mal.

Gruß Norbert
 
Ich hab keine Ahnung von Beckhoff obwohl hier immer wieder viele schreiben was für geiles Zeug
der Kram sein soll.... ;)

Bitte korrigiere mich wenn ich was falsches schreibe. :confused:
Modbus RTU oder Modbus TCP ? Ist aber auch egal.
Ich denke du hast für die Programmierung TwinCAT und dafür gibt es doch eine Softwarebibliothek Kommunikation
die zB. eine Modbus-RTU-Kommunikation über eine serielle RS232-, RS422- oder RS485-Schnittstelle realisiert.

Diese Bausteine aus der Softwarebibliothek müssen doch eine Fehlerbehandlung haben wenn ein Slave auf ein
Telegramm keine Antwort gibt. Damit hast du doch deinen Ping für jeden Teilnehmer.

Sorry das ich dir hier nicht weiter helfen kann im TIA Portal hätten wir das Problem in 0,5 Sekunden beseitigt.

Gruss

Nachtrag:
oder meist du einen Befehl wie bei Windows "Ausführen" Ping + Adresse zum testen ob ein Teilnehmer da ist ? Das gibt es nicht bei Modbus
 
Zuletzt bearbeitet:
@Capiain Future

oder meist du einen Befehl wie bei Windows "Ausführen" Ping + Adresse zum testen ob ein Teilnehmer da ist ? Das gibt es nicht bei Modbus

GENAU so etwas meine ich

@Holger
Ich hab da etwas im Infosys von Beckhoff gefunden. Wenn ich an einen Slave eine Anfrage sende, Muss ich ja immer die Modbus-adresse angeben,
die Registeradresse und die Anzahl der Register die ich lesen möchte. Diese Infos habe ich im Infosys leider nicht gefunden. Kannst Du mir da auch weiterhelfen?

Ich mach das immer so (arTempDaten usw. nur als Bsp.):

Master.ReadRegs(
Quantity:= 9,
MBAddr:= 0,
cbLength:= SIZEOF(arTempDaten),
pMemoryAddr:= ADR(arTempDaten),
Execute:= TRUE,
Timeout:= T#2s,
BUSY=> ,
Error=> ,
ErrorId=> ,
cbRead=> );


IF (NOT Master.BUSY) THEN
Master.ReadRegs(Execute:= FALSE);
IF Master.Error THEN
bModBusFehler[State] := TRUE;
arrLetzteErrorId[State] :=Master.ErrorId;
State_Sequenz:= State_Sequenz + 1 ;
ELSE
bModBusFehler[State] := FALSE;
arrLetzteErrorId[State] :=Master.ErrorId;
State_Sequenz:= State_Sequenz + 1 ;

END_IF
END_IF
 
Diese Infos habe ich im Infosys leider nicht gefunden
:confused:
Welche Infos hast du nicht gefunden? Ich verstehe deine Frage irgendwie nicht:ROFLMAO:

Schreibe doch auch bitte dazu:
Welcher Kommunikationsweg TCP/IP oder RTU seriell.?
Wenn RTU mit Klemme KLxxx oder über Schnittstelle vom Controller?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
:confused:
Welche Infos hast du nicht gefunden? Ich verstehe deine Frage irgendwie nicht:ROFLMAO:

Schreibe doch auch bitte dazu:
Welcher Kommunikationsweg TCP/IP oder RTU seriell.?
Wenn RTU mit Klemme KLxxx oder über Schnittstelle vom Controller?

Das finde ich auch etwas mehr Info kann nicht schaden

Seine erste Frage war ob es einen Befehl unter Modbus gibt bei Windows "Ausführen" Ping + Adresse
Ich als nicht Beckhoff Fachfrau sage "NEIN" den gibt es nicht.
Wenn du bei Deiner Inbetriebnahme testen willst ob alle Teilnehmer da sind dann muß du Software wie Modbus Poll benutzen

Ansonsten muß Du im Programm bei jedem Zugriff auf einen Teilnehmer die Antwort ( respond) auswerten ob Busy, Done oder Error
oder wie der Kram bei euch heißt.
 
Nach dem geposteten Baustein vom Thread-Eröffner dürfte es sich um ein serielle Kommunikation handeln.

Und bei serieller Kommunikation ist es immer etwas mühsam festzustellen ob die Kommunikation geht/nicht geht oder halb geht (duplex versus half duplex). Das ist halt das Problem wenn man allgemeine HW (beliebige serielle Schnittstellen) und viele Möglichkeiten (Modbus ASCII, Modbus RTU oder oder oder) abdecken will/muss. Flexible, kommt aber mit einem Kostenfaktor daher.

Prinzipiell:
-Jeder Slave sollte in seiner Doku definieren welche Modbus-Funktion er unterstützt. Es gibt keine zwingend vorgeschriebene Funktion. Eine equivalentes Teil zu einem Ping gibt es nicht da Modbus je nach Slave-Hersteller z.B. sehr sehr sehr dürftig implementiert ist.
-Wie schon weiter oben erwähnt musst du schauen ob du im TwinCAT Antworten erhälst über den Busy-Ausgang und den Fehlercode.
-Wenn du eine Antwort erhälst, diese aber unbrauchbar ist (d.h. es gibt einen ensprechenden Fehlercode) könntest du (aus der Erinnerung heraus) im Baustein auf eine interne Struktur schauen die dir das empfangene Telegramm logisch in die Modbus-Elemente auflöst. Dann sieht man gegebenenfalls wo das Problem ist. Letztendlich ist es aber nur eine etwas detaillierte Info als der Fehlercode.

Guga
 
als ich mit Modbus (RTU, RS485 Halfduplex) nicht weiter kam,
habe ich 2 RS485->RS232 wandler gebaut (2 ICs + 7805).
Die Signale an 2 COM-Ports (RxD) angeschlossen und in Binterm beobachtet.
(USB-RS232 geht auch falls der PC,Laptop keinen COM hat.)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

sorry, natürlich gebe ich auch mehr Infos

ich nutze immer die KL6041 von Beckhoff und kommuniziere damit per MudBus RTU

@Holger
Ich hab da etwas im Infosys von Beckhoff gefunden. Wenn ich an einen Slave eine Anfrage sende, Muss ich ja immer die Modbus-adresse angeben,
die Registeradresse und die Anzahl der Register die ich lesen möchte. Diese Infos habe ich im Infosys leider nicht gefunden. Kannst Du mir da auch weiterhelfen?

ich habe die Infos, auf welche Register/Adresse ich die Anfrage senden und abfragen muss nicht gefunden, genauso wie die Anzahl der zu schreibenden/lesenden Register.

@Captain Future

Ansonsten muß Du im Programm bei jedem Zugriff auf einen Teilnehmer die Antwort ( respond) auswerten ob Busy, Done oder Error
oder wie der Kram bei euch heißt.

Diese Auswertung mach ich sowieso, aber meine Idee war eine einfache Übersicht die unabhängig von den angeschlossenen Geräten ist. (Bsp. 100 Lampen die mir anzeigen ob ein Teilnehmer auf den Adressen 0 - 100 vorhanden ist oder nicht)
Prinzipiell ist mir ja bekannt welcher Teilnehmer welche Adresse hat und so erstelle ich ja auch die Software, aber bei der IBS gibt er bekanntlich viel Fehlerpotential (falsch eingestellte Adressen, falsch angeschlossene Geräte usw.)

@Guga

-Wenn du eine Antwort erhälst, diese aber unbrauchbar ist (d.h. es gibt einen ensprechenden Fehlercode) könntest du (aus der Erinnerung heraus) im Baustein auf eine interne Struktur schauen die dir das empfangene Telegramm logisch in die Modbus-Elemente auflöst. Dann sieht man gegebenenfalls wo das Problem ist. Letztendlich ist es aber nur eine etwas detaillierte Info als der Fehlercode.

Prinzipiell würde mir eine Antwort, EGAL welcher Art ja ausreichen. Wenn ich die Antwort auswerte und nur schaue ob diese "No Response" ist dann sollte ich doch eigentlich wissen ob da ein Teilnehmer ist oder nicht.
Fehlercode = No Response = Kein Teilnehmer bzw. ungültige Einstellungen vom Teilnehmer
Fehlercode xy = Teilnehmer vorhanden
 
Hallo,

wie bereits die Vorgänger geschrieben haben gibt es einen "ping" bei Modbus nicht

Daher einfach ein Functioncode nutzen mit einer beliebigen Adresse und einer kleinen Länge. Ist das Gerät vorhanden und wird die Anfrage nicht unterstützt, wird bei einem erreichbaren Gerät ein Exceptioncode kommen. keine Antwort ist somit nicht erreichbar
 
Hallo zusammen,

ich habe die Idee mit dem ModBus-Sucher umgesetzt und es klappt sehr gut.

Code:
CASE State_ModBus_Suche OF


0..9:
    byModBusLinie;
    byModBusAdr;


    IF bModBus_Suche THEN
        FOR iAktuell := 0 TO 254 DO
            arModBus[iAktuell] := FALSE;
        END_FOR
        bModBus_Suche_Aktiv := TRUE;
        sTime_LetzteSuche := sZeitStempel;
        State_ModBus_Suche := 10 ;
        byModBusAdr := 1;
    ELSE
        State_ModBus_Suche := 100 ;
    END_IF


10: (* Daten lesen *)


        Master.ReadRegs(
        UnitID:= byModBusAdr,
        Quantity:= 1,
        MBAddr:= iLeseAdresse,
        cbLength:= SIZEOF(wModBus_Suche),
        pMemoryAddr:= ADR(wModBus_Suche),
        Execute:= TRUE,
        Timeout:= T#2s,
        BUSY=> ,
        Error=> ,
        ErrorId=> ,
        cbRead=> );


    IF  (NOT Master.BUSY) OR TimeOut.Q THEN
        Master.ReadRegs(Execute:= FALSE);
        TimeOut(In := FALSE);
        IF Master.Error AND ( Master.ErrorId = MODBUSERROR_NO_RESPONSE) THEN
            arModBus[byModBusAdr] := FALSE;
            State_ModBus_Suche:= State_ModBus_Suche + 1 ;
        ELSE
            arModBus[byModBusAdr] := TRUE;
            State_ModBus_Suche := State_ModBus_Suche + 1 ;
        END_IF
    ELSE
        TimeOut(In := TRUE);
    END_IF


11: (* ModBus-Adresse erhöhen *)


    IF byModBusAdr < 20 THEN
        byModBusAdr := byModBusAdr + 1;
        State_ModBus_Suche := 10 ;
    ELSE
        State_ModBus_Suche := State_ModBus_Suche + 1 ;
    END_IF


12..1000:
    bModBus_Suche := FALSE;
    bModBus_Suche_Aktiv := FALSE;
    State_ModBus_Suche:= 0 ;
    State := State + 1;
END_CASE
 
Zurück
Oben