ST(Structured Text)とは?
コントロールのプロセスがますます複雑になり、いまオートメーションシステムもより複雑なデータ処理機能・計算が必要になります。
ST(Structured Text)はそのためにデザインされた言語です。IEC61131-3によって設計され、PASCAL-baseの高級言語、プログラマーを簡易でタスクを完成させるのは目標です。Siemnesだけではなく、三菱・Omron・CodeSys様々なメーカーもあり、命令だけが違うの場合が多いです。
Siemens With TIA

GXWorks2

Simotion

Siemens社のSIMOTION STはさらにTechnologyコマンド作られ、SIMOTIONデバイス・モーションコントロールとTechnologyを簡単に制御することができます。(例えば位置決め・CAMなど…)
今回の入門編はSIMOTIONのSTのをBaseとして書いたものです。どうぞよろしくお願いします。
前書き

まずSiemnesの気が失うほど1000ページくらいの英語ST言語取り扱い書があります。
このなかにいつも出てるの” Syntax diagram”があります。Siemensの取り扱い書がこのようなGraphでものことを説明するのが好きらしいけど、ちょっとわかりにくいですが。
ここでまず慣れておきましょう。
- Rule name:つまり該当する文法の名前
- Option:あってもなくても大丈夫な宣言
- Iteration:Looping・繰り返しですね。
- Alternative:ORと同じだと思えば大丈夫です。
ST Source の構成

ST Sourceは純文字でそして何か所の”Logicalセレクション”に分かれることができます。
ST Sourceにはメインのセレクションが以下になります:
- Unit Statement(Optional)
- STの名前
- Interface section
- 変数・構造体・プログラム(POU)の宣言
- 他のST SourceからのImport
- Implementation section
- プログラムなどの本体にいる場所
- 他のST SourceからのImport
- POU (program organization unit)
- 単体実行のプログラムソース(Program,Function,Function Block)
- Declaration section
- 数・構造体などの定義(Interface section、Implementation sectionも可能)
- Statement section
- POUの中の実際プログラム
基本文法
PASCAL-baseなので、書き方はそんなに難しくありません。
大事なのは”;”とか忘れなければ~笑。自分がいつも忘れます…あとSIMOTIONのEDITOR非常に…弱いです。
変数、関数のAuto-Fillがありません。
変数名

このGraphだけみても、うん?のイメージしかきませんね。
私はまずこのGraphを2つ大きな枠に分けますね。
Identifierは、うん~つまり変数の名前の決まりルールですね。
- 枠1は変数の頭文字の宣言ルール。
- 枠2は変数の頭文字以外のルール
- 変数宣言します
- Letterだけか
- ”_”にするか?
- ”_”にしたら、そのあとはLetterか、数字か
- “_”にするか?、Optionだからしなくて大丈夫。
- もし”_”にしたら、次はLetterか、Digitをつける。
- まだ文字つけるか?
- 変数宣言終わり。
って感じです。
例として:
枠1:A、A_、A、_9
枠2の5:A、_A、_9
枠2の6:A_1,_9A
枠2の7:まだ、Letter、Digitつけるなら5にも戻る。
枠2の8:宣言終わり
A、A1、_A、_9、AB,ABC,_9A,_9_A…のような変数名は有効になります。
*もちろん予約語は使ってはいけません。
変数定義

基本タイプはすこく簡単で、 変数の宣言のあとにデータタイプを定義するだけです。
MyReal:REAL;
MyBOOL:BOOL;
MyInt:INT:=100;
UDT(User defined Type)
構造体は以下の3つのところで定義できます。
- Interface section
- Implementation section
- Program organization unit (POU)

INTERFACE
TYPE
bRun :BOOL;
bCmdSet :ARRAY[0..100]OF BOOL;
sDrive :STRUCT
ActSpeed :REAL;
SetSpeed :REAL;
ActPos :REAL;
SetPos :REAL;
END_STRUCT
END_TYPE
PROGRAM pou1;
END_INTERFACE
IMPLEMENTATION
VAR_GLOBAL
Drive1Run :bRun;
Drive1 :sDrive;
END_VAR
PROGRAM pou1
Drive1.SetSpeed :=100.0;
Drive1.SetPos :=50.0;
END_PROGRAM
END_IMPLEMENTATION
配列

MyVar1:ARRAY[0..10]OF INT;
MyRealArray:ARRAY[0..999]OF REAL;
CONSTANT宣言
VAR CONSTANT

VAR CONSTANT
PI :REAL:=3.1415;
BuzzerONTime :TIME:=TIME#1h1m1s;
Message :STRING[40]:='Something Wrong..';
TwoPI :REAL:=PI*2;
END_VAR
VAR GLOBAL CONSTANT

VAR_GLOBAL CONSTANT
RefSpeed :REAL:=1500.0;
RefCurrent :REAL:=14.5;
END_VAR
Statements
ここで3種類の基本機能を説明します。
値を与える(Value assignment)

//Real
r32Temp:=0.0;
r32Temp:=3.3;
//String
str40 :='Hello World!';
str40_1 :=str40;
byteValue:=str40[5];
str40[20]:=byteValue;
MyArray1:=MyArray2;
MyArray1[i]:=10;
MyArray[5]:=23;
struct1.element1:=TRUE;
struct1.element2:=3.92;
コントロール(Control Statement)
IF
もし~ならこれをする、そうじゃなければこうする。

