シーケンス制御講座

プログラム設計(旧)

シーケンス制御講座 上級編 プログラム設計(旧)

ステップ方式で書いたバージョンです。プログラムを書く前に、プログラム自体の設計を行います。この作業を行わないとプログラムが読みにくいなったり、プログラムを作成する作業時間が長くなったりするので最初に行っておきましょう。

作成日:2016年05月10日
更新日:2021年10月05日

実際の作業の流れでは、おおまかな説明をしました。ここではさらに詳細に説明とプログラム設計をしようと思います。ここではI/Oは完成しているとします。

設備の動きを把握する

データシフトについてで説明した動作を例にします。

製品シフトは次のようになります。

まず全体の動きを把握します。各ユニットが何のためにあるのか?どのような動作をするのか?各ユニットの動作条件などすべて把握します。もし機械図面が手に入るようでしたらもらっておきましょう。ここでの機械図面は詳細まで書いてあるものでなくてもいいです。機械図面が手に入らないのであれば、手書きでもいいので簡単に書いて見ましょう。イメージがわかればいいので、本当に簡単でいいのです。私は各ユニットを四角で書くだけです。そして各ユニットの動作がイメージできていれば次の準備に移ります。

デバイス番号を決める

次はデバイス番号を決めておきます。たとえば「部品を置く」ステーションでは、「M1000」~「M1199」の200個の内部リレーを使用するように取り決めを行います。なぜこのようなことを決めるのかというと、分かりやすいからです。ラダー図も番号がそろっていてきれいに見えます。一昔前のシーケンサはメモリ容量も少なく、内部リレーも限られた数しかありませんでした。そのため、使用していないデバイス番号をかたっぱしから使用していました。このように使わないと内部リレーも足りなくなるからです。そのためなるべく隙間を空けないように使用するのが一般的でした。さらに昔のシーケンサになると、デバイス番号も固定されていて、タイマーコイルなどは数個しか使えない時代もありました。今は昔と違いこのようなことは無いと思います。内部リレーも大量に用意されていますので、コイルが足りなくなるより先にプログラムのメモリがオーバーすると思います。このように最近のシーケンサは性能もあがり、ある程度余裕のある使用ができるのです。

デバイス番号を決めるのですが、深く考える必要もありません。ただプログラムの経験がほとんどないと、使用する数がわからないと思います。そこまで大きくない動作でしたら内部リレーで200個程度割り当てれば問題は無いでしょう。上の図で例えると、

「部品を置く」 :「M1000」~200個  「D1000」~100個
「カバーを置く」:「M1200」~200個  「D1100」~100個
「ネジを締める」:「M1400」~200個  「D1200」~100個
「ネジを確認」 :「M1600」~200個  「D1300」~100個

だいたいこんな感じでしょうか?たとえば部品を置く動作をプログラムするときは「M1000」~「M1199」の内部リレーを使うようにします。製品情報や良否判定は「D1000」~「D1099」の範囲で使用します。ここでの取り決めは自分の中での取り決めなので、絶対に範囲以外のデバイスが使用できないということではありません。普通に使えば使用できます。足りなくなった場合など例えば「M2000」~などに適当に増やしていきます。こうしておけば使用している内部コイルによって、どこの制御か分かりやすいし、プログラムを作るときに「内部リレーは何番を使おう?」と悩む必要も無いのです。

デバイス番号が決まれば、先ほど準備した図面上にわかりやすく書いていきます。最終的には電子ファイルにまとめますが、作成中は紙に書いたものを見たほうが作業もしやすいでしょう。

全体のプログラム設計

デバイス番号が決まったからといって、プログラムを作るわけではありません。プログラムの設計は最初が大事で、最初の考え方を間違えると後で痛い目に会います。製作する設備にあわせた設計をしっかりしてください。この作業に時間をかけても問題ありません。設計といっても図面を引いたりするわけではなく、どのように制御するのかを考えるのです。 上の図での制御方法を少し考えて見ましょう。
図には書いていませんが、「ベースを入れる」位置にベースが来ると、設備は「部品を置く」位置までベースを引き込むものとします。このユニットを搬入ユニットと呼ぶことにします。
初めて設計する場合、このプログラム設計の時点でわからなくなる可能性があります。 どのように搬送を動かせばいいのか?どのように部品を置く動作をさせればいいのか?深く考えれば余計にわからなくなります。それは制御を上位側から考えようとしているからです。

慣れないうちは下から考えてください。下からというのは各ユニットの制御のことですが、今は全体的な制御設計をしているので各ユニットの動作までは考える必要はありません。各ユニットの動作条件を決めます。さらにこの条件は他のユニットとできる限り統一します。その条件が成立したとき、そのユニットは1サイクル動作させます。たとえばネジ締め動作条件が成立した場合、「ネジを締める」ユニットはネジ締め動作を1サイクル実行します。 このように各ユニットの動作条件を決めていくことも大切な設計となります。
次は搬入ユニットです。ここは「ベースを入れる」位置にベースがあった場合、さらに「部品を置く」位置にベースが無い場合と、内部の搬送ユニットが動作していない場合を条件に搬入動作させればいいと思います。

次は内部の搬送ユニットです。搬送ユニットが動作したら、D1000~D1399のデータを100個単位でデータシフトすることにします。ここで搬送ユニットが動作する条件を決める必要があります。搬入ユニットからベースが入ってきて、「部品を置く」動作を完了したとき、搬送ユニットが動作する。単純に考えればこのような動作条件になりますが、この条件には欠点があります。搬入ユニットからベースが入ってこないと動作しません。つまり、常に搬入させないと設備は動きません。一日の作業が終わったとき、中の作業中のベースを排出することができないのです。私はこのような条件は好きでないので変更します。搬送ユニットが動作する条件はワーク検出している各ユニットが動作完了している。各ユニットが動作中で無いこと、です。たとえば「部品を置く」ユニットでは、ワーク検出していれば、動作完了していること。またはワーク検出していないこと。この条件を各ユニットごと設定しANDでくくればいいのです。さらにいずれかのユニットがワーク検出していることも条件に入れておきましょう。こうしておけば例え次のベースが搬入されなくても、搬送動作は内部ワークがなくなるまで動作します。動作完了しているかどうかの条件設定方法は後で説明します。

搬送動作の条件はできました。次は各ユニットの動作条件を考えて見ましょう。搬送ユニットが動作した後に各ユニットを動作させる。この条件も一見はいいように見えますが、もし搬送ユニットが動作した後、設備を停止させた場合、動かなくなります。設備を自動運転に入れた瞬間、前回停止した状態を読み出し、各ユニットに動作指令を出す必要があります。このようなめんどくさい設計はやめましょう。もっと単純に考えればいいのです。ワーク検出している各ユニットが動作完了していない状態で、搬送ユニットが動作中でなく、原点で待機している場合。これだけです。

ユニットが動作完了しているかどうかを見るにはデータレジスタを使用します。部品を置くユニットの「D1000」~の部分を見てみます。下の図のように設定します。設定方法は自分のわかりやすい順序で設定してください。今回は説明用なので単純に設定してみました。

これは部品を置くユニットの内容なのですが、すでにネジを締めるユニットなどの項目があります。実はここで使うことは無いのですが、データレジスタを100個分まとめてシフトさせるのであらかじめ設定しています。このように先のことまで考えてシステム全体を設計することが大切です。全ユニットで見ると下の図のようになります。

