1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

仕様変更に強すぎる。現場で神扱いされた「万能マトリクスI/F」の全構造

1
Last updated at Posted at 2026-03-21

ラダーを書き換えずに論理を変えるための設計思想

序章:仕様書が曖昧だったので、現場で困る未来が見えた話

製造ラインの案件では、仕様書が曖昧なままスタートすることが珍しくない。
今回の案件もまさにそれで、
「このまま納品したら現地で確実に困る」
そんな未来がはっきり見えていた。
現場で仕様変更が入るのは当たり前。
しかも“止める・止めない”の判断は、下流の状況や機械の状態によってコロコロ変わる。
ラダーを都度書き換えていたら、現場は止まるし、工期も飛ぶ。
だから私は、
設定だけで論理を変えられる仕組み
を即興で作ることにした。
必要は発明の母──
いや、今回は“必要が発明を強制してきた”と言った方が正しい。
こうして生まれたのが、
選択 × 反転 × 遅延 を 16bit のマトリクスで抽象化した
万能マトリクスI/F」 である。
この仕組みのおかげで、
現場での仕様変更にも一切ラダーを書き換えずに対応でき、
工務さんからは「これどうやってんの…?」と神扱いされた。
この記事では、
この“万能マトリクスI/F”の思想から構造、
そして実際に現場で役に立った応用例まで、
全構造を余すことなく公開する。

第1章:思想──なぜマトリクス化するのか

製造ラインの制御は、仕様書どおりに動けばいい──
そんな単純な世界ではない。
実際の現場では、仕様変更・追加要求・運用上の都合が、
納品後に必ずと言っていいほど発生する。
しかもその変更は、
「この条件を反転してほしい」
「この信号も停止条件に入れて」
「この出力だけ遅らせて止めたい」
といった、論理の“微妙な調整” がほとんどだ。
こうした変更に毎回ラダーを書き換えていたら、
現場は止まるし、工期も飛ぶ。
だから私は、次の思想にたどり着いた。

思想①:ラダーを書き換えずに“設定だけで論理を変える”

PLCのラダーは本来、
固定された論理を実装するためのもの」 だ。
しかし現場で求められるのは、
変わり続ける論理に柔軟に対応できる仕組み」 である。
そこで私は、
入力条件の組み合わせ・反転・遅延といった
“論理の可変部分”をすべて 16bit のマトリクス に抽象化した。
これにより、
• 条件を増やす
• 条件を外す
• 反転する
• 遅延を付ける
といった変更が、設定だけで完結するようになった。

思想②:選択 × 反転 × 標準化 を bit で表現する

論理の可変部分を bit で持つことで、
PLC の内部はこうなる

(入力 XOR 反転) AND 選択

この処理は、
バラバラの入力条件を “標準形” にそろえる ためのものだ。
• 使う条件だけを抽出
• 必要なら反転
• 余計な条件は落とす
つまり、
論理に渡す前の“標準化レイヤー”を作っている。
この標準化があるから、
後から条件を変えても論理が壊れない。

思想③:遅延は“出力側”に置くことで意味が変わらない

遅延を入力側に置くと、
入力条件の組み合わせが変わるたびに
遅延の意味が変わってしまう。
しかし遅延を出力側に置けば、

どんな論理であれ
「最終的に出力が成立した瞬間」から遅延が始まる

つまり、
遅延が論理の外側に独立して存在できる。
これにより、
仕様変更があっても遅延の意味が変わらず、
現場での動作が安定する。

思想④:論理を“構造”として固定し、内容だけを可変にする

ラダーは構造、
マトリクスは内容。
この分離こそが、
壊れない制御 の本質だ。
• ラダーは一切書き換えない
• 設定だけで論理を変える
• 標準化で入力を整える
• 遅延も独立して動く
• AND/OR/NAND/NOR も設定で作れる
この思想が、
“万能マトリクスI/F” の根幹になっている。

第2章:ざっぱな構造──16bitで論理を抽象化する世界

まず、この画面の思想はこれだけ。

[I/F n] の行を ⇒ に見ていって欲しい項目を [選択] するだけ。

1行=1bit。
横に並んだ状態の中から、その I/F の入力源にしたい項目を選ぶ画面。

Untitiled.jpg

■ I/F1 の例(写真より)
I/F1 の行では「起動」だけが選択されている。

[I/F1] = [起動]

これで1bit 完成。


■ I/F2 の例(写真より)
I/F2 の行では
「蓋ストック無」と「蓋供給停止」が選択されている。

[I/F2] = [蓋ストック無] OR [蓋供給停止]

1行の中で複数選ぶと OR になる。


■ I/F3 は?
何も選んでいないので NOP。


■ I/F4 の例(写真より)
「操作異常」と「動力電源ON」が 反転 で選ばれている。
かつ、出力[I/F4]も反転されている。
反転は NOT を作る操作なので、

/[I/F4] = /[操作異常] OR /[動力電源ON]

ド・モルガンでひっくり返すと…

[I/F4] = [操作異常] AND [動力電源ON]

第3章:実装前の設計思想(この画面をコードに落とすための前提)

この画面をそのままコード化するには、
いくつかの前提と設計思想を押さえておく必要がある。
ここを理解していないと、後の「最短コード」が読めなくなる。

■ 1. 各項目(起動〜蓋無し搬出)は 2ワードのパラメタを持つ

• 選択パタン(16bit)
• 反転パタン(16bit)
この2つで画面の状態を完全に表現する。

■ 2. I/F1〜4 は下位4bitで表現する

1ワードで4つの I/F を扱う構造。
I/F1〜4 ⇒ bit0~3

■ 3. 項目は 8個あるので For-Next loop で処理する

実際のコードは予備を見て16回まわしている。
この構造で、8(16)項目分のパラメタを一気に処理できる。

■ 4. インデックス修飾注意点 “対象デバイスの単位で修飾される”

ここが 現場で最もハマるポイント。

● ワードデバイス(Z は ワード単位 で進む。)

EM0:10 → EM10(10ワード先)

● ビットデバイス
ビットデバイスは ビット単位で修飾される。

ワード単位の命令語でもビット単位で修飾される

R0000:16 → R0100(1チャネル先)
R0000:32 → R0200(2チャネル先)

• ワードデバイス → 16bits処理が成立する
• ビットデバイス → ビット単位なので構造が破綻する
よって、この設計では
ワードデバイスを使うことが絶対条件。

■ 5. 項目が OFF のときは「選択パタン=0000h」

OR に参加しない。

■ 6. 項目が ON のときは登録パタンをそのまま代入

画面で設定したパタンをそのまま使う。

■ 7. 反転パタンは選択パタンでマスクして作る

反転は XOR で NOT を作るだけなので、
選択されていないビットは反転させない。


画面で設定した内容は、
「選択パタン」「反転パタン」の 2ワードに代入される。
写真より、代表的な例を示す。

起動(反転なし)
選択 = 0001h
反転 = 0000h

• I/F1(bit0)を使用
• 反転なし → 反転パタンは 0000h


操作異常(反転あり)
選択 = 0008h
反転 = 0008h

• I/F4(bit3)を使用
• 反転あり → 選択パタンと同じビットだけ反転


● 補足
• 選択パタン … I/F の割当ビット
• 反転パタン … 選択パタンでマスクする
• 反転なし → 反転パタンは 0000h
• 反転あり → 選択パタンと同じビットが 1 になる

第4章:サンプルコードの解説 (Keyence版)

※ 本章のコードはすべてコピペで即実行できます。
 コピペ用リストは章末にまとめて掲載しています。
(コピペ用リストの内容は下記Serverのコードと若干相違があります。)
 
画面データと KV-STUDIO の実ファイルは Serverにアップ済みです。
https://yenqoo.com/qiita/matrix.zip
上記ファイルはKV-8000/VT5-W07 をターゲットにしています。
この章では、↑ このファイルの解説を行います。


主なデバイスの割り当て
・選択ビット:LR2400~(16ワード)
・選択ビットの代入用バッファ:@​DM0~
・選択ビットの演算用バッファ:@​EM16~

・反転ビット:LR4000~(16ワード)
・反転ビットの演算用バッファ:@​EM0~

・出力側の反転ビット:LR8800

ON Delay タイマ
・設定値:DM0~(4ワード)
・タイマデバイス:@​T0~
OFF Delay タイマ
・設定値:DM4~(4ワード)
・タイマデバイス:@​T4~

・出力デバイス:R1700~(4ビット)


• 初期化

004.jpg

PLCのRUN時は [MR000]はFなので、サブルーチン0(初期化ルーチン)を呼びます。
■ サブルーチン 00 の内容
057.jpg
L00057:
ローカル変数を使ってインデックス修飾しているため、変数宣言を行います。
エディタ側では使用範囲を自動判定できないため、明示的に宣言が必要です。
L00059以降:
初期値として遅延タイマの設定値を実タイマデバイスに代入します。
随時変更の必要が有る時はサブルーチン10に記述して変更通知ビットを立ててください。

ON  Delay--DM0 → DM3:出力1 → 出力4
OFF Delay--DM4 → DM7:出力1 → 出力4

L00063:
MR000をONして初期化ゲートを閉じます。

• SW操作の度にプリセット

007.jpg
画面の各スイッチが押された通知がR12210です。
スイッチが押される度に論理演算用のデバイスをプリセットします。

■ サブルーチン 10 の内容 
042.jpg
通知ビットをクリアして…
 
044.jpg
L00044:
SVは今回ビットデバイスにしているので、ワードデバイスにコピーします。
L00049:
反転ビットは選択している箇所のみ有効にします。
こうしておくことで、毎スキャン時の演算負荷を軽減できます。
 
052.jpg
L00052:
インデックス修飾のためビットデバイスをワードデバイスに代入します。

• ソースのON状態で設定パタンを有効にする

009.jpg
選択ビットの演算用バッファ(@​EM16~)を全クリアし、
ソースがONの場合に選択設定値を演算バッファへコピーします。

■ 実機ではこんな感じ・・・
018.jpg
この機能、実機での実装は最初から計画してなかったのでソースアドレスが連続しておらず、上図の様にバラバラに書く事になりました。

• 論理演算

022.jpg
L00022:
演算結果(@​EM32)をクリアします。
L00024:
各ソースの選択ビットと反転ビットの排他的論理和をとり、その結果を演算結果へ論理和で上書きします。
L00027:
演算結果を出力側の反転ビット(LR8800)で反転し、@​MR100へ代入します。

• 出力のON-OFF遅延 

030.jpg
@​MR100~をON-OFF遅延した後、最終出力のR1700~へ書き出します。

ここで注意点
タイマ自体はインデックス修飾することができません。
そのため、全タイマを常時アクティブにしておき、必要なタイマだけリセットする という方法を使っています。
タイマのインデックス修飾については以下の記事で詳しく解説しています
https://yenqoo.com/spices/basic/timer/timer.html
 
サンプルをシミュレーションした時のスクリーンショットです。
シミュレータ.jpg

• おまけの 裏技!

キーエンスPLCでは「ENDH」以降の領域に、メモ的になんでも記述できます。
今回のサンプルでも、登録モニタの立ち上げやSW操作に利用しています。
 
関連記事

[ENDH以降の動的メモの使い方]
ENDH以降の本当の使い方(現場が育てた文化)
https://qiita.com/yenqoo/items/5f63d0e94f6f72dec94f

[RCOMを使ったVersion管理の記事はこちら]
https://qiita.com/yenqoo/items/fc38b48de1bac44d4af2
 

• コピペ用ニモニックリスト

; ★彡┓汎用 Matrix Interface
; ┗━┛─────────────────────────
; KV-8000
; VT5-W07

;◎ Power ON Initial
LDB MR000
CALL #0

;■ SVを書き換えたら再計算
;  R12210:[選択]/[変転]SWを押すとONする
LD R12210
CALL #10

;■ 選択 ビットパタン(演算用)のデバイスをクリアしておく
LD CR2002
FMOV $0000 @EM16 DM100

;■ ソースの状態がアクティブになれば設定された選択パタンを演算用のデバイスに読み込む

;  << 以下はソースアドレスが連続している場合 >>
LD CR2002
DW.L +0 Z1
FOR DM100
    LD MR1000:Z1
    MOV @DM0:Z1 @EM16:Z1
    LD CR2002
    INC Z1
NEXT

;■ 16項目の論理和を計算
;@EM16~:各項目の選択bits
;@EM0 ~:各項目の反転bits
;@EM32:結果bitsパタン(出力に渡すやつ)

LD CR2002
LDA.L +0
CON
STA @EM32
CON
STA.L Z1

FOR DM100
    LD CR2002
    LDA @EM16:Z1
    CON
    EORA @EM0:Z1
    CON
    ORA @EM32
    CON
    STA @EM32
    INC Z1
NEXT

;■ 論理和の結果を出力側の[反転]パタンで反転し遅延前のデバイスに代入
LD CR2002
LDA @EM32
CON
EORA LR8800
CON
STA @MR100

; ON-Off Delay
; ■ タイマの入力側はインデックス修飾できないので、下の様に常時動作させておいて
; 目標のタイマをリセットする形をとります
; 下記Siteを参考にしてください
; ☆彡 Refer⇒ https://yenqoo.com/spices/basic/timer/timer.html

LD CR2002
TMS @0 #555
CON
TMS @1 #555
CON
TMS @2 #555
CON
TMS @3 #555
CON
TMS @4 #555
CON
TMS @5 #555
CON
TMS @6 #555
CON
TMS @7 #555
CON

DW.L +0 Z1
FOR DM102
    LD @MR100:Z1
    RES @T4:Z1
    CON
    INV
    RES @T0:Z1
    LDB @T0:Z1
    ANB R1700:Z1
    INV
    ANB @T4:Z1
    OUT R1700:Z1
    LD CR2002
    INC Z1
NEXT

END
; ☆━━━……‥‥・・・ Sub Routine
; 10 << Preset Logic Table
SBN #10

; ■ 変更通知Bitをクリア
LD CR2002
RES R12210

; ■ 各項目[選択]/[反転] パタンを修飾用変数に代入

LD CR2002
BMOV LR2400 TM16 DM100
BMOV LR4000 TM32 DM100

LD CR2002
DW.L +0 Z1

; ■ [反転]ビットパタンは[選択]している箇所のみに制限
;  毎Scanで演算しないのは、演算量を減らす工夫

FOR DM100
    LD CR2002
    LDA TM16:Z1
    CON
    ANDA TM32:Z1
    CON
    STA @EM0:Z1
    CON
    INC Z1
NEXT

; ■ インデックス修飾のためビットデバイスをワードデバイスに代入
LD CR2002
BMOV LR2400 @DM0 DM100
RET

;00 << Power ON Initial
SBN #0

; ● ローカル変数を使ってるので  変数宣言しときます。
;   インデックス修飾するのでエディタ側ではどの範囲まで使うのかが判断できないためです

LD CR2002
LDA @EM32
CON
LDA @DM15

; 初期値として遅延タイマの設定値を実タイマに代入します。
; 随時変更の必要が有る時は書き換えてください
; DM0~:出力1のON Delay~
; DM4~:出力1のOff Delay~

LD CR2002
DW.L +0 Z1
FOR DM102
    LD CR2002
    LDA DM0:Z1
    CON
    STA @T0:Z1
    CON
    LDA DM4:Z1
    CON
    STA @T4:Z1
    CON
    INC Z1
NEXT
LD CR2002
DW #16 DM100
CON
DW #4 DM102
CON
OUT MR000
RET
ENDH

