mcpField
S
scl-syntax

scl-syntax

github.com/deluale開発242 回インストール39 週間前に更新
リポジトリ

scl-syntax について

Siemens TIA Portal V20+ の PLC 開発者向けに、SCL の構文規則、コードパターン、リファレンスをまとめたスキルです。名前付きパラメーター、永続変数の配置、FC と FB の使い分けを重視しています。

主な機能

  1. 01SCL の基本構文規則の説明
  2. 02FC・FB・DB の選択ガイド
  3. 03関数とデータ型のリファレンス
  4. 04アンチパターンと検証項目
  5. 05標準ブロックのテンプレート

活用シーン

  1. 01Siemens PLC の SCL プログラム作成
  2. 02状態を持つロジック向けの FB 選択
  3. 03タイマー配置とパラメーター構文の確認
  4. 04標準関数の使い方や例の検索

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/deluale/framework_parser --skill scl-syntax

インストール後、Claude Code で/scl-syntaxを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

anti-patterns.md
core-functions.md
data-types.md
REFACTORING_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

自動検索のプロセス:

  1. Claude が index.json を読み、関数のカテゴリーを特定します
  2. 該当するカテゴリーの JSON ファイルを読みます
  3. パラメーターと例を含む完全な定義を抽出します
  4. 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/ 内)

コメント