Montag, 27. März 2023

 Copyright ©  Dipl.-Ing. Johannes Hofer 2022                                           

 

Ki2Plc

Die Möglichkeiten einer  SPS-Programmierung, um diese am Geschehen der künstlichen Intelligenz zu beteiligen



Die pyPlc

Nachdem nun doch einige nachgefragt haben, wie es nun mit der KI2Plc weitergeht, habe ich mich entschlossen zunächst eine pyPlc in Python zu programmieren. Damit wird die Grundlage gebildet, mit einer SPS nach Industriestandard vorerst seine eigenen Projekte unter Windows und Python zu testen, um diese danach in ein Gerät zu laden. Hier wird in der ersten Phase folgendes Ziel zur Umsetzung geplant:

  • pyPlc komplett in Python-Code auf PyCarm
  • Funktionen entsprechend nach IEC 61131-3 - allerdings in Python 
  • Operanden nach internationaler Darstellung (englisch)
  • Merker (M, MW, MDW)
  • Input (I, IW)
  • Output (Q, QW)
  • Datenbaustein (DB)
  • Timer (TON, TONR, TOF, TP)
  • Zähler(CTU, CTD, CTUD)
  • Scale
  • Unscale
  • Funktionsbausteine (FB)
  • Functionen (FC)
  • plc_Server
  • und vieles mehr, wie z.B.: Taktkette, py2SCL, Zweipunkt-Regler, PID ...

Das ganze basiert auf Basis mit meinem YouTube-Kanal, allerdings nur in Kurzform als jeweilige Einleitung zum Thema. Die Videos fürs Mitmachen allerdings auf meinem Blog oder einer neuen Webseite (mal sehen). Da kann dann jeder beliebig oft die Videos studieren ohne mit einer scheiss Werbung belästigt zu werden.

pyPlc lernt Machine-Learning 😂

In Python kann die Idee KI2Plc sehr gut angewendet werden. Dieser Prozess kann ebenfalls in einem Gerät, wie z. B. die Simatic in SCL übersetzt zur Anwendung kommen. Der Übersetzer Python2SCL ist bereits in Arbeit. 

Das bedeutet, dass in der Plc ein Lernprozess stattfindet, der beständig ist und nie endet.

Die Umsetzung ist relativ einfach, wenn man von dem Wissen der KI ableitet. Zur Bewertung bzw. Klassifizierung werden die Daten in der PLC innerhalb des Programmes erzeugt und kommen so zur Auswertung. Das sind in erster Linie :
  • Prozesszeit
  • Gewichtung der Prozesse
Diese bestimmen dann den weiteren Ablauf und erklärt auch, dass die Prozesse in FCs und FBs aufgeteilt sein sollten. Es gibt in der pyPlc also keine eigenständigen Funktionen (def), zumindest wird das nicht empfohlen. Dazu dienen die Methoden.

Natürlich kann jeder PLC-Programmierer in Python machen was er will, bedeutet aber, dass sein Algorithnus in diesem Fall nicht bewertet werden kann und somit auch nicht sooo lernfähig ist.

Die gelante Software-Struktur

Wir überlassen nichts dem Zufall und planen unser Vorhaben wie bereits der jetzige Stand zeigen kann:

Die Klasse c_pyPlc ist unsere Ausgangsklasse, welche von der Klasse c_plc_init abgeleitet wird. Diese wiederum ist von c_plc_helper abgeleitet und letztendliche diese von c_info. Damit können wir die Methoden aus allen Ableitungen in der Klasse c_pyPlc nutzen (nicht die private). Zudem hat die Klasse c_pyPlc zusätzlich die Komposition mit der Klasse c_plc_fct, welche eine Vielzahl der SPS-Funktionen anbietet.

Und damit es nicht langweilig wird, besitzt die Klasse c_plc_init noch die Klassen socket und c_plc_database, denn schliesslich brauchen wir Merker, Fbs, Fcs, Eingänge, Ausgänge und noch vieles mehr.

 
..... Fortsetzung folgt im nächsten Blog-Beitrag 🙋



Zum Thema auf meinem Blog:
Natürlich wie immer hier kostenfrei und mit entsprechender Interesse zu diesem Thema,  kann ich das umgsetzen. Also meldet euch! 