第5章:実際の応用例──工務さんに神扱いされた瞬間

5.1 下流からの停止指示

ある日のこと。
下流設備から「ライン全体を止めてほしい」という停止指示が飛んできた。
このラインでは、機械本体とコンベアが連動して動いており、
通常は 同時停止 する設計になっていた。
しかし、この日は状況が違った。

5.2 Load中にコンベアが止まると機械がバグる

問題は Load動作の最中 に起きる。
ワークを機械に取り込んでいる途中でコンベアが止まると、
• 位置ズレ
• センサ誤検知
• ワーク詰まり
といった 典型的な“Load中停止バグ” が発生する。

工務さんは困り果てていた。
「下流が止め言うてるのに、こっちは止めたらバグるねん…
どうしたらええんや…」

5.3 だからコンベアだけ停止遅延が必要だった

この問題を解決するには、
停止命令そのものを分離して扱う必要があった。
実際に行ったのは、次の三手順だけである。

  1. 停止命令系を二つに分ける
    • 上流機械への停止命令
    • コンベアへの停止命令
    この二系統を独立制御にする。
  2. 上流の機械に対しては即停止
    下流から停止要求が来た瞬間、
    上流機械には 即時停止 を指示する。
  3. コンベアに対しては遅延停止
    一方でコンベアは、Load が完了するまで 数秒だけ動かし続ける。
    これにより、Load中停止バグを完全に回避できる。
    従来のラダー構造では、
    この例外処理を入れるだけで 改造が必要だった。

5.4 マトリクスI/Fなら設定だけで吸収

ここで真価を発揮したのが、前章までで構築した マトリクスI/F である。
今回の例外処理は、
タッチパネル上で停止命令の分岐と遅延値を設定しただけ で完結した。
• ラダーは一行も触っていない
• 停止命令の二系統化も
• コンベアの遅延停止も
すべて 画面設定だけで成立 した。
設定後、ラインを再起動すると──
一発で安定動作した。

5.5 「これどうやってんの?」と工務さんが驚いた

工務さんはしばらく画面を見つめてから、ぽつりとこう言った。
「……え、ラダー触ってへんの?
これどうやってんの?
いや、これ神やろ。」

その瞬間、
“例外のたびにラダーを書き換える文化” が終わった。

5.6 この仕組みが現場にもたらしたもの

• 例外対応が 設定変更だけ で完結
• ラダー改造ゼロで運用が回る
• 工務さん自身が調整できる
• ライン停止時間が激減
• 現場のストレスがなくなった
そして何より──
「例外が怖くないライン」 が誕生した。

終章:万能マトリクスI/Fは“現場の正史”になり得る

• 仕様変更に強い

現場で最も多いトラブルは「仕様が曖昧」「仕様が変わる」。
その不確実性を前提にした設計は、現場にとって武器になる。

• 壊れない

ラダーを書き換えない。
だから壊れない。
だから現場が安心して触れる。

• 拡張性が高い

条件が増えても、例外が増えても、
マトリクスの行と列を増やすだけで吸収できる。

• 設定だけで論理変更

これは“現場の文化”を変える力を持つ。
ラダー改造という儀式から、現場を解放する。

• 現場で戦う人間のための設計

工務さん、保全さん、立ち上げ担当、夜勤のオペレータ。
彼らが「自分で調整できる」ことが、どれほどの価値を持つか。

• この記事が誰かの現場を救うかもしれない

この記事を読んだ誰かが、
例外処理に追われる日々から解放されるかもしれない。
仕様変更に怯えずに済むかもしれない。
現場の文化が、少しだけ良い方向に変わるかもしれない。


万能マトリクスI/Fは、
私が現場で積み重ねてきた経験と思想の結晶であり、
“現場の正史”として残す価値がある技術 である。


作者
圓空(えんくう)
https://yenqoo.com/spices/
https://yenqoo.com/monologue/

キーエンスPLCを中心に、
“技術 × 美学 × 遊び心” をテーマにした技術文化を発信しています。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?