TIA Wiederholtes verwenden von SEND_PTP (RS232)

Chris:UniBE

Level-1
Beiträge
6
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

Schlimmer als sein Code der nicht funktioniert, ist ein Code der funktioniert und man weiss nicht wieso :rolleyes:

Ich will verschiedene Kommandos nacheinander über die Serielle Schnittstelle versenden.
Heisst… ich will das erste Kommando versenden, warten bis es raus ist, dann das nächste… usw.

Ich habe das realisiert in dem ich den "DONE" Ausgang der SEND_PTP Module verwende (Bild im Anhang)
Dies funktioniert.

ABER! Es funktioniert nur wenn ich für jedes SEND_PTP-Modul einen eigenen DB verwende.
Wieso ist dies so?
Was wenn ich 100 Befehle nacheinander senden möchte?

Für jeden Hinweis wäre ich enorm dankbar.

Grüsse
Christoph

SPS: S7-1200 / CPU1214C DC/DC/DC
Module: CM 1241 RS232
 

Anhänge

  • code.jpg
    code.jpg
    39,6 KB · Aufrufe: 34
Da du auf einer Seriellen Linie sowieso nur ein Telegramm auf einmal loswerden kannst, macht es gar keinen sinn mehrere Send_PTP Module aufzurufen. Das macht man mit einem einzigen und wechselt nur die Telegramme aus.