Mittwoch, 22. März 2023

   Copyright ©  Dipl.-Ing. Johannes Hofer 2022                                           

 

Ki2Plc

Die Möglichkeiten einer Programmierung im TIA-Portal, um diese am Geschehen der künstlichen Intelligenz zu beteiligen



Simatic S7-1200 und Snap7 - Teil 2 (matrix)


Die Grundposition ist der Ausgangspunkt aller Dinge. Wie auch in Python wird hier zuerst die Grundposition überprüft und erst danach ist eine weitere Verarbeitung möglich.  Deswegen auch diese etwas verwirrenden Zeilen zum folgenden Bild:


Zunächst wird in Zeile 41 der IPL in ein char gewandelt um danach weiterhin verwendet zu werden. In unserem DB sind die Zustände als char gespeichert, deswegen die Anweisung von INT_TO_CHAR.

Solange also die Grundposition (gp) nicht erreicht wurde, wird der Baustein mit Zeile 46 verlassen. Ist die Grundposition erreicht, wird in Zeile 49 der Merker gesetzt und ein eventuell aufgetretener Fehler in Zeile 50 gelöscht. Nun wird solange das RETURN ausgeführt (Zeile 51), bis die Grundposition verlassen wird. In unserem Fall durch drücken des Eingangs V1 für den Zyl. auszufahren. So schlägt keine IF-Anweisung mehr (Zeilen 42 und 48) zu und das Programm kann ab Zeile 55 beginnen.