「カバーを置く」ユニットで考えて見ましょう。「D1101」を動作完了確認とします。「D1101」が”0”で搬送が原点で待機しているとき動作させます。ユニットが動作開始した時点で、搬送ユニットは動作しないようにしてください。「カバーを置く」ユニットがサイクル完了した時点で、正常完了であれば「D1101」に”1”を書きます。トラブルがあった場合などは”2”を書きます。「D1101」の値が1以上であれば動作完了となります。各ユニットもこのような条件をつけます。各ユニットが動作完了すると搬送ユニットが動作します。するとデータシフトするので、「D1101」は”0”となり、再度動作します。「ネジを締める」ユニットはどうでしょう。データシフトするので「D1201」は”1”が入っています。「ネジを締める」は「D1202」を使います。一桁目の番号を変えないと上書きされるからです。この方法だと動作条件を細かく変えることもできます。たとえば「ネジを締める」ユニットで「D1201」に”2”が入っていれば動作させずにそのまま「D1202」に”3”を書き込み完了させる。これは前ユニットで正常に完了していなければ、それ以降のユニット動作は必要ないため、動作をさせないのです。ここで”3”を書き込みましたが、これはユニットパスしたということで、書き込んだだけで特に何を書き込んでも問題ありません。面白いことに最初から”3”を書き込んでおくとそのユニットをパスしていきます。搬入時に書き込んでおけばパス運転などに使えます。

各ユニットの条件は完了しました。ここで気づいた人もいると思いますが、これで動作します。つまり全体を把握するメインルーチンと言うべき回路を作る必要は無かったのです。各ユニットがそれぞれの条件で動作するため、何らかの不具合で動かない時はそのユニットの動作条件を見ればいいのです。

一応回路設計は完了しましたが、今回の設備はあまり大きくないので各ユニットがそれぞれ独立して動作する形になりました。各ユニットを接続するものはデータシフトしているデータのみです。しかし、大きな設備や複雑な制御が必要な場合はやはり全体を監視するプログラムをいれておいたほうがいいかもしれません。

方法は特に難しくも無く全体を監視できる動作部分、ここでは搬送部分になりますが、この部分にデータシフトから各ユニット情報を監視して、各ユニットに動作指令を出すようにすればいいのです。簡単に言うと、各ユニットがそれぞれ動作条件を持って動作していたものを、搬送ユニットにまとめて、全体を監視するようにするのです。

各ユニットのプログラム設計

全体の制御の設計が終わったら、各ユニットの制御設計を行います。簡単に説明しましたが、各ユニットの動作完了状況を入れるデータレジスタの値は統一しておいてください。0が未実施。1が正常完了。2が異常完了のようにです。そしてこの値が0ということを動作条件に入れておきます。たとえば「ネジを締めるST」は「D1202」が0のときでワーク検出しているときのように、まだ動作していない場合を条件に追加しておきます。 こうしないと動作完了しても、何回も動作してしまうからです。

次に各ユニットの動作をすべて書き上げてください。ここで重要なのは条件分岐の考え方です。「カバーを置く」ユニットでみてみます。置くカバーの種類をあらかじめ設定するプログラムでは、設定にあったカバーを置く必要があります。これは単純に別プログラムで動作すればいいのですが、この動作プログラムをメイン部分とサブの部分に分けてかんがえて見ましょう。まずメイン部分はでは

  • ①カバーを取りに行く
  • ②ハンドを下降する
  • ③ハンドを閉めてカバーをつかむ
  • ④ハンドを上昇する
  • ⑤カバーを置く位置まで持ってくる
  • ⑥ハンドを下降する
  • ⑦ハンドを開いてカバーを置く
  • ⑧ハンドを上昇する
  • ⑨1サイクル完了

もしカバーの種類によって別プログラムを作る場合は、上記の動作をカバーの種類分作る必要があります。違うのは①のカバーを取りに行く場所が違うだけで、他の動作は同じはずです。つまり上記の動作の①の部分で、「カバーを取りに行け」という指令を内部リレーで出し、その内部リレーとカバーの種類の設定で場所を変化させるのです。この場所を変化させている部分をサブとします。この部分に位置情報と実行指令を出すのです。実行指令と一緒に送る位置情報などの値を引数と呼びます。移動が完了したら、移動完了の信号をメイン部分に返して、次のステップに進ませます。これが簡単なサブルーチンの考え方です。ステップ制御で説明した書き方でサンプルをかいてみます。

