PHP + Siemens PLC

Zuviel Werbung?
-> Hier kostenlos registrieren
Auch von mir mal ne Rückmeldung,

hab die erste Version auch ohne Probleme bei mir am laufen, für meine Hausvisu
(IPS).Danke für deine tolle Lib.

Wie schaff ich es so wie bei der ersten Lib die rückgabe als Byte Array
Gruß Michael
 
Zuletzt bearbeitet:
Wie schaff ich es so wie bei der ersten Lib die rückgabe als Byte Array
Gruß Michael

In der ersten Version werden in einer for-Schleife die SPS-Daten in ein Array kopiert. Wenn du die neue Version mit deiner ggf. alten Programmierung die ein Array erwartet verwenden willst, müsstest du diese Schleife wieder ans Ende der Lese-Methoden einbauen (oder eine andere Variante die ein String in ein Array wandelt).

Das Handling mit Strings ist in php aber einfacher, da auch der Netzwerksocket einen String als Rückgabewert zurückgibt.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Danke Dir das wars,
das mit dem string mag sein aber meine Funktionen für meine Visu bauen auf Bytes auf.
Wenn ich mal Zeit hab schreib ich diese mal um,was aber immer ein bisschen dauert weil meine PHP-kentnisse noch nicht so toll sind.

danke gruß Michael
 
Hallo zusammen,

ich bin gestern beim Schmökern durchs Forum auf dieses PHP-Script gestoßen und da ich gerne mal herumexperimentiere habe ich mich gleich daran versucht...

Leider habe ich ein Problem, das für euch evtl. lösbar ist :)

Environment (alles auf einer Maschine):
PC (192.168.1.130) mit Step7 V5.4 SP4 + PLCSim (Verbindung:TCP/IP)
Ein S7-Programm mit 317 PN/DP (192.168.1.130)
nettoplcsim (connected mit PLCSim) (Client: disconnected)
xampp mit dem PHP-Script unter htdocs (localhost)

Wenn ich nun das PHP-Script (s7plc_test_simple.php) im Mozilla aufrufe:
PHP:
// Daten lesen 
    $db = 10;
    $plcdata = $plc->ReadBytes("DB" , $db, 40, 4 ); // 4 Bytes im DB10 ab DBB40 lesen
erscheint:
Verbunden mit 192.168.1.130
Fehler beim Lesen der Daten!


Im nettoplcsim sehe ich, dass er aus meinem angegebenen DB die Daten ausliest!

Was läuft hier schief?

Hoffe ihr könnt mir weiterhelfen?!?!

Gruß Mike
 
Wenn ich nun das PHP-Script (s7plc_test_simple.php) im Mozilla aufrufe:
PHP:
// Daten lesen 
    $db = 10;
    $plcdata = $plc->ReadBytes("DB" , $db, 40, 4 ); // 4 Bytes im DB10 ab DBB40 lesen
erscheint:
Verbunden mit 192.168.1.130
Fehler beim Lesen der Daten!


Im nettoplcsim sehe ich, dass er aus meinem angegebenen DB die Daten ausliest!

Was läuft hier schief?

Hoffe ihr könnt mir weiterhelfen?!?!

Hast du den DB10 denn mit der entsprechenden Länge (44 Bytes) in die SPS bzw. Plcsim geladen? Funktioniert das Lesen von anderen Bereichen, z.B. Merkervariablen?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Also ich habe irgend einen DB (DB10) aus meinem Projekt genommen. Er ist viel größer als 44Byte und auf der PLCSim ist er auch!
Wie gesagt das nettoplc hat mir was in HEX angezeigt.
Merker habe ich erst gar nicht porbiert.
Ich bin erst wieder am Dienstag am Rechner.

Soll ich dir von irgendwas nen Screenshot oder so machen?

Gruß Mike
 
Hab den Fehler gefunden. Da merkt man mal wieder dass man nicht alles Wissen von C auf php übertragen kann, auch wenn es ähnlich aussieht. Obwohl ich mir sicher bin dass es irgendwann schonmal funktioniert hat...
Aber dann hatten einige damals doch Recht, weil einige die Abfrage auskommentiert haben (ist auch nur für WinAC interessant).

