【実践プログラミング編:第8回】
本連載では、FA現場で戦うための実務特化型プログラミングを解説します。
- 「品種切り替えのラダーで、MOV命令を20行も30行もコピペして並べている」
- 「パラメータが1つ増えるたびにアドレスの修正漏れが起き、デバッグで徹夜になる」
- 「一括転送を組んだら、全然関係ない隣のタイマ設定値まで勝手に書き換わった」
データを1点ずつMOV命令で運ぶ書き方は、画面のスクロールを増やすだけでなく、コピペミスによるバグの温床になります。放置すれば、仕様変更のたびに現場で冷や汗をかくことになります。
実務で数多くの制御盤・PLC設計を手掛けてきた筆者が、大量データを一瞬で処理する「BMOV/FMOV命令の鉄則」を伝授します。この記事を読めば、何十行もあったラダーがたった1行に圧縮され、保守性の高い美しいプログラムが組めるようになります。
結論として、並び順を保って丸ごとコピーする「レシピ転送」にはBMOVを使い、同じ値で埋め尽くす「一括初期化」にはFMOVを使う(必要に応じてパルス化する)のが基本です。
ただし、転送点数の指定を1つ誤るだけで「隣接する別用途のメモリを一瞬で破壊する致命的な罠」が潜んでいます。安全にブロック処理を使いこなす具体的な設計作法を順番に見ていきましょう。
【本連載の前提】 本記事内のプログラム例や命令語は、国内FA業界で最もシェアの高い「三菱電機製PLC(MELSEC)」をベースに解説しています。しかし、ここで解説する「なぜその命令が必要なのか」「現場でどう使うのか」という設計思想は、オムロンやキーエンスなど、すべてのメーカーのPLCで共通して使える普遍的な技術です。メーカーの違いを恐れず、本質的な「設計の根幹」を身につけてください。
BMOVとFMOVの決定的な違い(基本の理解)
まずは2つの命令の根本的な役割を整理します。前回のMOV命令と同様、どちらも「転送元のデータは消えずに残る(上書きコピー)」という大原則は同じですが、転送元(S)のデータをどう参照してコピーするかが決定的に異なります。

