連枝とMCPサーバーの連携

 いいですね!「連枝(れんり)」で描いたラダーをPIC/H8向けにコンパイル→HEX生成→ライタで書き込み…までを、MCPサーバとつないで“AIに指示→実機が動く”流れにできます。まずは全体像、その後に最小構成の実装例を載せます。


全体アーキテクチャ(最小構成)


ChatGPT(AI) ──> MCPサーバ(renri-mcp)

                      ├─ Ladder生成(AIテキスト→Ladder DSL)

                      ├─ 連枝のビルド呼び出し(HEX出力)

                      ├─ シミュレーション実行(任意)

                      └─ ライタCLIで書込み(PICkit 等)

PC上の「連枝」S版/製品版 + PIC/H8書込み環境(PICkit, 秋月ROMライタ等)


連枝はラダー図からPIC/H8等の機械語/HEXを生成でき、画面上のシミュレータも備えています。HEXは標準フォーマットなので多くのロムライタで使えます。


目的が「マイコンをシーケンサ同等に動かす」ことなら、ラダー→HEX→書込みの自動化をMCPでラップするのが一番シンプルです。類似発想としてLDmicroなども存在しますが、ここではユーザーご指定の連枝を中核にします。


**MCP(Model Context Protocol)**はAIとツールを標準化されたサーバ経由で連携する仕組み。サーバ側で「コンパイル」「フラッシュ」「シミュレート」等のコマンドを公開すれば、AIから一発で実行できます。




---


実装ステップ


1. PC側のツール列




連枝(S版でも可/製品版推奨)


連枝の回路コンパイルをコマンド化(後述の自動化ラッパーで操作)


書込み:PICなら**PICkit(pk2cmd/pk3cmd)**や他社ROMライタのCLI


(任意)連枝の動作シミュレータをバッチ/ログ出力で確認

※ 連枝はHEX出力とシミュレーション機能を備えます。



2. MCPサーバ(renri-mcp)




公開コマンド例


generate_ladder(requirements):仕様テキスト→ラダーDSL生成


compile_ladder(ladder_src, target):連枝でHEX生成


simulate(ladder_src):連枝シミュレータの結果(通電パス等)を返す


flash_hex(hex_path, programmer, device):PIC/H8へ書込み


read_status():接続/電圧/ID確認(書込みツールの出力を整形)




3. AIプロンプトの型




機器I/O割付(X/Y番地↔︎ピン)、スキャン周期、非常停止、立下り/立上りエッジ、タイマ/カウンタ時定数、非常時のフェイルセーフ等を明示


例:「X0非常停止は自己保持全解除、Y0メイン接触器、X1起動、T0=500ms、立上り自己保持…」




---


連枝の非GUI自動化の考え方


連枝自体は古典的なWindowsアプリですが、(A) キーボード/マクロ操作での自動化、(B) 連枝のプロジェクト/中間形式を直接出力して「回路コンパイル」を呼ぶ、(C) 変換ライブラリ(製品付属/別売)を呼ぶ、の3経路が現実的です。

最低限はファイル監視+自動ビルドでOK:ladder.renri(仮)を書き出す→自動で連枝コンパイル→out.hexを得る→次タスクで書込み。連枝はHEX生成を標準で行える旨が明示されています。



---


サンプル:Node.js製 MCP サーバ(最小)


> 連枝のビルドはここでは擬似コマンドrenri-cli --compile in.renri --cpu PIC16F84A -o out.hexでラップする想定です(実機ではAutoHotkey等でGUI操作をCLI化、または変換ライブラリを叩く)。書込みはpk3cmd等の実CLIに置換。




// src/server.ts

import { Server } from "@modelcontextprotocol/sdk"; // 代表的なMCP SDK

import { execFile } from "child_process";

import fs from "fs/promises";

import path from "path";


const srv = new Server({ name: "renri-mcp", version: "0.1.0" });


// 1) 仕様→ラダー(超簡易:AIにそのまま返す/将来はテンプレ展開・検証を追加)

srv.command("generate_ladder", async ({ requirements }: { requirements: string }) => {

  // TODO: requirementsをチェックして連枝のラダーDSLへ変換

  const ladderSrc = `; RUNG 1: ${requirements}\n; (ここに連枝のテキスト形式を生成)\n`;

  return { ladderSrc };

});


// 2) 連枝でコンパイル