Zeilt 357 muss wie folgt geändert werden:
PHP:
} elseif (strlen($recv) > 7 && !((ord($recv[6]) & 0x80) == 0x80 )) {
oder die Datei s7plc.php aus dem Anhang nehmen.
 

Anhänge

  • s7plc-2011-03-03.zip
    3,7 KB · Aufrufe: 90
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin Thomas,

ich habe es gleich mit deinem neues Script versucht aber es geht immer noch nicht!
Ich habe mal einen Screenshot vom nettoplc gemacht. Es zeigt mir in HEX das Byte an welches ich auslese!
In dem Byte DB10.DBB40 steht 15 (DEZ) bzw. 0F (HEX).

PHP:
// Daten lesen 
    $db = 10;
    $plcdata = $plc->ReadBytes("DB" , $db, 40, 1 ); // 1 Byte im DB10 ab DBB40 lesen
db10.jpg


Also die Kommunikation sollte doch demnach gehen nur die Ausgabe im PHP-Script scheint nicht zu funktionieren.

Der Rückgabewert: $plcdata ist demnach = NULL
PHP:
if ($plcdata != null) {
        for ($i = 0; $i < strlen($plcdata); $i += 2) {
            $iVal = $plc->getS16At($plcdata, $i);
            echo "DB".$db.".DBW".$i." = " . $iVal . "<br />";
        }
    } else {
        echo "Fehler beim Lesen der Daten!<br />";
    }
Weiterhin bekomme ich bei allen Abfragen, die kleiner als 4BYTE sind folgende Fehlermeldung:
#########################
Verbunden mit 192.168.1.130

Notice: Uninitialized string offset: 28 in C:\xampp\xampp\htdocs\s7plc\s7plc.php on line 284
Fehler beim Lesen der Daten!
#########################

Hoffe du ahst noch ne Idee!?!
Gruß Mike

EDIT: Ich rufe s7plc_test_simple.php auf! Wenn ich Merker lese passiert das gleiche wie beim DB-lesen. Die Änderung von dir am Script bezieht sich doch auf das Schreiben WriteBytes(), nicht wahr? Ich versuche ja erstmal nur zu lesen...
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
EDIT: Ich rufe s7plc_test_simple.php auf! Wenn ich Merker lese passiert das gleiche wie beim DB-lesen. Die Änderung von dir am Script bezieht sich doch auf das Schreiben WriteBytes(), nicht wahr? Ich versuche ja erstmal nur zu lesen...

Ja, irgendwie hatte ich die Korrekturen nur bei WriteBytes eingebaut, warum auch immer. Musste natürlich in allen 3 Funktionen angepasst werden.
Eigentlich habe ich auch gar keine Zeit und Lust den Code weiter zu supporten. Das Programm ist nun wirklich sehr überschaubar, da kann man auch selber einen Blick reinwerfen.

Des weiteren kannst du mit getS16At() auch nur Daten aus dem Puffer lesen wenn du auch mindestens 2 Byte gelesen hast. Du liest aber 1 Byte aus der SPS und willst 2 Bytes lesen, das geht nicht.
 

Anhänge

  • s7plc-2011-03-08.zip
    3,7 KB · Aufrufe: 243
Hi Thomas,
ich hab mir den Code schon etwas angesehen aber die ganzen x01/x02 etc. schrecken mich total ab... davon verstehe ich leider nichts!

Ich kann dich verstehen, dass du da keine Lust mehr hast... ich versuche morgen nochmal mein Glück und wenns mich so interessiert werde ich es auch noch selbst herausbekommen wie es geht ;)
Frage mich nur wieso es bei den Anderen funktioniert hat?

Danke vielmals!

Mike
 
Es funktioniert :)
Leider kommt mir jetzt was dazwischen und ich kann nicht weiter machen...
Aber grundsätzlich geht´s und ich kann ruhig schlafen ;)

Danke Thomas!!
 
Hi zusammen,

ich habe mal etwas Zeit investiert und das PHP-Script von Thomas in eine Website (localhost/XAAMP/PLCSIM/NETTOPLC/FIREFOX) eingebaut.
Die Daten werden zyklisch mit AJAX in die Seite geladen damit man keine unschönen Aktualisierungsefekte wie bei F5 oder so hat.