Nun kommt zuerst die Fehlerauswertung. Sollte der IPL den Zustand des error-Sektor besitzen, hier sind das zwei, dann wird der error_status gesetzt (Zeile 62), die Grundposition gelöscht (Zeile 61) und der Baustein verlassen. Da wir zu Beginn in Zeile 5 den Ausgang immer löschen (#matrix_out := False, in Teil-1 zu sehen) ist dieser automatisch False solange keine Zuweisung auf  True erfolgt. Der error_status ist als Ausgang Output in der Bausteinschnittstelle deklariert deklariert (letztes Bild).


Der Zustand no action entsteht immer dann, wenn der V1 nicht gesetzt ist. Ist also der IPL mit den zwei Zuständen (Zeilen 68 und 70) erfüllt, wird der Ausgang und die Grundstellung gelöscht. Hier könnte Zeile 74 entfallen 😌 , da das ja beim Eintritt des FBs immer geschieht.


Der Zustand action entsteht immer wenn der Eingang V1 gesetzt ist. Ist also der IPL mit den Zeilen 80 bis 84 erfüllt, dann wird der Ausgang in Zeile 87 gesetzt. In Zeile 91 wird die Grundstellung gelöscht und entspricht im Python der Exception. Eines der drei Zustände error, no action oder action muss vorhanden sein. Wenn nicht wird diese Zeile 91 erreicht und es muss wieder eine Grundstellung erreicht werden, damit das Spiel von vorne beginnt.

Das wäre eine getippte Lösung zur Matrix. Natürlich sollte die Matrix so interpretiert werden, dass jede beliebige Matrix übersetzt werden kann. Dabei ist auch zu überlegen, ob man nicht einen anderen Weg einschlägt, denn diese Matrix wird umfangreich, wenn grössere Projekte anstehen und auch SPS-spezifische Dinge hinzukommen.

Das könnten also Analogwerte sein, oder die noch nicht erklärten warnings, welche den Zeitfaktor berücksichtigen oder die in den Videos genannten Synapsen, welche zusätzliche Atrribute erhalten können.

Fazit: ? 
Man könnte eine Python-Sequenz an die SPS senden (write_DB), welche interpretiert wird. Also sowas wie IEC61131-3_Python? oder plc_python? oder sowas 😁, schließlich gibt es ja auch micropython!



🙋













Dienstag, 21. März 2023

  Copyright ©  Dipl.-Ing. Johannes Hofer 2022                                           

 

Ki2Plc

Die Möglichkeiten einer Programmierung im TIA-Portal, um diese am Geschehen der künstlichen Intelligenz zu beteiligen



Simatic S7-1200 und Snap7 - Teil 1

Die uns bereits bekannte Kommunikation mit den Bausteinen TRCV_C und TSENDE_C aus dem TIA-Portal (Open user communication) habe ich zur allgemeinen Information im Projekt belassen, nutze diese hier aber nicht mehr

Wir verwenden jetzt python-snap7 um die Kommunikation nun unabhängig der angebotenen Bausteine aus der Open user communication umzusetzen und schaffen so eine kleine Grundlage für ein mögliches Ziel 😁

IEC-61131-3-Python oder Plc-Python zu schaffen

Bevor wir uns damit in der Zukunft beschäftigen können, müssen wir die Grundlage erarbeiten, diese Aufgabe richtig zu verstehen. Erst dann ist eine Lösung bzw. mehrere Teil-Lösungen machbar.




Wir benötigen python-snap7, wie im Link gezeigt und können nun gezielt in einem DB Informationen ablegen, welche in SCL direkt übersetzt werden und eine quasi hardcodierte Lösung anbietet.

Darüber muss man unbedingt nachdenken, denn jetzt kann eine quasi Hardcodierung aufgrund der Daten aus KI2Plc erfolgen, welche bei jedem Training eine neue Datei und somit einen neuen Ablauf ermöglicht.

Ich kannte snap7 noch aus meiner C/C++-Tätigkeit und freue mich sehr über diese neue integrierte Lösung in python-snap7, welche ausserordentlich gut funktioniert, wenn man diese richtig anwendet und dazu die Dinge in der SPS folgerichtig versteht 😎.


Der neue Baustein Cylinder_FB (Main[OB1]) beinhaltet nun alle Dinge welche notwendig sind unsere Matrix aus KI2Plc umzusetzen. Also IPL lesen, Matrix interpretieren und OPL setzen. Sozusagen wie ein Rezept in einem Kochbuch - all in one 😀

Diese Lösung funktioniert, wie im noch ausstehendem Video zu sehen und soll keine komplette Lösung darstellen, sondern den neuen Weg erklären. Schritt für Schritt kommen wir so dem grossen Ziel näher.


Zunächst werden wir einen kleinen Check vornehmen und die gelieferten Daten überprüfen und dann den Input-Layer (IPL) lesen. Danach überprüfen wir die Grundposition und schliesslich den Rest aus der Matrix mit error, no action und action. So entsteht der Ausgangs-Layer (OPL).

Wir verwenden dazu den uns bereits bekannten DB SendReceiveData und davon den Receive-Abschnitt. Dort schreibt unser python-snap7 die Daten der Matrix hin.



In Zeile 3 und 4 sehen wir z. B. die Anzahl der Bytes (84) welche die Matrix umfasst. Dann folgen die Matrix-Daten, welche nun hardcodiert übersetzt werden können. 

Das heisst: Die Indizes, wie beim Check zu sehen (Bild unten), werden jeweils speziell in einem DB abgelegt. Hier nicht, hier habe ich diese zur Vereinfachung der Erklärung in den DB unter Constant abgetippt - damit keine Mißverständnissse entstehen -. 

So lässt sich das am einfachsten erklären.


Eine Datenprüfung im Sinne einer Checksum ist das nicht und soll es auch nicht sein. Wir sind damit zufrieden und gehen davon aus, wenn Zeile 15 erreicht wird, dass wir im Baustein weiter verfahren können um den IPL einzulesen.


Auch hier kommen wir mit einer einfachen Auswertung zurecht und haben nun einen Wert in #ipl, welcher uns zum Vergleich in der Matrix dient. Wichtig ist, dass die Reihenfolge der Daten der Reihenfolge in KI2Plc entspricht. Also wie hier ist der erste Eingang der V1 für Zyl.-Vor-Zur.
Beginnen wir im nächsten Teil mit der Grundposition  🙋













 

Montag, 20. März 2023

   Copyright ©  Dipl.-Ing. Johannes Hofer 2022                                           

 

Ki2Plc

Die Möglichkeiten einer Programmierung im TIA-Portal, um diese am Geschehen der künstlichen Intelligenz zu beteiligen



 

Pico-EVB als mini-plc Teil-3

Nun zur Matrix selbst. Ich denke dass auf einem Pico kein Programm im Sinne einer SPS zur Anwendung kommt. Projekte mit geringem Umfang sind sicherlich interessant und auch umsetzbar. Ich habe hier nun von der Matrix die action, no_action und den error aus der Matrix von KI2Plc verarbeitet. Die Grundposition fehlt hier im Beispielund macht wohl wenig Sinn, da der Zylinder ohnehin nur simuliert wird.


Hier wird _matrix() vom _thread aufgerufen und sollte ohne Unterbrechung über while True laufen. Diese Funktion ruft __matrix auf, wenn run eingeschaltet ist (True). Dazu wird auch die LED.on() verwendet, damit wir auch etwas sehen können. Der Ausgang V1_Od wird ebenfalls auf True gesetzt. Ist run False oder die Funktion __matrix() liefert False, dann schalten wir die LED ab und setzen den Ausgang zurück.



In der Funktion __matrix() erfolgt die Auswertung der Liste matrix_lst mit der Reihenfolge error (Zeile 135), no action (Zeile 140) und action (Zeile 144). 

Wie auch immer ist hier diese Funktion nur dann anwendbar, wenn die Daten aus KI2Plc vorhanden sind. Der status wird ja in Zeile 130 gelesen und mit den Werten aus der Liste verglichen. Fehlt also diese Liste, gibt es keine gültige Auswertung. Da wir hier im Pico lediglich ein Beispiel erklären, fehlt die Speicherung der Daten im Pico. Das wäre ohne Probleme möglich, müsste aber dann auch wieder gelesen werden. Dieser Aufwand ist nicht lohnenswert, da ohnehin keiner den Pico als Zylindersteuerung verwendet 😀

Im nächsten Bild sei noch einmal der Python-Abschnitt gezeigt, welcher in KI2Plc verwendet wird. Hier ist auch die Grundstellung berücksichtigt (Zeile 300).


Im nächsten Teil werde ich die Anwendung des Zylinders in einer Simatic S7-1200 mit Python und Snap7 zeigen 🙋














Mittwoch, 15. März 2023

  Copyright ©  Dipl.-Ing. Johannes Hofer 2022                                           

 

Ki2Plc

Die Möglichkeiten einer Programmierung im TIA-Portal, um diese am Geschehen der künstlichen Intelligenz zu beteiligen



 

Pico-EVB als mini-plc Teil-2

Nachdem der Loop läuft, benötigen wir einen Client und das erfolgt normalerweise mit dem ersten Kontakt über den Request 4000. In Zeile 241 im Teil-1 ersichtlich, wird die Funktion rem_socket.send(set_neuron_ipl_str(set_neuron_ipl())) aufgerufen, welche nun die Daten zum Client sendet. Das Programm KI2Plc benötigt eigentlich nur die Anzahl der Eingangsparameter und dessen Typ, also digital oder analog. Hier werden die Daten aus der Funktion set_neuron_ipl() zusammengesetzt, welche danach von set_neuron_ipl_str() als String zum Versenden zusammengesetzt wird.  


Hier wird ein Set (Array) mit jeweils einem Tupel bestehend aus den Daten des digitalen Eingang zusammengesetzt. Insgesamt sind das hier die drei digitalen Eingänge. Die Informationen sind jeweils mit einem Schlüssel (Key) und den Daten dazu beschrieben, welche KI2Plc auswertet. Was da so wichtig ist, ist nicht so exakt festgelegt. KI2Plc benötigt mindestens den Typ (Zeile 191) und die Quelle des Gerätes (Zeile 192). Der Rest ist zum Debuggen und zur Datenerhaltung wichtig, aber nicht zur Programmierung der Matrix. Dazu mehr Information, wenn die KI2Plc veröffentlicht wird.



In der Funktion set_neuron_ipl_str() wird diese Information als String zusammengesetzt und an die KI2Plc gesendet.

Der Request für die neue Matrix ist im Teil-1 in Zeile 233 ersichtlich. Dieser wird von der Funktion set_matrix(datas) umgesetzt. Die Daten werden als Dictionary von KI2Plc gesendet und müssen nun als Matrix-Daten aufgelöst werden. 


Wichtig dabei ist, dass dir globale Variable run auf 0 gesetzt wird, damit die Matrix im anderen _thread nicht mehr bearbeitet wird. Ansonsten ensteht eine Liste (Array), welche nur die Werte und nicht mehr den Schlüssel beinhaltet. Danach kann mit run = 1 die Bearbeitung wieder freigegeben werden. Funktioniert so wunderbar 👍

Der Request 4002 soll nun immer den aktuellen Zustand des Eingangs-Layer senden, welcher allerdings derzeit nur für die Anzeige zur Erklärung im Vidio dient. Dazu sind die Funktionen get_status() und get_status_str() zuständig. Wobei hier das return in Zeile 90 den Status aus der Funktion cylinder_simulation() erfolgt.


Diese ist nun für einen künstlichen Ablauf zuständig. Hier wird etappenweise ein Zustand ausgegeben, welcher einen fahrenden Cylinder simuliert. In Micropython gibt es noch keinen match, deswegen die Auflösung mit einem If-Grab 😀


Diese Zustände haben wir im Video gesehen. Und nun fehlt noch der dritte Teil zur Matrix selbst, der in Kürze folgt. 🙋










  Copyright ©  Dipl.-Ing. Johannes Hofer 2022                                           

 

Ki2Plc

Die Möglichkeiten einer Programmierung im TIA-Portal, um diese am Geschehen der künstlichen Intelligenz zu beteiligen



 

Pico-EVB als mini-plc Teil-1

Diesesmal ist das Video auf meinem YouTube-Kanal zuerst fertig geworden 😉
Nun einige Worte zum Python-Programm auf dem Pico-EVB. Im ersten Teil ist die Initialisierung zum Pico-EVB zu sehen und soll somit den Einstieg mit der dort angegbenen Version (OS)  zeigen (Zeile 37 - 50). Ich habe den Pico so auf die Adresse '192.168.1.200' initialisiert ( Zeile 42)



Jeder Pico-Programmierer weiß, daß hier die entsprechenden Angaben des Herstellers studiert werden müssen. Ich hatte damit keine Probleme. Also bitte die Version in Zeile 2 beachten.



Darüber im Listing einige Angaben zur Version und den verwendeten imports, Konstanten und die verwendeten Ports für einen möglichen Zylinder, welcher hier und auch im Video simuliert wird. Nun benötigen wir noch einige globale Variablen, welche wir in den Funktionen benutzen. Hier die Initialisierungen im folgenden Bild und in den Funktionen später mit dem Zusatz global wieder zu erkennen sind.


Interessant, wenn überhaupt, wird sicherlich das nächste Bild, welches das main() beschreibt und zunächst anzeigt, was da so passiert. Übrigens, einfach eine Nachricht senden (Kontakt-Formular) und ich sende das Programm main.py zum Thonny, dann muss das keiner abtippen.


Eigentlich ganz einfach, da nur wenige Zeilen notwendig sind das Programm zu starten. Der _thread startet die Funktion _matrix() (Zeile 289) und benötigt zur Verriegelung den lock, welcher zuvor deklariert wird (Zeile 288). Somit starteten die Funktioneen _matrix() und server_loop() fast gleichzeitig ,  wenn die Zeile 292 bearbeitet wird.

Betrachten wir im nächsten Bild zuerst den server_loop():


Was komliziert aussieht, ist oft sehr einfach. In Zeile 225 wird der Socket mit der Funktion init_socket_pc() initialisiert. Der soll als Mini-Server arbeitet und wird später erklärt. Wenn das erfolgreich war, gehts in Zeile 226 mit einer weiteren while-Anweisung weiter. Nun erwartet der Socket einen Client in Zeile 230, welcher Requests an den Server senden soll. Hier ist es ein PC mit dem Programm KI2Plc, wei im Video gezeigt wird. Sollte das der Fall sein, wird der Request ausgewertet. In Zeile 233 erkennt der Server, dass eine neue Matrix gesendet wurde und ruft set_matrix(datas) auf, damit die neue Matrix gestartet werden kann.

Ansonsten kann der Request 4000 in Zeile 241 erkannt werden oder der Request 4002 in Zeile 244. Der erste sendet die Informationen der Pins für den Input-Layer (Zeile 242) mit rem_socket.send(set_neuron_ipl_str(set_neuron_ipl())) und der zweite den Status vom Input-Layer (Zeile 245) mit rem_socket.send(get_status_str()). Andernfalls wird in Zeile 247 gemeckert, was eigentlich nicht sein darf 😀

Sollte in der normalen Kommunikation was schieflaufen, werden durch die Exceptions die innere Schleife abgebrochen (Zeile 256) und die äussere Schleife neu gestartet (Zeilen 261-264) in der Hoffnung dass nach dem Schliessen des Sockets in Zeile 262 mit my_socket.close() alles wieder in die Reihe kommt.

Nun, wie es weiter geht, folgt im nächsten Beitrag diesmal sehr zügig 🙋




















Sonntag, 5. März 2023

  Copyright ©  Dipl.-Ing. Johannes Hofer 2022                                           

 

Ki2Plc

Die Möglichkeiten einer Programmierung im TIA-Portal, um diese am Geschehen der künstlichen Intelligenz zu beteiligen

 

Neuronen und Synapsen für die KI-PLC

Was wir hier sehen, ist eine völlig andere Betrachtung der KI-PLC. Dieses mal nicht nur für das TIA-Portal, sondern auch für Geräte mit der Option, diese in Python als SPS zu betreiben.




In einem praktischen Modell-Versuch, wie im Bild dargestellt, werden Daten von einer SPS über den Pico-EVB an einen PC gesendet. Selbstverständlich geht das auch im dargestellten Netz direkt zum PC, ohne den Pico.

Der Vorteil die Daten über den Pico zu senden, besteht u. a. darin, dass diese Option auch nach der Inbetriebnahme zur weiteren Datenübertragung bestehen bleiben kann.
 

Was passiert hier?

Der SPS-Programmierer sorgt für die Daten zur Inbetriebnahme eines FB‘s und sendet diese an die KI2Plc. Das ist der sogenannte Input-Layer (IPL), welcher dann in eine Matrix mit künstlichen Neuronen und Synapsen übernommen werden. Eine Inbetriebnahme des FBs erfolgt danach in der KI2PLC-Software mittels Deep-Learning und dessen Training. Diese sendet dann das Ergebnis in Form einer Matrix an die SPS und kann nun dort im FB mittels einer Standard-Prozedur angewendet werden.

Geräte (SPS / IOT) mit integriertem Python-Interpreter erhalten eine Matrix in Python geschrieben, welche speziell aus dem Training als Datei.py abgeleitet wird.


Aufgabenstellung

Die Daten von der SPS oder Pico, werden im Eingangslayer aufgenommen und über Synapsen für das Deep-Learning zur Verfügung gestellt. Hier können die Synapsen mit zusätzlichen Eigenschaften versehen werden. Danach erfolgt die Übergabe in den Eingangslayer. 

Das Training sorgt nun dafür, dass die Hiddenlayer bearbeitet werden und diese dann am Ausgangslayer zur weiteren Bearbeitung zur Verfügung stehen. Diesen Vorgang schauen wir uns im folgen Video (ohne Ton) an:


Ergebnis

Ein Ergebnis aus einem Training, ist ein Ausgangslayer, welcher für die SPS als Daten oder ein Python-File zur weiteren Bearbeitung zur Verfügung steht. Insgesamt wurden bei diesem Durchlauf 920 Aufnahmen gemacht (Bild unten) und in den Layern ausgewertet. Daraus entsteht nun eine Matrix, welche hier den Zylinder interpretiert. Vergleichbar mit den Aufnahmen von Katzen, um diese von z. B. Hunden zu differenzieren.



Das funktioniert wunderbar auch für PLCs, nur mit anderen Gewichtungsmethoden für das Training, wie es üblicherweise für Erkennung von Katzen dokumentiert wird.

Natürlich werden mehrere Layers mit künstlichen Neuronen benötigt, wie hier im Video gezeigt wird. Das Video soll uns also nur einen möglichen Weg darstellen und die Fantasie anregen einmal darüber nachzudenken. 

Wie nun so eine Umsetzung der Matrix in der SPS oder in einem Pico praktisch aussieht, zeige ich bei meinem nächsten Blog-Beitrag 🙋


https://youtu.be/uzpAZC_Ag_4



Mein KI-Berater: