scl-syntax について
Siemens TIA Portal V20+ の PLC 開発者向けに、SCL の構文規則、コードパターン、リファレンスをまとめたスキルです。名前付きパラメーター、永続変数の配置、FC と FB の使い分けを重視しています。
主な機能
- 01SCL の基本構文規則の説明
- 02FC・FB・DB の選択ガイド
- 03関数とデータ型のリファレンス
- 04アンチパターンと検証項目
- 05標準ブロックのテンプレート
活用シーン
- 01Siemens PLC の SCL プログラム作成
- 02状態を持つロジック向けの FB 選択
- 03タイマー配置とパラメーター構文の確認
- 04標準関数の使い方や例の検索
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ deluale/ framework_parser --skill scl-syntaxインストール後、Claude Code で/scl-syntaxを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
anti-patterns.mdcore-functions.mddata-types.mdREFACTORING_SUMMARY.md詳細
SCL 構文スキル
Siemens TIA Portal V20+ の PLC プログラミングにおける SCL 構文の支援。
🚨 厳守必須の重要ルール
R1: 名前付きパラメーターを必ず使用
IT: Tutti i parametri di funzioni native DEVONO usare sintassi nominata con := per input e => per output.
EN: All native function parameters MUST use named parameter syntax with := for inputs and => for outputs.
// ✅ CORRETTO / CORRECT
result := LIMIT(MN := 0, IN := value, MX := 100);
#Motor1(Start := signal, Running => output);
// ❌ SBAGLIATO / WRONG - ERRORE COMPILAZIONE!
result := LIMIT(0, value, 100);
#Motor1(signal, output);
R2: タイマー/カウンター/トリガーには永続ストレージを使用
IT: Timer, Counter, Trigger DEVONO essere dichiarati in VAR (FB) o VAR_STAT, MAI in VAR_TEMP. VAR_TEMP si resetta ogni ciclo PLC!
EN: Timer, Counter, Trigger MUST be declared in VAR (FB) or VAR_STAT, NEVER in VAR_TEMP. VAR_TEMP resets every PLC cycle!
// ❌ SBAGLIATO / WRONG
VAR_TEMP
myTimer : TON; // ERRORE: timer si resetta ogni ciclo!
END_VAR
// ✅ CORRETTO / CORRECT
VAR
myTimer : TON; // OK: memoria persistente tra cicli
END_VAR
R3: ELSEIF ではなく ELSIF を使用
IT: In SCL si usa ELSIF, non ELSEIF come in altri linguaggi.
EN: In SCL use ELSIF, not ELSEIF.
// ✅ CORRETTO / CORRECT
IF temp < 0 THEN
state := 'FROZEN';
ELSIF temp < 100 THEN // ELSIF!
state := 'LIQUID';
ELSE
state := 'GAS';
END_IF;
R4: 代入には :=、出力には => を使用
IT: Usa := per input, => per output quando chiami Function Block.
EN: Use := for inputs, => for outputs when calling Function Block.
// ✅ CORRETTO / CORRECT
#Motor1(
Start := startButton, // IN: usa :=
Speed := speedValue, // IN: usa :=
Running => motorStatus, // OUT: usa =>
Error => errorFlag // OUT: usa =>
);
R5: FC と FB/Function と Function Block
IT:
- FC (Function): 状態を持たないロジック用(計算、変換)
- FB (Function Block): 永続メモリを持つ状態付きロジック用(モーター、バルブ、シーケンス)
EN:
- FC (Function): For stateless logic (calculations, transformations)
- FB (Function Block): For stateful logic with persistent memory (motors, valves, sequences)
FC と FB の判断ツリー
Hai bisogno di memoria persistente? / Need persistent memory?
├─ NO → Usa FC / Use FC
│ └─ Esempi: calcoli, conversioni, media, controlli
│ Examples: calculations, conversions, averaging, validations
│
└─ SI → Usa FB / Use FB
└─ Esempi: motori, timer, sequenze, state machine
Examples: motors, timers, sequences, state machines
3 ステップのワークフロー
STEP 1: ブロックの種類を特定
- 状態を持たない周期ロジック → FC (Function)
- メモリを使用する制御(モーター、バルブ、シーケンス) → FB (Function Block)
- グローバルデータ → DB (Data Block) または PLC Tags
STEP 2: ネイティブ関数を確認
- Core Functions: 一般的な関数(LIMIT、MIN、MAX、TON、CONCAT など)については、
scl-reference/core-functions.mdを参照 - Extended Functions: 追加の 192 個の関数については、Claude が
scl-reference/functions/内の JSON データベースを自動的に読み込みます - Usage Examples: 実用例については、
scl-reference/USAGE_EXAMPLE.mdを参照
STEP 3: チェックリストで検証
- 名前付きパラメーター ✓
- タイマーは VAR 内(VAR_TEMP ではない) ✓
- ELSIF(ELSEIF ではない) ✓
- 避けるべきよくあるエラーについては、
scl-reference/anti-patterns.mdを参照
📋 標準ブロックテンプレート
FC テンプレート (Function)
FUNCTION "Calculate_Average" : REAL
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
values : Array[0..9] of Real; // Array di valori
count : Int; // Numero elementi
END_VAR
VAR_TEMP
sum : Real; // Somma temporanea
i : Int; // Indice loop
END_VAR
BEGIN
// Validazione input / Input validation
IF count <= 0 OR count > 10 THEN
#Calculate_Average := 0.0;
RETURN;
END_IF;
// Calcolo media / Calculate average
sum := 0.0;
FOR i := 0 TO count - 1 DO
sum := sum + values[i];
END_FOR;
// Ritorna risultato / Return result
#Calculate_Average := sum / TO_REAL(count);
END_FUNCTION
FB テンプレート (Function Block - State Machine)
FUNCTION_BLOCK "Motor_Control"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
Start : Bool; // Segnale avvio
Stop : Bool; // Segnale stop
SpeedSetpoint : Real; // Velocità richiesta
END_VAR
VAR_OUTPUT
Running : Bool; // Motore in marcia
ActualSpeed : Real; // Velocità attuale
Alarm : Bool; // Flag allarme
END_VAR
VAR
State : Int; // 0=Idle, 1=Starting, 2=Running
StartTimer : TON; // Timer avvio (DEVE essere in VAR!)
ErrorCount : Int;
END_VAR
VAR_TEMP
tempSpeed : Real; // Variabile di lavoro temporanea
END_VAR
BEGIN
// State machine
CASE State OF
0: // Idle
IF Start AND NOT Stop THEN
State := 1;
#StartTimer(IN := FALSE, PT := T#0ms); // Reset timer
END_IF;
Running := FALSE;
1: // Starting
#StartTimer(IN := TRUE, PT := T#2s);
IF #StartTimer.Q THEN
State := 2;
Running := TRUE;
END_IF;
IF Stop THEN
State := 0;
END_IF;
2: // Running
Running := TRUE;
// Limita velocità tra 0 e 3000 RPM
ActualSpeed := LIMIT(
MN := 0.0,
IN := SpeedSetpoint,
MX := 3000.0
);
IF Stop THEN
State := 0;
Running := FALSE;
END_IF;
END_CASE;
// Gestione allarmi / Alarm handling
IF ActualSpeed > 3000.0 * 1.1 THEN
Alarm := TRUE;
ErrorCount := ErrorCount + 1;
END_IF;
END_FUNCTION_BLOCK
🔄 制御構造
IF-ELSIF-ELSE 条件文
// Condizionale semplice / Simple conditional
IF temperature > 100.0 THEN
alarm := TRUE;
shutdownHeater();
END_IF;
// Condizionale completo / Full conditional
IF pressure < 1.0 THEN
status := 'LOW';
ELSIF pressure > 10.0 THEN
status := 'HIGH';
ELSE
status := 'NORMAL';
END_IF;
// Condizioni combinate / Combined conditions
IF (temp > 80.0) AND (pressure > 5.0) OR emergencyStop THEN
shutdown := TRUE;
END_IF;
CASE 文(ステートマシン用)
// Ottimo per state machine e selezione multi-valore
CASE state OF
0: // Idle
Running := FALSE;
IF StartCommand THEN
state := 1;
END_IF;
1: // Starting
Running := TRUE;
IF startupComplete THEN
state := 2;
END_IF;
2: // Running
processControl();
IF StopCommand THEN
state := 3;
END_IF;
3: // Stopping
IF shutdownComplete THEN
state := 0;
END_IF;
ELSE
// Stato invalido - vai in error
state := 99;
errorFlag := TRUE;
END_CASE;
FOR ループ
// Loop con contatore crescente / Ascending counter loop
FOR i := 0 TO 9 DO
temperatures[i] := readSensor(i);
END_FOR;
// Loop con contatore decrescente / Descending counter loop
FOR i := 10 DOWNTO 0 DO
buffer[i] := 0;
END_FOR;
// Loop con incremento custom / Custom increment
FOR i := 0 TO 100 BY 5 DO
// i = 0, 5, 10, 15, ..., 100
processValue(i);
END_FOR;
// EXIT per uscita anticipata / Early exit
FOR i := 0 TO 99 DO
IF data[i] = targetValue THEN
foundIndex := i;
EXIT; // Esce dal loop
END_IF;
END_FOR;
// CONTINUE per saltare iterazione / Skip iteration
FOR i := 0 TO 99 DO
IF data[i] < 0 THEN
CONTINUE; // Salta al prossimo i
END_IF;
processPositiveValue(data[i]);
END_FOR;
WHILE ループ
// Pre-test (condizione prima esecuzione)
WHILE counter < 100 DO
counter := counter + 1;
process(counter);
END_WHILE;
// Con EXIT
WHILE TRUE DO
data := readData();
IF data = STOP_MARKER THEN
EXIT;
END_IF;
processData(data);
END_WHILE;
REPEAT ループ
// Post-test (esegue almeno una volta)
REPEAT
counter := counter + 1;
value := readSensor();
UNTIL (value > threshold) OR (counter >= maxRetries)
END_REPEAT;
// ⚠️ ATTENZIONE / WARNING: REPEAT termina quando condizione è TRUE
// (opposto di WHILE che continua quando TRUE)
📚 参照ファイル
ファイルを参照するタイミング
一般的な組み込み関数(LIMIT、MIN、MAX、TON、CONCAT など)について:
→ scl-reference/core-functions.md を参照してください
- 実践的な例を含む、最もよく使われる30個の関数を掲載
- 完全なシグネチャ、パラメーター、使用例
よくある回避すべきエラーについて:
→ scl-reference/anti-patterns.md を参照してください
- 解決策を含む、15件以上のアンチパターンを掲載
- パフォーマンスと正確性に関するエラー
- 正しい例と誤った例の比較
データ型(Int、Real、String、Array、Struct など)について:
→ scl-reference/data-types.md を参照してください
- 基本型と複合型に関する完全なリファレンス
- 型変換
- メモリ割り当てのベストプラクティス
Core 30以外の関数について:
→ Claude が scl-reference/functions/ 内の JSON データベースを自動的に参照します
- カテゴリー別に整理された、追加の192個の関数
- Math、Comparison、Conversion、String、Move、Bitwise、Timers、Counters、Triggers
index.jsonによる自動検索
実践的な使用例について:
→ scl-reference/USAGE_EXAMPLE.md を参照してください
- FC と FB の完全な例
- 正しく実装された一般的なパターン
関数データベース
データベースの構造:
scl-reference/functions/
├── index.json # Indice completo 222 funzioni
├── math.json # Funzioni matematiche avanzate
├── comparison.json # Comparazioni e selezioni
├── conversion.json # Conversioni di tipo
├── string.json # Manipolazione stringhe
├── move.json # Trasferimento dati
├── bitwise.json # Operazioni bitwise
├── timers.json # Timer avanzati
├── counters.json # Contatori
└── triggers.json # Trigger eventi
自動検索のプロセス:
- Claude が
index.jsonを読み、関数のカテゴリーを特定します - 該当するカテゴリーの JSON ファイルを読みます
- パラメーターと例を含む完全な定義を抽出します
- Core Functions のスタイルに沿って回答を整形します
✅ コミット前のセルフチェック/検証チェックリスト
SCL コードを仕上げる前に、以下のすべての項目を確認してください。
- 名前付きパラメーター:すべての組み込み関数のパラメーターで、
:=(IN)と=>(OUT)を使用している - タイマーの格納先:Timer/Counter/Trigger は
VAR(FB)またはVAR_STATに配置し、VAR_TEMPには絶対に配置しない - ELSIF 構文:条件分岐で
ELSEIFではなくELSIFを使用している - 組み込み関数:core-functions.md を参照し、LIMIT、MIN、MAX などを再実装していない
- エッジ検出:手動でのエッジ検出ではなく、R_TRIG/F_TRIG を使用している
- 配列操作:コピー/値の設定に FOR ループではなく、MOVE_BLK/FILL_BLK を使用している
- 文字列操作:
+演算子ではなく、CONCAT を使用している - 入力検証:入力範囲と有効な値をチェックしている
- エラー処理:適切にアラーム/エラーを処理している
- 命名:変数に説明的な名前を付けている(最終的な名前に
i、x、tempを使用していない) - コメント:複雑なロジックや自明でないロジックにコメントを付けている
- ブロックの種類:状態を持たないロジックには FC、状態を持つロジックには FB を使用している
- アンチパターン:よくあるエラーを避けるために anti-patterns.md を確認している
📝 クイックリファレンス
SCL キーワード:
FUNCTION/FUNCTION_BLOCK- ブロックを定義VAR/VAR_INPUT/VAR_OUTPUT/VAR_TEMP- 宣言セクションBEGIN/END_FUNCTION/END_FUNCTION_BLOCK- 区切りIF/ELSIF/ELSE/END_IF- 条件分岐CASE/OF/END_CASE- switch 文FOR/TO/DOWNTO/BY/END_FOR- 列挙型ループWHILE/END_WHILE- 前判定ループREPEAT/UNTIL/END_REPEAT- 後判定ループEXIT/CONTINUE- ループ制御RETURN- 関数の終了
演算子:
:=- 代入/入力の割り当て=>- 出力パラメーター=- 比較<>- 等しくないAND/OR/NOT- 論理演算子&/|/XOR- ビット演算子
スキルのバージョン:2.0
対象:TIA Portal V20+ / S7-1500 / S7-1200
規格:IEC 61131-3 SCL
言語:イタリア語と英語のバイリンガル
アーキテクチャ:段階的開示(コアは SKILL.md、詳細は references/ 内)