Mittwoch, 11. Januar 2017

Absturz der IOT2000

IOT2000  ohne Shield testen

Bei den ersten Schritten mit der SIMATIC IOT2000 fällt auf, dass beide Sketche sich gleichzeitig im RUN befinden können. Das kann sehr Vorteilhaft sein, wenn die Arbeitsaufteilung stimmt und bedeutet, dass die Programme sich nicht in Konkurrenz befinden dürfen. Also entweder die Pins mit der Arduino- oder der Intel® -Welt programmieren, sonst gibt es einen gemischten Salat ☺.

Absturz beim Test der PLC in Kapitel 9 festgestellt

Die Anwendung der  PLC wird in Kapitel 9 vorgestellt. Hier ein Ausschnitt für das Lesen von analogen Werten.
9.2.5 Analogwerte lesen uns skalieren
Das Programm befindet sich auf der Buch-CD unter PLC_IOT200_Kap_9_2_5.



Hier wurde die Funktion von SCALE aus der FUP-Programmierung verwendet und angepasst. Die Parameter error und BIPOLAR (Bild  9.11), wurden nicht übernommen. Tritt ein Fehler auf, z. B. bei falscher Angabe der Grenzen (HI_LIM, LO_LIM), wird der Analogwert auf 0.0 gesetzt. Die Anwendung negativer Werte findet im Baustein nicht statt und kann vom Leser gegebenenfalls nachgeholt werden. In den meisten Fällen ist der negative Wert aus dem Rohwert ein Thema nach der Skalierung, wenn das bei einem Rohwert von 0-1023 überhaupt sinnvoll ist, da dieser nicht negativ werden kann.
Im Beispiel wurde plc.Scale für vier Bereiche skaliert. Jeder Bereich soll einem Ausgang (A0-A3) zugeordnet werden. In Bild  9.11 sind die vier Bereiche (Punkt 1 bis Punkt 4) durch die Schieber optisch dargestellt (diese haben keine Wirkung auf das Programm) und zeigen wie der aktuelle Wert (AI0) von 692 sich im dritten Bereich befindet und deswegen A2 gesetzt ist.

9.3  Das Absturz-Problem mit C++-Klassen bei der IOT2000
Wenn sie eine Klasse nicht im loop() instanziieren (Bild  9.13), dann darf die Klasse im Konstruktor keine Systemfunktionen aufrufen.

Wird im Konstruktor einer Klasse eine Systemfunktion benutzt, wie z. B. Millis(), dann hängt sich die IOT2000 nach dem Hochladen auf (Stand Jan. 2017), wenn die Instanz der Klasse global erzeugt wird.
In Bild  9.13 ist das Beispiel der Deklaration aus den Übungen zu sehen. PLC_IOT plc(&ioSim) wird vor dem loop() deklariert. Der Konstruktor initialisiert dabei die PLC und muss unter anderem auch die Timer zurücksetzen. In der Timerfunktion wird Millis() verwendet. Das würde zu einem Systemabsturz führen, da es Millis() anscheinend noch gar nicht gibt. Aus diesem Grunde wird die Klasse über den Konstruktor keine Systemfunktionen aufrufen. Diese Absicherung ist im folgenden Bild  9.14 zu sehen.

Hier wird das Attribut inRun auf false gesetzt bevor der Konstruktor wirksam wird und somit verhindert, dass die Methode InitPLC() keine Systemfunktionen anwendet (z. B. beim Timer). InitPLC() wird danach inRun auf true setzen, damit z. B. Millis() für die Timer im Anwenderprogramm verwendet werden kann.
Wenn also die Kommunikation zum Simulator ausfällt (Checksum zählt hoch) dann haben Sie vielleicht in einem Konstruktor eine Systemfunktion benutzt, obwohl diese noch nicht instanziiert war und das IOT2000 kennt die Programmanwendung nicht mehr.
Nun können Sie das Problem lösen, indem Sie grundsätzlich keine globalen Deklarationen vornehmen, sondern erst im loop() deklarieren. Das ist für die Programmierer welche z. B. mit Singleton arbeiten nicht möglich, denn diese sind instanziiert, bevor der loop() beginnt. Je nach Auffassung und Begründung gehen hier die Meinungen auseinander, aber abstürzen darf eine Hardware mit den besonderen Eigenschaften der Industrietauglichkeit, nach meiner Meinung nicht.
Übrigens: Bei einem Test auf dem Arduino-Board UNO mit diesem Problem, konnte kein Absturz festgestellt werden!

Vertrieb in Deutschland zum Buch gesucht!