かなり簡単に書きましたが、最初の5ステップ目では機種設定をビット出力に変更しています。21ステップからが動作制御になりますが、最初の条件はサンプルプログラムなので動かないようにしています。ここに動作条件をいれてください。次の「M101」の部分です。ここではカバーを取に行く位置まで移動しなさい。という命令しか書いていません。どこに取に行くかというと、52ステップから書いています。

今回はダイヤディックやIAIのロボシリンダを想定しています。52ステップでは「M101」がONするとともに、機種設定された位置を書き込んで、さらに移動パルスを出しています。次の68ステップで、移動パルスを受けたら移動位置の出力をロボット側に出し、0.1秒後に移動指令を出しています。一応この部分は自分で自己保持を解除する仕組みにしています。

次はサブルーチンを使わない条件分岐です。細かい条件分岐がたくさんある場合は便利です。たとえば「ネジを締める」部分で見てみましょう。ネジを締める箇所が全部で①~⑥ポイントあるとします。ただし機種によって締める箇所を変更します。

  • 機種1:全箇所
  • 機種2:①②③④
  • 機種3:①②⑤⑥

簡単に書きましたが、機種によって上記のように締め付け箇所を変更します。このとき何も考えずにプログラムを書くと、機種の数だけプログラムを書いてしまいます。また悪い例として、無理やり一個のプログラムで実行させようとして、複雑になりすぎてしまうことがあります。

機種数だけプログラムを書く場合

無理やり一個のプログラムにした場合

このような書き方だと、一個の動作に対して、多数のサイクル完了ができてしまいます。これは非常に悪い書き方です。理由は、今実際にどの部分をプログラムが動作しているのかが非常に分かり難い。さらに、プログラムの構成が不安定になりやすく、バグが潜みやすいことです。普段は問題なく動作していても、何かのタイミングで動作不能になる可能性が大きくなります。

プログラムは複雑に分岐する必要がない場合は、一個のプログラムにすべての動作を書いて、必要ない部分をパスさせる方向で考えて見ましょう。ここでは①~⑥ポイントのすべてのネジ締めを行うプログラムを作ります。機種2の場合、⑤⑥のネジ締めをパスさせ、サイクル完了させます。ここで重要なのは、⑥ポイントの締め付け動作の後にサイクル完了信号を書きます。そしてどの機種がきても、必ずこのサイクル完了を通って終了します。機種2で④のネジ締めを行った後、別のサイクル完了信号を書くのではなく、⑥のネジ締めの後のサイクル完了信号を利用するのです。これにより、プログラムが実行して、サイクル完了信号が入って完了するという一つの流れが出来上がります。

この書き方だと、プログラムは分岐せずまっすぐ進むため、今どの部分で動作しているか等が把握しやすいと思います。また、条件分岐により、同じような動作を何個も書く必要がないので、見た目もシンプルになります。必要ない部分はパス(飛ばす)させればいいので、動きも自由に変更できます。この制御はステップ制御で説明した書き方だと簡単に実現できます。

上記のように動作制御している「D0」の値を書き換えてしまえば簡単に制御をパスできます。これを歩進制御で説明した回路で行う場合少し工夫が必要です。順番に自己保持をかけているので、パスするタイミングで、パスしたい部分に一気に自己保持をかけてしまうか、パスしたいタイミングで新たに別コイルで自己保持をかけ、そのコイルを利用してパス先の自己保持が入るようにするかです。やり方はいろいろありますが、制御するものによってはできない場合がありますので、制御するものにあわせて行うことが大切です。

プログラムを構造化する

先ほど「同じ動作を何度も書く必要がない」という言葉が出てきましたが、実際には2度でも書きたくはありません。構造化の部分で説明していますので、大きいプログラムになるほど、できるだけ構造化して分かりやすいプログラムにすることを心がけましょう。



図解入門 よくわかる最新 シーケンス制御と回路図の基本はKindle版(電子書籍)です。単行本ご希望の方は、フォーマットで単行本を選択してください。または、トップページよりご購入ください。

Copyright (C) 2010 シーケンス制御講座, All rights reserved.