PHP + Siemens PLC

Zuviel Werbung?
-> Hier kostenlos registrieren
Und nochmal ein Bug...

Es gingen immer nur die ersten 5 Bits eines Bytes (Hatte es nicht gemerkt, da Ich bei meiner Visua fürs Iphone immer neue Structs hatte, wo max 4 Bits drinn waren...)

muss sagen, mit dieser Lib und iWebKit kann man sich in ein paar Minuten ne schöne Bedinung fürs I-Phone basteln...
 

Anhänge

  • s7plc.zip
    1,9 KB · Aufrufe: 145
Hi Leute,
sorry wenn ich das Thema noch mal reaktiviere, aber seh ich das richtig
Das Script ist für Iso on Tcp geschrieben?
Dann wäre es schön, wenn mir mal einer die Vergabe der Tsap 's erklären könnte ;-).

Grund:
Hab hier ne 1200 er die zwar über php mit nem einfachen Socket Script auch angetriggert wird, sprich es wird wohl nen socket über eine normale TCP Verbindung aufgebaut, die S7 Bausteine geben jedoch immer einen in der Doku nicht beschriebenen Kommunikationsfehler aus.

Also hab ich das Script hier mal probiert,1200er seitig auch die richtigen Bausteine verwendet, komme aber so auch nicht zum Ziel, vermute es hängt an den Tsaps ( an den Bausteinen falsch eingetragen???)

Da ich in PHP noch nicht so fit bin, fällt es mir schwer zu deuten was die Abfrage auf 300/400er Steuerung bringen soll bzw, wo diese Abfrage dann weiter verwendet wird.

Wenn ich das script hier starte läuft es einfach nur durch , am Baustein zeigt er mir nen Fehler an, aber er scheint weder zu lesen noch zu schreiben.

Für Tips wär ich echt wahnsinnig dankbar ;-) , reicht mir das ich hauptberuflich nach 10 Jahren Step7 mich nun in Codesys reinfuchsen muss.

Lg Micha
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Diese Abfrage 200/300/400er CPU ist nur durch das umsetzen von diesem C# Programm hineingekommen.
Das einzige was man damit anfangen kann ist, dass bei einer 300er die CPU immer auf Rack 0 und Slot 2 sitzt. Bei einer 400er kann ich die CPU an fast jede Position im Rack stecken.

Imho ist das php-Teil ziemlich mit der heißen Nadel gestrickt, da z.B. die Ebene ISO-Protokoll eigentlich überhaupt nicht implementiert ist. Spätestens bei den "funny 7-byte packets" (Zitat von Zottel aus libnodave) einer WinAC kracht es nämlich.

Mit einer 1200er funktioniert das glaube ich auch nicht, denn was ich hier mal an Protokollmitschnitten gesehen habe, sieht der Datenaustausch schon etwas anders aus, auch wenn die grundlegende Kommunikation - also ISO-on-TCP, und Teile der S7-Kommunikation - gleich sind. Darum bekommst du auch einen Verbindungsaufbau hin, nur Daten können nicht gelesen/geschrieben werden.
 
Dann wäre es schön, wenn mir mal einer die Vergabe der Tsap 's erklären könnte ;-).

Grund:
Hab hier ne 1200 er die ....

Wir haben da auch eine Klasse zur Kommunikation mit Siemens SPS
http://pvbrowser.org/pvbrowser/sf/manual/rllib/html/classrlSiemensTCP.html
Durch diese Doku kann man sich bis in die Implementierung "durchclicken"

Der eigentliche Verbindungsaufbau ist dabei etwas im dunkeln :-(
Es wird ja über TCP/IP kommuniziert.
TSAPs gibt es aber nur bei OSI Netzwerken (wie z.B. VOTS DECnet Phase V)
Siemens hatte ursprünglich auf solche OSI Netzwerke gesetzt.
Heute wird aber TCP verwendet aber dabei verwendet man den speziellen Port 102
iso-tsap 102/tcp # ISO-TSAP Class 0
iso-tsap 102/udp # ISO-TSAP Class 0

Die beiden "TSAP" (die es bei TCP ja eigentlich garnicht gibt) werden nach dem Aufbau der TCP/IP Verbindung gesendet.
Siehe:
http://pvbrowser.org/pvbrowser/sf/m...mensTCP.html#14d6ae4a736f17e41fd79a14d3f65abc

Höchst wahrscheinlich musst Du nur hier experimentieren:
00073 if(rack_number != -1) connect_block[17] = rack_number;
00074 if(slot_number != -1) connect_block[18] = slot_number;
Das ist bei jedem SPS Typ etwas anders (dahinter versteckt sich der TSAP)

PS: Die 1200er haben wir noch nicht testen können :-(
 
00073 if(rack_number != -1) connect_block[17] = rack_number;
00074 if(slot_number != -1) connect_block[18] = slot_number;
Und du bist dir sicher dass das da richtig ist?

Meiner Meinung nach ist bei der Destination TSAP das erste Byte immer 0x02, das zweite Byte setzt sich aus Rack und Slot zusammen. Wobei die rechten 5 Bits der Slot sind, und die linken 3 Bits das Rack.

Beispiele für Destination TSAP:
Rack 0 / Slot 2:
0x02 0x02

Rack 7 / Slot 18:
0x02 0xF2

Rack 0 / Slot 18:
0x02 0x12
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Und du bist dir sicher dass das da richtig ist?

Meiner Meinung nach ist bei der Destination TSAP das erste Byte immer 0x02, das zweite Byte setzt sich aus Rack und Slot zusammen. Wobei die rechten 5 Bits der Slot sind, und die linken 3 Bits das Rack.

Beispiele für Destination TSAP:
Rack 0 / Slot 2:
0x02 0x02

Rack 7 / Slot 18:
0x02 0xF2

Rack 0 / Slot 18:
0x02 0x12

Bei der S7200 steht da schon mal
connect_block[17] = 'M'
connect_block[18] = 'W'
also nicht immer 0x02

Das mit rack/slot ist mir auch noch etwas nebulös.
Die Namensgebung ist alt und vielleicht nicht sehr glücklich.

Jedenfalls geht es mit:
static const unsigned char s7_200_connect_block[] = {3,0,0,22,0x11,0xE0,0x00,0x00,0x00,0x01,0x00,0xC1,2,'M','W',0xC2,2,'M','W',0xC0,1,9};
static const unsigned char s7_300_connect_block[] = {3,0,0,22,0x11,0xE0,0x00,0x00,0x00,0x01,0x00,0xC1,2,1 ,0 ,0xC2,2,1 ,2 ,0xC0,1,9};
static const unsigned char s7_400_connect_block[] = {3,0,0,22,0x11,0xE0,0x00,0x00,0x00,0x01,0x00,0xC1,2,1 ,0 ,0xC2,2,1 ,3 ,0xC0,1,9};
auf den mir bekannten SPS Typen.
 
WinCC unterscheidet zumindest nicht zwischen S7-300 und 400. Und bei der S7-Protocol-Suite werden Destination-TSAP dem Rack und Slot entsprechend wie ich es oben geschrieben habe zugewiesen.
Mit 200er Steuerungen habe ich nichts zu tun.

Woher hast du denn deine Informationen, wenn nicht durch Abhören einer Kommunikation? Hast du deinen pvbrowser auch mal an 400er Steuerungen und exotischen Rack/Slot Kombinationen getestet?
Bei einer WinAC muss der Destination TSAP zumindest passen, kann ja sein dass es eine 400er Steuerung garnicht stört.

Edit:
Zottel hat das in seinem Code auch genauso, laut seinen Kommentaren steht da auch noch:

1, // Function (1=PG,2=OP,3=Step7Basic)
2, // Rack (Bit 7-5) and Slot (Bit 4-0)
// 0 for slot = let select the plc itself the correct slotnumber
 
Zuletzt bearbeitet:
Da muss noch etwas "Forschungsarbeit" geleistet werden oder
bei Siemens müsste es ein Leck geben :)

TSAP (Transport Service Access Point) bei OSI Netzen
entspricht in etwa einem Port bei TCP/IP.

Das ist ein Wert (TSEL Hex), der frei vergeben werden kann, in diesem Falls frei nach Belieben von Siemens. Es ist durchaus möglich, dass die da rack/slot mit rein verwurschten.

In unsere Lib haben wir deshalb die Möglichkeit connect_block[17], connect_block[18] von außen vorzugeben, damit man da probieren kann
bzw. das eintragen kann, was einem z.B. tcpdump sagt.

Leider habe ich hier nicht so viel Hardware rumstehen,
sonst würde ich tcpdump anschmeissen und mal eine Tabelle mit gültigen TSAP anfertigen.

Frage in die Runde: Wer könnte mal so eine Tabelle anfertigen ?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Slot geht maximal bis 18, da das größte Rack für eine S7-400 18 Steckplätze hat.
Wieviele Racks maximal gehen weiß ich nicht, meine größte 400er Konstellation hatte 5 Racks. Da für Rack aber nur 3 Bits zur Verfügung stehen, würde ich mal sagen: maximal 7 ;-)
 
