Socket-Kommunikation via sps mit arduino/raspberry

freak1051

Ensign
Registriert
Dez. 2012
Beiträge
198
Hallo community,

Habe mal so ne allgemeine Frage. Ich selbst bin SPS-Programmierer und mache gerade den Automatisierungstechniker. Mir schwirrt schon länger im Kopf rum, etwas mit Haus-Automation zu machen mittels einer SPS. Leider ist alles "komfortable" wie Profinet oder ProfiBUS kostentechnisch nicht realisierbar, sodass ich mir des erst mal aus dem Kopf geschlagen habe.

Nun hatte ich diese Woche das erste Mal Kontakt mit einem Kamera-System welches ich über TCP/IP-Socket Kommunikation ansprechen musste. Im Zuge dessen habe ich ein Tool gefunden (Socket-tester 3) mit dem ich recht einfach auf einem PC einen "Server" aufsetzen kann, und mich damit verbinden. Nach etwas experimentieren ging alles recht gut, sowohl Pakete senden, wie auch empfangen (asynchron).

Jetzt kam mir die Idee, ob es nicht möglich wäre, so einen "Bus-Teilnehmer" zu bauen.

Würde mir das so vorstellen, dass ich ein steuer-Wort mittels TCP/IP an arduino/pi sende, und mir zu dem Zeitpunkt das "Endgerät" konsistent in einem Doppelwort oder String oder wie auch immer, das prozessabbild seiner ein-und Ausgänge sendet. Klar habe ich mich dann auf der sps um das Datenhandling zu kümmern, aber das ist nicht das Problem. Zeit kritisch soll hier eh nichts passieren.

Nun ist die Frage, ob soetwas schon mal jemand gemacht hat, oder infos hat. Mit dem arduino hab ich einige Tutorial-Erfahrung und auch schon einige einfachere Sachen selbst gemacht, allerdings hab ich die IO's der Pi noch nie genutzt (auch noch nie python programmiert). Auch hab ich noch nie mit nem ethernet-shield auf dem arduino gearbeitet.

Hat jemand Lösungsansätze/tutorials/snippets an der Hand, mit dem man die Aufgabenstellung angehen kann? Würde mich sehr über Informationen freuen

Mfg

Daniel
 
Was soll überhaupt die sps machen? Naja jedenfalls gibts für die siemens cps ne Bibliothek für socket Verbindungen. Profinet ist basiert ja auf tcp/ip
 
Hab noch nicht so richtig kapiert was du vorhast. Um mit einer SPS zu kommunizieren, bietet sich libnodave an. Dabei wird die Standardschnittstelle auf TCP 102 genutzt.
 
freak1051 schrieb:
Leider ist alles "komfortable" wie Profinet oder ProfiBUS kostentechnisch nicht realisierbar,
Profinet geht doch normal über Ethernet, da es nicht zeitkritisch sein muss tuts jedes normale Netzwerk.

freak1051 schrieb:
Würde mir das so vorstellen, dass ich ein steuer-Wort mittels TCP/IP an arduino/pi sende, und mir zu dem Zeitpunkt das "Endgerät" konsistent in einem Doppelwort oder String oder wie auch immer, das prozessabbild seiner ein-und Ausgänge sendet.
Ein kleiner Modbus/TCP Server wäre da wie geschaffen dafür. Lässt sich auf einem Arduino locker realisieren.

freak1051 schrieb:
Nun ist die Frage, ob soetwas schon mal jemand gemacht hat, oder infos hat.
Ich habe sowas vor vielen Jahren gemacht als der Duemillanove gerade das heiße Eisen war ;).
Zuerst UDP basiert, natürlich mit Sequenznummern und Prüfsummen, sogar auf Wunsch per OTP verschlüsselt und dann noch mal als einfacher Modbus/TCP Server. Punkto Ressourcen auf dem 328 beides überhaupt kein Thema.
Das Gegenstück war allerdings keine SPS sondern ein Programm auf einem stinknormalen x86 Computer. Konnte Sensorwerte erfassen, umwandeln/verarbeiten, darauf reagieren, Ausgänge schalten, hatte einen einfachen PID Regler, usw usf.

Bei Python kann ich Dir aber leider nicht weiterhelfen, war bei mir alles in C und abgesehen vom Zugriff auf das Ethernet Shield weitgehend frei von den Arduino Libs. Doku und Libraries waren damals schon ganz gut und werden sicher nur noch besser geworden sein.

Woran genau stehst Du denn an?
 