srv.command("compile_ladder", async ({ ladderSrc, target }:

  { ladderSrc: string, target: "PIC16F84A" | "PIC16F877A" | "H8/3694" }) => {


  const work = await fs.mkdtemp(path.join(process.cwd(), "build-"));

  const inFile = path.join(work, "in.renri");

  const hexFile = path.join(work, "out.hex");

  await fs.writeFile(inFile, ladderSrc, "utf8");


  // ★ 実環境では、renri-cli相当の自動化ラッパーを用意

  const cmd = "renri-cli"; // AutoHotkey等でGUIを自動操作してコンパイルする自作CLI

  const args = ["--compile", inFile, "--cpu", target, "-o", hexFile];


  await new Promise<void>((resolve, reject) => {

    execFile(cmd, args, { timeout: 120000 }, (err, stdout, stderr) => {

      if (err) return reject(new Error(stderr || err.message));

      resolve();

    });

  });


  const ok = await fs.stat(hexFile).then(() => true).catch(() => false);

  if (!ok) throw new Error("HEX生成に失敗しました");

  return { hexPath: hexFile };

});


// 3) シミュレーション(任意)

srv.command("simulate", async ({ ladderSrc }: { ladderSrc: string }) => {

  // 連枝シミュレータの結果ログをCLI化して返す想定

  return { result: "pass", energizedPaths: ["RUNG1", "RUNG2/T0"] };

});


// 4) 書込み(PICkit3の例:pk3cmdに置換)

srv.command("flash_hex", async ({ hexPath, device, port }:

  { hexPath: string, device: string, port?: string }) => {

  const cmd = "pk3cmd";

  const args = ["-M", "-P", device, "-F", hexPath];

  if (port) args.push("-B", port);

  await new Promise<void>((resolve, reject) =>

    execFile(cmd, args, { timeout: 60000 }, (err, stdout, stderr) =>

      err ? reject(new Error(stderr || err.message)) : resolve()

    )

  );

  return { status: "flashed", device };

});


srv.listen();


> MCPの基本や導入の全体像は以下がわかりやすいです。





---


連枝用のラダーDSL(下地の例)


連枝は画面でラダー図作成→コンパイルが基本ですが、運用自動化のためにテキスト中間表現を1つ決めて、MCPで出力→自作ラッパーが連枝プロジェクトへ反映、という流れにすると安定します。

テキスト例(擬似):


TITLE: Pump Interlock

CPU: PIC16F84A

SCAN_MS: 5

I: X0 EM_STOP, X1 START

O: Y0 MAIN_CONT, Y1 PUMP

T: T0 500ms

RUNG:

  ( /X0 ) & ( X1 | ( Y0 & /T0 ) ) -> Y0

  Y0 & /X0 -> Y1


※ 実際の連枝内部形式は非公開のため、自前DSL→GUI自動操作 or 変換ライブラリ呼出で橋渡しする設計にしています(連枝にHEX出力・シミュレータがあること自体は公式記載)。



---


運用Tips(重要)


I/O割付表を真っ先に機械可読(YAML/CSV)で持つ(例:X0=非常停止、X1=起動、Y0=主接、Y1=ポンプ…)。AI→DSL生成の精度が上がります。


シミュレーション前提:非常停止や自己保持解除など安全ロジックは必ずシミュレータで通電パス確認→HEX生成→書込み。


書込みツールは機種別CLIを用意(PICkit、秋月ROMライタ等)。連枝は標準HEXを吐くので選択肢が広いです。


連枝は古めのアプリのため、AutoHotkey等でのGUI自動化 or 変換ライブラリ併用が実務的。ヘッドレス運用を目指すなら、将来はLDmicro等のオープン系で同様のMCPラップを用意する手もあります。




---


すぐ試せる「最小フロー」


1. PCに連枝S版を入れる(S版解説や使い方ガイドがネットに多い)。



2. AutoHotkeyで「回路コンパイル→HEX出力」ボタンを押すスクリプトを用意してrenri-cliとしてラップ。



3. 上のMCPサーバを起動。



4. ChatGPT側から:


generate_ladder(requirements="非常停止X0で全停止、X1起動、Y0自己保持、T0=500ms後にY1起動")


compile_ladder(ladderSrc, target="PIC16F84A")


simulate(ladderSrc)(OKなら)


flash_hex(hexPath, device="PIC16F84A")






---


必要なら、AutoHotkeyのサンプル(連枝のウィンドウ識別→ファイル読込→回路コンパイル→ログ収集→HEXパス取得)や、PICkit系の具体的CLI、I/O割付テンプレ(CSV/YAML)まで一式お作りします。

まずは、狙うターゲットMCU(PIC/H8の型番)とI/O割付、最初に動かしたい制御仕様を教えてください。その前提で、MCPコマンド群とDSLのテンプレを“あなたの現場仕様”に合わせて初期セットを組みます。



コメント

このブログの人気の投稿

ミライアイ内服薬は薬事法違反で、ほとんど効果がない詐欺ですか?

最高裁での上告理由書受理・却下の判断基準について

裁判官の忌避申立書の作成例