IF r32Temp > 0.0 THEN
str40:='r32Temp is >0';
ELSIF r32temp = 0.0 THEN
str40:='r32Temp is 0';
ELSE
str40:='r32Temp is <0';
END_IF;
Case
IF文は複雑の条件を組み合わせて条件分け事できますが、もし1つの変数に対してこの値からこの処理、
あの値から別の処理のであればCASEを使ってたほうがわかりやすいと思います。

Valus List

CASE i16Value OF
1:
speedSetPoint:=300.0;
2:
speedSetPoint:=600.0;
3..10:
speedSetPoint:=1500;
ELSE
speedSetPoint:=0.0;
;
END_CASE;
FOR Loop

FOR i16Value:=0 TO 10 DO
//
boolList[i16Value]:=FALSE;
END_FOR ;
FOR i16Value:=0 TO 2 DO
//
boolList[i16Value]:=FALSE;
END_FOR ;
FOR i16Value:=10 TO -2 DO
//
boolList[i16Value]:=FALSE;
END_FOR ;
WHILE Loop
条件立つまでずっとLOOPINGします。
注意するのはLOOPING始まる前に条件をチェックする。

WHILE i16Value <=10 DO
boolList[i16Value]:=TRUE;
i16Value:=i16Value+1;
END_WHILE;
REPEAT
WHILE LOOPと似てて同じく条件立つまでずっとLOOPINGします。
こっちはWHILE LOOPと違ってLOOPING一回終わってから条件をチェックする。
つまり最低限一回は実行します。

i16Value:=0;
REPEAT
boolList[i16Value]:=FALSE;
UNTIL i16Value=10
END_REPEAT;
FOR i16Value:=10 TO -2 DO
//
boolList[i16Value]:=FALSE;
IF bStopSw THEN
EXIT;
END_IF;
END_FOR ;
EXIT
LOOPINGが途中に終わりたいとき使います。
FOR i16Value:=10 TO -2 DO
//
boolList[i16Value]:=FALSE;
IF bStopSw THEN
EXIT;
END_IF;
END_FOR ;
CONTINUE
LOOPINGの中にある条件立つとプログラム実行したくない、でもLOOPINGまだ続きたいのとき使います。
//if bStopSw is FALSE,i16sum=15
//if bStopSw is TRUE,i16sum=9
i16sum:=0;
FOR i:=0 TO 2 DO
FOR j:=0 TO 1 DO
i16sum:=i16sum+1;
IF bStopSw THEN
CONTINUE;
i16sum:=i16sum+1;
END_IF;
END_FOR;
i16sum:=i16sum+1;
END_FOR;
RETURN
RETURNを使うことによって、LOOPINGから離れるだけではなく、このプログラムまで終了させます。
なので下の例だとRETURNの条件が成立するとi16sum:=1999;がもう実行しないままプログラムを終了する。
SiemensのSTL”BEU”と同じな考え方でいいだと思います。
FOR i16Value:=0 TO 10 DO
//
boolList[i16Value]:=FALSE;
IF bStopSw THEN
RETURN;
END_IF;
END_FOR ;
//This statement will not be execute if bStopSw is TRUE
i16sum:=1999;
WAITFORCONDITION
Motion Taskの中ににイベント待ちのとき使われています。条件がTRUEになるまでプログラム実行は猶予します。
注意するのはWITHのあとにあるExpressionは以下の2つ状態しかみないです:
- FALSEー>TRUE、いわゆる立ち上げ。つまり条件成立。
- FALSE、条件不成立。

Expression

IMPLEMENTATION
EXPRESSION TriggerSensor
TriggerSensor:=%I10.0;
END_EXPRESSION
PROGRAM pou1
WAITFORCONDITION TriggerSensor WITH TRUE DO
%Q10.0:=TRUE;
;
END_WAITFORCONDITION;
;
END_PROGRAM
END_IMPLEMENTATION
GOTO
一応、使えます。POUの中に好きな場所に飛べます。
ManualにもGOTOは特殊な場合だけ使ってください、と。(例えばTroubleshooting、構造プログラムには使うべきではない、と。)

Comments
Line CommentとBlock Commentがあります。
- Line Comment
- //
- Block Comment
- (**)
//This is a line comment
a:=0;
(*
This is a Block comment
TEXTTEXTTEXTTEXTTEXT
*)
b:=0
実例
先の文章にはInterfaceとか、PROGRAMとか色々なわけわからない単語出てきますが、ここで一旦それらを無視しましょう。
それらの意味は次の入門2に説明したいと思います。
TIA SIMOTION

まずTIAでD445を一つ追加します。

Project>>Oepn SIMOTION Configurationします。

PLC_1 >>PROGRAMS >>Insert ST source fileをクリックします。

ST source の名前を入力しOKをクリックします。

このような画面が出てきます。
TIAとかGXWORKSとかは少し違いますので、ここで特に書きません。
では仮に、Program1つ、Function1つを書きましょう。
ProgramはMyPBとMyVariableという2つの変数があり、もしMyPBがONになったら、MyVariableに10を書き込みます。MyPBがOFFのであれば、MyVariableに0を書き込みます。簡単明瞭。
Functionは整数のパラメターがあり、Function内ではこの整数を実数に変換しそのあと二乗し*3.14として返しします。

まずINTERFACEのところに、そのProgramとFunctionのを定義します。
ここでfcCalとmyPou1として定義します。

次はIMPLEMENTATIONのところにプログラム書きます。
これはfcCalの中身です。

これはmyPou1です。
みんなはまだPROGRAM?FUNCTION?とか色々な疑問が出てくるかもしれませんが、次からそれらの考え方を書きたいと思います。では、お疲れ様ですー!