Also erst mal vielen Dank für die Menge an Antworten.

Ich höre schon raus, des wird net einfach ;-).

Das heisst die Nächte am nächsten WE sind bei mir verplant. Vorher komme ich wahrscheinlich nicht dazu weiter zu testen.

Eine Frage stellt sich mir aber doch noch auf die schnelle, warum sollte der Datenaustausch bei der 1200er anders aufgebaut sein?
Ich meine, da würde das grosse S ja das Rad neu erfinden.

Gut, das mit Rack und Slot kann durchaus Architektur bedingt schon anders aussehen.

Netzteil,CPUund I/O's in einem Block.

Mit der 1200er geht Siemens da dann wohl den Weg der Codesys basierten Controller. Einzelne Bausteine ändern ist nicht. Komplettes Prog kompilieren und dann übertragen. Und dabei noch CPU in Stop. Irgendwie tödlich wenn man es anders gewohnt ist.

Ich hab ja noch Hoffnung das über ein Firmware update der Webserver integriert wird, den die CPU in Hannover on Board hatte. Vielleicht kann man da ja dann ansetzen.

Nur die SD Karte mit 24 MB, die dafür benötigt wird,kostet soviel wie die CPU, irgendwas um die 200 €. Da hätte ich dann auch ne 300er nehmen können. Und alles nur weil ich gern spiele ;-)

Wäre aber schön wenn ihr trotzdem noch mit am Thema bleiben würdet ;-)
 
Nochmal zurück zum Destination TSAP:
Das erste Byte stellt die Verbindungsressource dar.

Dazu steht in der WinCC Hilfe:
WinCC Online Hilfe schrieb:
Verbindungsressource
gibt die Verbindungsressource als Hexadezimalwert an. Das Feld ist nur aktiviert, wenn das Kontrollkästchen "Rohdatenblock senden/empfangen" aktiviert wurde.Die Verbindungsressource wird bei der Projektierung der festprojektierten Verbindung (sog. PBK-Verbindung) in der AS von STEP7 vergeben.Wertebereich (hex) :10 - DF

Wenn die Option "Rohdatenblock senden/empfangen" nicht angehakt ist, wird dort immer ein 0x02 übertragen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
So, nun war Wochenende und ich bin auch nen Schritt weitergekommen.