BMOV(ブロック転送)=「複数データの丸ごとコピペ(n対n)」
BMOV(Block MOV)は、ある連続した領域(n点分)の内容を、並び順をそのまま保った状態で別の場所(n点分)へ丸ごとコピー(複製)する命令です。
Excelで複数のセルを範囲選択してコピーし、別の列へそのまま貼り付ける動作や、複数ページの「レシピ原本」をページ順のまま丸ごとコピーするイメージを思い浮かべてください。もちろん、コピー元(原本)のデータは消えずにそのまま残ります。「速度・圧力・温度・タイマ値」といった複数の異なるパラメータで構成される品種レシピの塊を、実動作エリアへ一括展開する用途に最適です。
- 書式:
[BMOV S D n]- S(転送元先頭):コピー元のスタートアドレス(例:
D1000) - D(転送先先頭):コピー先のスタートアドレス(例:
D200) - n(転送点数):転送するワード数(例:
K10なら10個分)
- S(転送元先頭):コピー元のスタートアドレス(例:
例えば [BMOV D1000 D200 K3] を実行すると、D1000→D200、D1001→D201、D1002→D202 へと3点のデータが並び順のまま一括でコピーされます。
FMOV(同一データ一括転送)=「1つのデータを連続スタンプ(1対n)」
一方のFMOV(Fill MOV)は、指定した「たった1つのデータ(定数または単一レジスタ)」を、連続した複数のエリア(n点分)へ一気に複製して埋め尽くす命令です。
同じ印影のスタンプを、連続する枠すべてに「ポンポンポン!」と押して同じ値で塗りつぶすイメージです。実務では、定数 K0 を指定して特定エリアを一撃でゼロクリア(初期化)したり、1つの基準レジスタの値を全軸・全工程のレジスタへ一斉に同じ値でセットしたりする用途で活躍します。
- 書式:
[FMOV S D n]- S(格納する値):コピーしたい1点のデータレジスタまたは定数(例:
D1000、K0) - D(転送先先頭):書き込み先のスタートアドレス(例:
D200) - n(転送点数):書き込むワード数(例:
K10なら10個分)
- S(格納する値):コピーしたい1点のデータレジスタまたは定数(例:
まずは「並び順のまま丸ごとコピーするならBMOV、同じ値(0など)で一気に埋め尽くすならFMOV」と明確に使い分けてください。
転送元に「Dレジスタ」を指定したときの挙動の違い
初心者が勘違いしやすいのが、「FMOVは定数(K0など)しか入れられない」という思い込みです。FMOVの転送元(S)には、定数だけでなく D レジスタも指定できます。
ここで、転送元に D レジスタを指定した以下のラダーを見比べてください。

見た目はそっくりですが、裏で動いているデータの流れは全くの別物です。
[BMOV D600 D700 K3]を実行した場合(3点 → 3点の丸ごとコピー):D600の中身 →D700へコピーD601の中身 →D701へコピーD602の中身 →D702へコピー- 転送元も 連続する3ワード分(
D600〜D602) が参照され、並び順のまま1対1で複製されます(D600〜D602のデータは消えません)。
[FMOV D800 D900 K3]を実行した場合(1点 → 3点の同一コピー):D800の中身(400) →D900へコピーD800の中身(400) →D901へコピーD800の中身(400) →D902へコピー- 転送元は 先頭の
D800(1ワード)しか参照されません(D801やD802は無視されます)。D800に入っている「400」などという値が、D600〜D602の3箇所すべてに複製されます。
まずは「並び順のまま n対n で丸ごとコピーするならBMOV、1つの値(定数や単一レジスタ)を 1対n で全域にコピーするならFMOV」と正確に仕組みを押さえてください。
新人がやりがちな3大トラブル(現場の罠)
ブロック転送命令は、引数ひとつで数十〜数百ワードを一瞬で書き換える強力な命令です。しかし、その威力ゆえに、使い方を一歩間違えると設備の誤動作やパラメータ消滅を引き起こします。
実務1年目が現場で必ず直面する代表的な3つの罠を見ていきましょう。
罠① 点数オーバーによる「隣接データの破壊」
最も多発するのが、転送点数 n の指定ミスによる別領域の巻き込み破壊です。
例えば、レシピデータを10点(D200〜D209)転送する設計だったとします。ここで「後から項目が増えるかもしれないから、余裕を持たせておこう」と安易に n = K20 と指定したらどうなるでしょうか。
当然、D200〜D219 までの20ワード分が強制的に上書きされます。もし D210 以降に「シリンダ遅延タイマの設定値」や「サーボの現在位置バッファ」を配置していた場合、品種を切り替えた瞬間にそれらのデータが破壊されます。
結果として「品種を変えると全く関係ないシリンダがタイムアップ異常を起こす」という怪現象に発展します。
罠② パルス化忘れによる「毎スキャン強制上書き」
前回のMOV命令と同様に、実行タイミング(常時実行かパルス実行か)の考慮漏れにも注意が必要です。
M10(品種1選択中)
───[ ]───────────────────────[ BMOV D1000 D200 K10 ]
このように常時実行型の BMOV で記述すると、PLCは1秒間に何百回もマスターデータ(D1000〜)を実動作エリア(D200〜)へ上書きし続けます。
通信用のバッファへ常時データをミラーリングしたい場合など、あえて毎スキャン上書きさせる設計もありますが、レシピ展開などでこれを行うとトラブルの元になります。現場の作業者がタッチパネルから D200 の速度を微調整しても、次のスキャン(0.01秒後)には元の値に強制リセットされてしまうためです。
後から数値を微調整する可能性があるエリアへ一括転送・一括クリアを行う際は、命令語をパルス型(BMOVP / FMOVP)にするか、手前の実行条件を立ち上がりパルス接点(|↑|)にして「条件成立時に1回だけ叩く」ように設計する点に気をつけてください。
常時実行とパルス実行のスキャンタイム上の違いや、32ビットデータが裏で2ワード占有する仕組みについては、前回の『【第7回】MOVとDMOVの決定的な違い!32ビット化けと2ワード破壊の罠』で詳しく解説しています。
罠③ 32ビットデータを転送する際の「点数カウント間違い」
レシピの中に「サーボの目標座標(32ビット=2ワード)」が含まれている場合、転送点数 n の数え方に注意が必要です。
BMOV や FMOV の点数 n は、「データの個数」ではなく「ワード数(16ビット単位の箱の数)」を指定します。
つまり、32ビットの座標データを「5個」転送したい場合、n に指定すべき数値は K5 ではなく、2倍の K10(10ワード分) です。ここで K5 と書いてしまうと、データの後半半分が転送されずにちょん切られ、座標データが化けて設備が暴走します。
つまり、「転送先の最終アドレス(どこからどこまで書き換わるか)を正確に計算し、毎スキャン上書きによる不具合が起きないよう実行タイミング(パルス化の有無)に気をつける」のが現場で身を守るポイントです。
実践回路① FMOVで作る「データ一括クリア(初期化)」
ここからは、現場でそのまま使える実践回路の型を解説します。まずは設備のサイクル開始時や異常リセット時に、作業用メモリを一撃で初期化する FMOV 回路です。
現場で求められる初期化処理
生産設備では、1サイクルが完了してワークを排出した際、前サイクルの「計測データ」や「演算途中のバッファ」を綺麗にゼロクリアして次のワークを迎え入れる必要があります。
これを [MOV K0 D200]、[MOV K0 D201]……と1行ずつ書くのは今日で卒業しましょう。
// 実装イメージ(GX Works ラダー表現)
M10(初期化指令)
───[ ↑ ]───────────────────────[ FMOV K0 D200 K50 ]
回路設計のポイント
- 定数
K0の指定: 第1引数にK0を指定することで、D200を先頭とする連続50ワード(D200 〜 D249)のメモリを一瞬ですべて0に書き換えます。 - 終端アドレスの把握: 「
D200から50点」なので、クリアされる最後のアドレスは200 + 50 - 1 = 249(D249)です。別用途のデータは必ずキリよくD250やD300から配置してください。
このように、「初期化したいデータは連続したアドレスに固めて配置し、FMOVP K0 の1行で一掃する」設計作法です。
実践回路② BMOVで作る「品種レシピ切り替え」
続いて、BMOVP を用いた品種レシピ切り替えの王道回路です。
量産設備では、生産する品種(品種1、品種2、品種3…)に応じて、「搬送速度」「プレス加圧力」「加熱タイマ値」などのパラメータ群をごっそり入れ替える制御が求められます。

メモリマップ(データテーブル)の設計思想
レシピ管理をシンプルに組む最大の秘訣は、ラダーを書く前の「メモリの区画整理」にあります。
以下のように、全品種でデータの「並び順(内訳)」と「確保する枠のサイズ」を完全に統一します。
- 実動作エリア(
D200 〜 D209:10ワード枠)- 実際の自動運転ラダーが常時参照するエリア(D200:速度、D201:圧力、D202:タイマ値…)。
- 品種1 マスター(
D1000 〜 D1009:10ワード枠) - 品種2 マスター(
D1010 〜 D1019:10ワード枠) - 品種3 マスター(
D1020 〜 D1029:10ワード枠)
💡 現場で活きる「予備領域」の知恵 今すぐ使うパラメータが「6個」しかなくても、枠はキリよく 「10点単位(または20点単位)」 で確保し、余った4点は空き(予備)にしておきます。こうしておけば、後から「やっぱり乾燥タイマもレシピに追加して!」と客先から要求されても、既存のアドレスを一切ずらさずに空き枠へ追加できます。
品種切り替えラダーの実装
タッチパネルで品種を選択し、「レシピ展開ボタン(M50)」を押した瞬間に実動作エリアへデータをロードする回路です。
// 品種1 選択時
M101(品種1選択中) M50(レシピ展開指令)
───[ ]───────────────[ ↑ ]─────────────────[ BMOV D1000 D200 K10 ]
// 品種2 選択時
M102(品種2選択中) M50(レシピ展開指令)
───[ ]───────────────[ ↑ ]─────────────────[ BMOV D1010 D200 K10 ]
// 品種3 選択時
M103(品種3選択中) M50(レシピ展開指令)
───[ ]───────────────[ ↑ ]─────────────────[ BMOV D1020 D200 K10 ]
ラダーの自動運転回路側は、常に実動作エリア(D200〜D209)だけを見て動けばよいため、品種ごとの条件分岐を作る必要がなくなります。
「マスター領域は10点や20点のキリが良いブロック単位で区切り、運転前に実動作エリアへ BMOV で一括ロードする」という型を覚えてください。
まとめ & 次回予告
1点ずつMOV命令を並べる書き方から卒業し、データを「ブロック(塊)」として設計できるようになると、プログラムの行数は劇的に減り、改造に強いラダーへと進化します。
- BMOV(コピー機):並び順を保ったまま別エリアへ一括コピーする。レシピ展開の主役。
- FMOV(一括スタンプ):同じ値(
K0など)で連続領域を一気に埋め尽くす。データ初期化の主役。 - 実行タイミングへの配慮:タッチパネルからの微調整が毎スキャン上書きされて消えないよう、用途に応じて
BMOVP/FMOVPや立ち上がりパルス接点 を使い分ける。 - 予備を含めたブロック設計:32ビットデータは2ワード分として数え、将来の項目追加に備えて「10点・20点単位」のキリが良い区画でメモリを割り当てる。
まずはご自身のプログラムで、MOV や RST が何行も縦に並んでいる箇所を探し、BMOV / FMOV の1行に置き換えてみてください。
次回予告
今回のレシピ回路では、品種1〜3を接点で分岐させて3行の BMOV で記述しました。数種類ならこれで十分ですが、もし「品種数が50種類、100種類に増えたら」どうするでしょうか? まさか BMOV を100行並べるわけにはいきません。
そこで登場するのが、品種番号に応じて転送元アドレスを自動で計算・変化させる「インデックス修飾(Zレジスタ)」です。
次回は、100行のラダーをたった1行に圧縮する魔法の杖でありながら、使い方を誤るとPLCを即座にエラー停止させる諸刃の剣、【第9回】ラダーが10分の1に縮む!インデックス修飾(Zレジスタ)の基礎と「暴走・青天井」を防ぐリミットの鉄則 をお届けします。中級者への壁を突破する最重要回ですので、ぜひお楽しみに!
※本記事で使用している画面は、三菱電機株式会社「GX Works2」の操作画面です。
※GX Works2、MELSECは、三菱電機株式会社の登録商標です。
※本記事で紹介しているプログラムや回路図は、技術解説のためのサンプルです。実機での動作を保証するものではありません。
※実際に使用する際は、十分な検証を行った上で、安全に配慮して運用してください。