http://img690.imageshack.us/img690/9642/j50.mp4

Die Aktualisierungszeit des AJAX beträgt 500ms ... wie lange der Server braucht um die Daten zu liefern weiß ich noch nicht... sieht aber so aus als hätte ich im worstcase mehr als 1Sek.

Ich versuche demnächst das ganze insichtlich Aktualisierungszeit zu optimieren. Keine Ahnung welche Zeiten da möglich sind!
Sollte es nicht unter 500ms gehen, wird das ganze wohl nur zu Visu-Zwecken wie Statistiken einsetzbar sein und nicht zum Bedienen.

Außerdem muss ich erstmal das PHP-Script von Thomas verstehen (wie kann man da einzelne bits lesen?) Thomas gibt es da evtl. was zum nachlesen?

Gruß Mike
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Die Aktualisierungszeit des AJAX beträgt 500ms ... wie lange der Server braucht um die Daten zu liefern weiß ich noch nicht... sieht aber so aus als hätte ich im worstcase mehr als 1Sek.

Ich versuche demnächst das ganze insichtlich Aktualisierungszeit zu optimieren. Keine Ahnung welche Zeiten da möglich sind!
Sollte es nicht unter 500ms gehen, wird das ganze wohl nur zu Visu-Zwecken wie Statistiken einsetzbar sein und nicht zum Bedienen.

Außerdem muss ich erstmal das PHP-Script von Thomas verstehen (wie kann man da einzelne bits lesen?) Thomas gibt es da evtl. was zum nachlesen?

Hallo,
um einzelne Bits zu lesen musst du aus einem gelesenen Byte das entsprechende Bit ausmaskieren. Am einfachsten machst du dir eine eigene ReadBit Methode welche Readbyte aufruft und das entsprechende Bit ausmaskiert. Es gibt zwar im S7-Protokoll extra Funktionen um einzelne Bits zu lesen, aber das Lesen eines einzelnen Bits "kostet" (im Sinne von Bandbreite und Zeit) genausoviel wie das Lesen eines ganzen Bytes.

Bei der Performance gibt es ein grundsätzliches Problem wenn du das Skript auf einem Webserver laufen lässt, weil es bei jeder neuen Anfrage erst die Verbindung zu SPS aufbauen muss (TCP Connect, S7 Verbindungsaufbau) und dann erst Daten lesen kann.
Eigentlich würde es reichen die Verbindung nur einmalig zu öffnen und dann offen zu halten, dann geht das Lesen wesentlich schneller vonstatten.

Vielleicht ist es ja doch irgendwie möglich im Kontext des Webservers quasi einen Hintergrunddienst laufen zu lassen. Wenn das möglich ist, würde ich nämlich folgendermaßen vorgehen:
Auf dem Webserver liegt eine Konfigurationsdatei für den S7-Server, mit den Daten Name, Datentyp, Adresse, Pollrate.
Z.B.
Messwert_1, REAL, DB1.DBD0, 1s

Der Server baut dann einmalig die Verbindung zur SPS auf und pollt im entsprechenden Zyklus die Daten und legt sie in einem internen Speicher ab.

Wenn dann ein XML Request z:b. für die Variable "Messwert_1" kommt, gibt der Server die Daten aus dem internen Speicher zurück (evtl. noch mit einem Statuswert). So kommen die Daten ohne große Wartezeit zurück.
Vom Prinzip her also wie ein einfacher OPC-XML Server.
 
Websockets statts AJAX

Ich denke man könnte auch versuchen auf Websocket (http://de.wikipedia.org/wiki/WebSocket) statts AJAX umzusteinen, für eine Visu. Das scheint ja dann doch zeitvorteile zu bringen! Inwieweit das von PHP unterstütz wird, kann Ich aber nicht sagen, und am Script von Thomas müsste dann bestimmt auch einiges gändert werden! Ab alle aktuellen Browser scheinen die ja schon zu unterstützen! (Sogar der IPhone Safari) (Ausser der IE (selbst in 9.0 noch nicht!), aber dafür gibts ja auch schon ne Lösung: https://github.com/gimite/web-socket-js)
 
Zurück
Oben