Na mein Gedanke ist als Beispiel in einem Party-Raum Lichter und Aktoren zu schalten, oder evtl. nen Türkontakt Überwachen. Fensterkontakte Überwachen etc.

Geschickt wäre mir halt, wenn ich in ner UVDose nen Arduino platzieren könnte und somit lediglich 5 Inputs und 5 Outputs habe (plus reserve). Behandenln würde ich es in der SPS gerne wie n "normaler" Bus-Teilnehmer mit 8 DI/DO´s. Ich würde Das Abbild dann in meine SPS lagern bearbeiten und wieder schreiben, falls ein Aktor am Arduino etwas tun soll.

Wie gesagt die SPS seite ist Komplett. Es geht mir darum, dass ich Mit der SPS ein "Steuerwort" senden kann. meinet wegen ein String "lesen" und damit weiß der arduio, dass er seine Eingänge in ein Wort legen soll. zurück würde ein Wort kommen mit dem Systemabbild. Als Bsp 184. damit weiß ich (dualcodiert) welcher Eingang High und welcher Low ist.

Weiters würde ich gerne mit einem Steuerwort "schreiben" und hinter her eine zahl schreiben, damit der Arduino weiß, welche Ausgänge er schreiben muss.

Das Handling in der SPS ist fertig. Die Steuerworte können Angepasst werden. und ob ich nachher einen String Raus schickt oder ne Zahl oder n "Ausgagsbyte" oder n "Ausgangsword" ist mal wurst.

ich denke auch die Arduino Seite dürfte in sofern kein Problem darstellen, dass er auf "Irgendwas" hört, und wenn da eben eins der oben beschriebenen trigger-Strings kommt muss der Arduino einen Code ausführen.

Hängen tu ich daran: Den Arduino "TCP-IP-fähig" machen. Also in so zu Programmieren, dass er eine Art "Server" aufmacht, mit dem ich mich mit der SPS verbinde, der Arduino auf befehle hört, welche über das TCP/IP kommen und auch wider was verschickt.
 
dir sollte das OSI 7 Schichten Modell bekannt sein und du musst dir überlegen auf welcher Ebene du überhaupt "rum machen" möchtest.

statt jetzt ganz unten auf socket ebene anzufangen und alles darüber selber zu machen, würde man üblicherweise z.B. auf MQTT aufsetzen. Dafür bekommst du auch die nötigen Bibliotheken für den Arduino.

man muss das Rad ja nicht ganz neu erfinden, dafür haben sich darüber schon genug Leute den Kopf zerbrochen ;)
 
  • Gefällt mir
Reaktionen: Raijin
Naja, auf der Socket-Ebene ist halt mein Code in der SPS schon komplett durch. Ist die Frage ob ich dann mein Persönliches Rad auf dem Arduino neu erfinde oder auf der SPS :)
 
Ich verstehe immer noch nicht so recht was du vorhast. Für mich klingt das wie von hinten durch's Auge in die Brust. Du willst scheinbar eine eigene Schnittstelle entwickeln, obwohl das nicht wirklich notwendig ist.

Wenn du vom Arduino aus auf die SPS zugreifst - zB mit oben verlinkter libnodave - dann kannst du doch die SPS pollen und zB auf ein Trigger-Bit lauschen. Dazu fragst du einfach im 250/500/1000/2000 ms Takt (je nach Anforderung) mit einem simplen Lesebefehl ein Bit in der SPS ab und wenn es true ist, liest du die eigentlichen Daten aus der SPS aus oder du pollst diese Daten direkt und ohne Triggerbit. Andersherum schreibst du vom Arduino aus in der SPS regelmäßig deine Datenworte in einen DB und setzt falls nötig ebenfalls ein Triggerbit, um in der SPS einen Prozess zu starten, etc.

Eine eigene Schnittstelle zu bauen, die irgendwelche Strings durch die Gegend schickt, ist deutlich über's Ziel hinausgeschossen. Das Problem dabei ist nämlich, dass du schnell an die Grenzen der Schnittstelle stößt, wenn du weitere Kommandos benötigst. Nach obigem Prinzip musst du nur in der SPS ein paar DBs definieren und dann vom Arduino aus diese DBs lesen und/oder schreiben, fertig. Die Schnittstelle an sich ist durch besagte libnodave-dll sichergestellt und besteht nur aus simplen Read- und Write-Anweisungen.
 