z.B. So
Code:
REGION Senden von Daten    IF #Remote_Aktiv THEN // nur wenn RemoteIO Aktiv und erreichbar ist, auf die HW Adresse schreiben (sonst wird Diagnosebuffer unnötig gefüllt)
        #Send(REQ    := #Fut_Tel_Koppel.Send_Koppel.Req,
              "PORT" := #Serial_PORT, // HW Adresse des PTP Ports
              BUFFER := #Fut_Tel_Koppel.Send_Koppel.Tel,
              LENGTH := ULINT_TO_UINT(#Fut_Tel_Koppel.Send_Koppel.Len),
              DONE   => #Fut_Tel_Koppel.Send_Koppel.Done,
              ERROR  => #Fut_Tel_Koppel.Send_Koppel.Error,
              STATUS => #Fut_Tel_Koppel.Send_Koppel.Status);
    END_IF;
    IF #Fut_Tel_Koppel.Send_Koppel.Error THEN // Status bei Error wegsichern.
        #send_status := #Fut_Tel_Koppel.Send_Koppel.Status;
    END_IF;
    
    #Fut_Tel_Koppel.Send_Koppel.busy := #Fut_Tel_Koppel.Send_Koppel.Status <> 16#7000;
    
    
END_REGION

Dann füllst du dein Telegramm in Telegrammbuffer und deklarierst die Länge (ich mach das üblicherweise in einem anderen Baustein)
Wenn der Buffer schrieben wurde, dann setzt du Req auf True. Und wartest ab bis done oder error kommen, danach setzt du Request zurück.
Wenn Req false ist, dann füllst du den Telegrammbuffer mit dem neuen Telegramm füllst die Länge ab und setzt das Req.

Das Req blockiert in der zeit die anderen zu sendenden Telegramme. Ob du die Telegramme aus einem FIFO Array abarbeitest, oder verschiedene Bausteine die möglichkeit haben das Abzufüllen. ist dann wieder eine Sache des Aufbaus.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo vollmi,

Besten Dank für deinen Input... ich werde es versuchen umzuprogrammieren.
Normalerweise arbeite ich mit Mikrokontrollern und mir macht die SPS "denkensweise" noch etwas Mühe.

Eine Frage:
Wenn du von komplett unterschiedlichen Bausteinen aus, absolut asynchron, serielle Kommandos über ein und dieselbe Schnittstelle versenden willst.... wie machst du das?
 
Wenn du von komplett unterschiedlichen Bausteinen aus, absolut asynchron, serielle Kommandos über ein und dieselbe Schnittstelle versenden willst.... wie machst du das?
Die Telegramme bzw. Anforderungskennungen in einen FIFO legen. Und die Senderoutine schaut zyklisch nach, ob Sendeanforderungen im FIFO vorhanden sind. Wenn ja, dann das zugehörige Telegramm versenden.

Harald
 
Dann Arbeite ich üblicherweise mit einem Case das mir die verschiedenen Telegrammarten auseinanderhält.
Also sagen wir
Telegramm "setze Konfig" hat wertigkeit 1 und wird selten gesendet
Telegramm "befehlEIN/AUS" hat wertigkeit 2 und wird oft gesendet

Das sieht dann etwa so aus.
Das wäre dann z.B. der Controllbaustein der neben dem Sendeempfangsbaustein steht. Ich mach das so damit ich den SendeEmpfangsbaustein wo der PTP Send und so drin ist, auch tauschen kann z.B. gegen einen TCP sendeempfangsbaustein, wenn ich z.B. Ethernet Serialserver einsetze. Dann muss ich den Controllbaustein nicht anpassen und kann den schön nebenher immer weiterentwickeln.
Code:
CASE #ComCase OF // Hier werden die Telegramme die Anstehen angeschaut.    1: 
        REGION Setconfig
            IF NOT #Fut_Tel_Koppel.Send_Koppel.Req AND #Telegramstarten THEN // ist der Sendebaustein frei? REQ = FALSE? Könnte man auch vor dem Case machen. ich prüfe aber meistens noch ein paar sachen vor der prüfung ob die Sendeeinheit bereit ist.
                IF #Partner.setconfig.Req THEN // Soll ein Config gesendet werden?
                        #Data_Len := #Len_SetConfig;
                        "FC_SendTelCompose"(Count     := #Data_Len,
                                            TagCmd    := #Partner.TagCmd,
                                            Data      := #Partner.setconfig.Telegram,
                                            Command   := #Cmd_SetConfig,
                                            SenderTel := #Fut_Tel_Koppel.Send_Koppel.Tel);
                        #Fut_Tel_Koppel.Send_Koppel.Len := #SendTelHeadLen + #Chk1 + #Data_Len + #Chk2;
                        #Partner.setconfig.Req := false;
                        #Fut_Tel_Koppel.Send_Koppel.Req := true;
                    END_IF;
            END_IF; // Wenn kein Config gesendet werden soll, mach mal weiter im Programm
                #ComCase += 1;
        END_REGION
    2:
        REGION SetEinAus
            IF NOT #Fut_Tel_Koppel.Send_Koppel.Req AND #Telegramstarten THEN // ist der Sendebaustein frei? REQ = FALSE?
                IF #Partner.SetEinAus.Req  THEN // Soll ein Befehl gesendet werden?
                    #Data_Len := #Len_SetEinAus;
                    "FC_SendTelCompose"(Count     := #Data_Len,
                                        TagCmd    := #Partner.TagCmd,
                                        Data      := #Partner.SetEinAus.Telegram,
                                        Command   := #Cmd_SetEinAus,
                                        SenderTel := #Fut_Tel_Koppel.Send_Koppel.Tel);
                    #Fut_Tel_Koppel.Send_Koppel.Len := #SendTelHeadLen + #Chk1 + #Data_Len + #Chk2;
                    #Partner.SetEinAus.Req := false;
                    #Fut_Tel_Koppel.Send_Koppel.Req := true;
                END_IF;
            END_IF;
            #ComCase += 1;
        END_REGION
ELSE
        #ComCase := 1;
END_CASE;
 
vollmi... Danke.
Ich sehe, ich muss mich unbedingt mit SCL auseinandersetzen.
Aktuell programmiere ich alles in FUP. Grunsätzlich wäre mir aber SCL näher, da ich von der Mikrokontroller Programmierung in C her komme.
Besten Dank.
 
Zurück
Oben