Basis war das auf der Siemens Website vorhandene Beispiel zur Verbindung zwischen 2 1200er Steuerungen. Hab dort einen unspezifizierten Partner mit der IP meines Webservers eingestellt, anstelle der sendenden 1200er.
Der verwendete Baustein bietet keine Möglichkeit zur Tsap eingabe, sei hier kurz angemerkt.

Im Script hier meine Ip Adresse eingetragen, Racknummer gelassen und als Steckplatz 1 angegeben. Das Script gestartet und ein Erfolgserlebnis.

Lesen klappt vorzüglich.

Nun wollte ich denn auch mal schreiben ;-)

Schwups, den Projektteil mit dem Senden gegen den mit dem Empfangsbaustein ausgetauscht. Und nichts ging!!

Habe dann noch ein bisschen mit dem Script hier rumgespielt, dabei aber nur besonderheiten der 1200er aufdecken können.

In der CPU ist nur noch der Empfangsbaustein mit entsprechenden DB's und trotzdem kann das Script den DB noch auslesen.

Eigentlich wird doch der Socket im Script geschlossen oder hab ich das falsch gelesen?

Demzufolge hätte ich doch beim nächsten Start keinen sendenden Partner mehr wenn der Baustein in der Cpu nicht vorhanden ist und müsste eine Fehlermeldung bekommen.
Spannung von der Cpu entfernen und Neustart nur mit dem recv Baustein, trotzdem kann ich Aktualdaten aus dem DB lesen.

Statusänderung am Recv Baustein hab ich nicht. Der behauptet er würde auf eine Verbindung warten.

Jetzt vermute ich mal die bestehende Verbindung zum Senden an das script verhindert das ich schreiben kann.

Hat evtl. noch jemand ne Idee?

Und im Script steht beim read was von "x02" ; Typ Byte
und beim write was von "Chr(132)" 0x84 Datenbaustein.

Weiss da jemand die Kennungen für Word , String etc. bzw. was ausser DB kann man da noch angeben ? über ?


LG Bitti
 
Genau was ich gesucht hab, bei google war ich nicht wirklich erfolgreich - aber per Zufall hier gelandet und siehe da...

Danke dass sich jemand die Mühe gemacht hat das in PHP umzusetzen!

Ich werd's dann gleich mal nächste Woche testen. :)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich habe mal auf die schnelle was in php zusammengestümpert, kannst ja mal testen ob das bei dir funktioniert, und ob das so ist wie du dir das vorgestellt hast. Ich hab das eben nur mal mit meinem nettoplcsim grob durchgetestet - Daten kommen zumindest rein.
Hallo
Das PHP Script funktioniert bei mir mit einer S7-400 aber bei einer S7-300
nicht.
400er: $plc = new S7PLC("S7400", "121.11.58.10", 0, 3, "TestSPS");
Ist OK
300er: $plc = new S7PLC("S7300", "121.11.74.23", 0, 2, "TestSPS");
NOK
Fehlermeldung
Uncaught exception 'Exception' with message 'WrongNumberReceivedBytes'
an der Stelle werden 0 Bytes zurueckgegeben.
Vielleicht kann mir jemand helfen den Fehler einzukreisen.
Danke
 
Hallo
Das PHP Script funktioniert bei mir mit einer S7-400 aber bei einer S7-300
nicht.
400er: $plc = new S7PLC("S7400", "121.11.58.10", 0, 3, "TestSPS");
Ist OK
300er: $plc = new S7PLC("S7300", "121.11.74.23", 0, 2, "TestSPS");
NOK
Fehlermeldung
Uncaught exception 'Exception' with message 'WrongNumberReceivedBytes'
an der Stelle werden 0 Bytes zurueckgegeben.
Vielleicht kann mir jemand helfen den Fehler einzukreisen.
Danke

Hallo,
die Auswahl ob "S7300" oder "S7400" ist nicht relevant, du kannst also auch auf eine 300er mit "S7400" zugreifen.