freak1051 schrieb:
Den Arduino "TCP-IP-fähig" machen. Also in so zu Programmieren, dass er eine Art "Server" aufmacht, mit dem ich mich mit der SPS verbinde, der Arduino auf befehle hört, welche über das TCP/IP kommen und auch wider was verschickt.
Wenn Du die Arduino Libraries benutzen möchtest, https://www.arduino.cc/en/reference/ethernet .
Das Chat- und Web-Server Beispiel sollte, für C, die nötigen Grundlagen beschreiben. Zu "arduino python ethernet" findet google genug, der erste Link sollte passen.
Ansonsten bedarf es halt den Kampf durch das Datenblatt des WizNet Chips (5100/5200/...).

Es gab auch noch etwas Fertiges für s7, settimimo oder so ähnlich hieß die Library.
 
Okay, dann mal komplett einfach gesagt.

ich möchte mit der SPS den Eingangsstatus des Arduino auslesen. Das ganze zu dem Zeitpunkt zu dem ich es möchte. (Deshalb muss ein Auftrag, egal in welcher Form, von der SPS an den Arduino erfolgen) TCP/IP Kommunikation ist bei einer SPS Azyklisch. Deshalb muss dieser Handshake erfolgen : SPS sendet Abfrageauftrag an Arduino. Arduino anwortet mit Abbild seiner Eingänge. Das Datenformat ist jetzt mal egal.

Und der zweite Schritt ist, das die SPS ausgäge vom Arduino schreiben kann. Wie hier die Kommunikation ist ist auch mal Wurst. Ich stelle mir das mit 2 Byte
A0A1A2A3A4A5A6A7A8A9A10A11A12A13A14ST
1111111110000001

Die zweite Zeile ist das Abbild, welches gesetzt werden soll

Somit sende ich ein 0xFF01. Das St ist das Steuerbit. Liegt dieses auf High soll der Arduino die Ausgänge schreiben, liegt deses auf lo will die SPS die Eingänge lesen.

Libnodave fällt raus. 1. möchte ich es aus interesse so testen, und 2. möchte ich den Arduino-Code nicht anfassen, wenn ich eine andere Steuerung einbaue. Bei der Libnodave.dll muss ich im Bereich Rack/Slot anfassen, wenn ich eine 300er oder 1500er verbau.
 
Zuletzt bearbeitet:
Nun gut, wenn du die Schnittstelle zu Fuß entwickeln möchtest, rate ich dir dazu, dir ein adäquates Protokoll zu definieren, das auch für potentielle Erweiterungen geeignet ist.

Grundsätzlich bietet sich TCP als Übertragungsprotokoll an, weil du ja sichergehen willst, dass die Pakete ankommen. Darüber hinaus sollte eine Message in etwa so aussehen:

STX<msgnr><opcode><daten><crc>ETX

Anfangs möchtest du vielleicht nur eine Art Lesebefehl von der SPS an den arduino senden, aber evtl. willst du später auch mal einen Schreibbefehl senden. Es tut nicht weh, ein paar Byte für opcode (zB banal "R" bzw. "W") im TCP-Paket zu verwenden. Auch tut eine Checksumme am Ende nicht weh und sichert dafür die Integrität der Daten. Die msgnr zu Beginn des Pakets, die der arduino bei der dazugehörigen Antwort übernimmt, dient der Zuordnung des jeweiligen Requests zum Reply.

Ob ein TCP-Paket nun 10 Byte oder 1000 Byte überträgt, ist einerlei, es ist so oder so genau ein Paket, nur die Payload bzw der obige Messagestring ist etwas länger.

Mit diesem Prinzip kannst du dir dann überlegen welche Kommandos sinnvoll wären. Wenn's am Ende nur beim "Gib mir alles"-Befehl bleibt ok, aber wenn du zB auch mal einzelne Werte lesen willst oder eben auch mal von der SPS aus etwas im arduino schreiben möchtest (zB irgendwelche Sollwerte), dann lohnt sich der Mehraufwand für ein adäquates Protokoll.

Ohne jetzt persönlich Erfahrung mit dem arduino zu haben, kann man sich dieses Beispiel anschauen. Mit client.read() liest man die Daten, die vom Client (SPS) kommen. Nun würde man nach obigem Schema die Bytes auseinandernehmen, STX bzw ETX suchen - die muss die SPS natürlich aktiv an den Anfang bzw das Ende der Message setzen. Die Message dazwischen wird dann mit der Checksumme geprüft und anschließend Byte für Byte in msgnr, opcode und Daten gesplittet.
 
Gibt's Fortschritte oder ist das Projekt gestorben?
 
Zurück
Oben