Welche Version verwendest du denn, die erste von dieser Seite dieses Threads? Das war nur ein "Schnellschuss" sozusagen. Kann sein dass deine 300er fragmentierte Pakete verschickt (habe ich bisher nur bei einer WinAC so gesehen), die diese php Version nicht verarbeiten kann.

Ich hänge meine letzte Version mal an in der ich das korrigiert habe, und zusätzlich ein paar Konvertierungsfunktionen vorhanden sind.
Kannst ja mal testen ob sich das mit der anders verhält.

Ansonsten entwickle ich das nicht weiter, und nutze das auch kaum. Aber ich habe das mittlerweile schon an mehrere Leute per Email verschickt. Leider gab es weder positive oder negative Rückmeldungen :-(

Gruß
Thomas
 

Anhänge

  • s7plc-2011-02-11.zip
    6,1 KB · Aufrufe: 108
Hallo
Ich glaube ich hab den Fehler gefunden. Hatte nicht die erste Version genommen. Musste folgende Aenderung machen und es lief .
PHP:
                //S7300: Chr(194) & Chr(2) & Chr(3) & Chr(2)  'Fremder Tsap
                $bSend1[15] = 194;
                $bSend1[16] = 2;
                $bSend1[17] = 3;
                $bSend1[18] = $this->Rack * 2 * 16 + $this->Slot;
                break;
$bSend1[17] = 2;
Soll das die Slotnummer sein? Werd aber nun deine neue Version
nehmen.
Danke.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo
Ich glaube ich hab den Fehler gefunden. Hatte nicht die erste Version genommen. Musste folgende Aenderung machen und es lief .
PHP:
                //S7300: Chr(194) & Chr(2) & Chr(3) & Chr(2)  'Fremder Tsap
                $bSend1[15] = 194;
                $bSend1[16] = 2;
                $bSend1[17] = 3;
                $bSend1[18] = $this->Rack * 2 * 16 + $this->Slot;
                break;
$bSend1[17] = 2;
Soll das die Slotnummer sein? Werd aber nun deine neue Version
nehmen.
Danke.
Nein, die Rack/Slot-Nummern sind wie zu sehen in Byte 18 verwurstet.

Das Ganze ist Teil des COTP-Protokolls.

$bSend1[15] = 194; <-- 0xc2, zeigt an dass als nächstes ein Parameter vom Typ "destination tsap" folgt

$bSend1[16] = 2; <-- zeigt an dass der Parameter 2 Bytes lang ist

$bSend1[17] = 2; <-- Byte 1 des Parameters, Siemens Spezial (2=OP Funktion)

$bSend1[18] = <-- Byte 2 des Parameters, Siemens Spezial Rack/Slot
 
Ansonsten entwickle ich das nicht weiter, und nutze das auch kaum. Aber ich habe das mittlerweile schon an mehrere Leute per Email verschickt. Leider gab es weder positive oder negative Rückmeldungen :-(

Gruß
Thomas

Hier mal ne Rückmeldung: Nutze immer noch die Erste Version welche Ich um die schreibfunktionen erweitert hab. Funzt astrein, Steuere damit mein Garagen und meinbScheunentor, sowie die Lichter! Danke für die Lib!

P.S. Hast du die schreibfunktionen in deine neue Version auch eingebaut?
 
Hier mal ne Rückmeldung: Nutze immer noch die Erste Version welche Ich um die schreibfunktionen erweitert hab. Funzt astrein, Steuere damit mein Garagen und meinbScheunentor, sowie die Lichter! Danke für die Lib!

P.S. Hast du die schreibfunktionen in deine neue Version auch eingebaut?

Hm, eine WriteBytes und WriteBit Funktion habe ich drin. Und ich habe noch etwas bezüglich timeout-Verhalten angepasst, wenn eine IP nicht erreichbar ist. Der Socket wird auf non-blocking gesetzt und kehrt in dem Fall sofort zurück, und nicht erst nach x Sekunden.
 
Zurück
Oben