C言語によるPLCプログラミングガイド:サイクルスキャン


APDahlen Applications Engineer

概要

  • PLCサイクルスキャンは、入力を読み取り、ユーザープログラムを実行し、出力に書き込むという一連のプロセスです。ユーザーのプログラムがI/Oに対して直接操作することはありません。これは、実行時のバグを最小限に抑えるための重要な考え方です。

  • 最近のPLCはC言語でプログラムできるものもあります。また、PLCとPCの境界線は曖昧です。Revolutions PiのようなハイブリッドPLCは非常に柔軟性が高く、さまざまなプログラミング言語を使用できます。

  • ラダーロジック(LL)やストラクチャードテキスト(ST)のようなIEC 61131-3専用言語を可能な限り使用すべきです。しかし、プログラミングの経験や、クラウドストレージやサイバーセキュリティを備えた一般的になりつつあるインダストリー4.0ネットワーキングを活用する能力など、C言語を使用する理由があります。

はじめに

産業経済の鉄則から始めましょう。システムのダウンタイムは、1分あたり数百ドルから数千ドルのコストがかかり、恐ろしく高価です。PLCのような産業用コンポーネントは、このダウンタイムを最小限に抑えるために、メンテナンスが容易なように設計されています。この事実は、ラダーロジック(LL)などのIEC 61131-3言語にも及びます。これらの言語は、ロジックの状態を技術者にわかりやすくほぼリアルタイムで表示するなど、ロジックをグラフィカルに表現して読みやすさを高めるように設計されています。

確実に信頼できるPLC言語を使い続けるべき理由は沢山あります。しかし、今でもsprintf( )を使用し、自信を持っているK&RのC言語プログラマーもいるでしょう。PLCと産業用PCの境界線が曖昧な技術を活用したい場合もあるでしょう。また、データ共有(クラウド)、サイバーセキュリティ、および更新の容易さを重視して、ネットワークデバイスの規模と機能性を活用したい場合もあるでしょう。

メインルーチン内でのPLCサイクルスキャン

main( )ルーチンをできるだけシンプルにするために、構造を追加しましょう。例えば、従来のラッチをこのように表現すると、いくらかの価値があるでしょうか?そのアイデアを図式化したものが図1です。

void loop( ) {

  readInputs( );

  if (SS1 & PB_START & !PB_STOP) {
    FAN = ON;
    PL_GREEN = ON;
    PL_RED = OFF;
  }

  if (!SS1 | PB_STOP) {
    FAN = OFF;
    PL_GREEN = OFF;
    PL_RED = ON;
  }
   writeOutputs( );
}

可能な限り、I/Oへの関数呼び出しを抽象化し、I/Oにシンプルで自己文書化可能な名前を付けました。多くの点で、時には扱いにくいC言語(あっ、すみません、完璧です)を、ストラクチャードテキスト(ST)に近づけたのです。コードリストで暗黙的に使われていXマクロの技法について説明をしている、この前提条件となる記事を参照してください。この文書では、簡略化されたコードに関連する抽象化について説明しています。また、ラダーロジックの観点からPLCのメモリ構造について説明している、この記事も興味があるかもしれません。

図1: この時計のアナロジーは、PLCのプログラムスキャン中に実行される動作を表しています。

PLCのサイクルスキャンのパターン

このコードでは、図1に示すように、ループの開始時に入力が固定され、ループの終了時に出力が設定されるPLCスタイルのサイクルスキャン構造を想定しています。おそらく、入力のスナップショットを取得してから操作することで、このスタイルをすでに使用していることでしょう。これは重要な構造で、ループの間、固定データセットを操作したいからです。例えば、ループの最初にPB_STARTを操作するコードがあり、ループの終わり近くに同じPB_START変数を操作する追加のコードがあるとします。PB_STARTがループの途中で変更されると、プログラムに微妙なバグが入る可能性があります。

PLCのサイクルスキャン構造は、特定の種類のバグも防止します。たとえば、MOTOR_1が条件文の中からループの先頭付近で更新されたとします。その後、プログラマーが MOTOR_1の以前の値を使用したとします。条件文の構造によって出力が入力に依存する場合としない場合があるため、システムは予測不可能になります。このような非決定論的バグのトラブルシューティングは、条件の特定が非常に難しいので、幸運を祈ります。

モジュール性とカプセル化

重要なのは、入力と出力を直接操作しないということです。代わりに、内部メモリ(スナップショット)構造を操作します。readInputs( )関数(メソッド)と writeOutputs( )関数(メソッド)は、そうしなければコードが乱雑になるdigitalRead( )関数とdigitalWrite( )関数をすべて統合します。この統合により、決定論的な動作も保証されます。

技術的なヒント: PLCサイクルスキャン構造は、最も速いプログラミング手法ではなく、最もリソース効率が高いプログラミング手法でもないことは事実です。しかし、プログラミングの危険性を考えると、このアドバイスに反する理由はあまりありません。

高速性が必要な場合は、マイクロコントローラの割り込みサービスルーチン(ISR)を揮発性変数とmain( )とISR間のアトミックなデータ転送で実装する必要があります。

技術的なヒント: バグはまだプログラムに入り込む可能性があります。詳細については、PLC操作の「最後のラングが優先する」ことを考慮してください。MOTOR_1 などの内部変数を操作する複数のコード行は、予期しない動作を引き起こす可能性があります。明確に言えば、この種のバグはプログラマーにとっては予期しないものであっても、決定論的なものであり、トラブルシューティングは比較的簡単です。

I/Oの名前用の単一の場所

前提となる記事の説明を繰り返すつもりはありません。しかし、プログラムの明快さと、readInputs( )関数(メソッド)やwriteOutputs( )関数(メソッド)と連携した名前付き変数の使用の重要性は強調しすぎることはありません。I/Oリストを統合したXマクロの技法は、プログラミングを適切に行うための重要な要素です。バグを防ぐために、PB_STARTやMOTOR_1などの変数を一度だけ定義します。そして、ポートの初期化と読み込みのルーチン作業を自動化します。

技術的なヒント: プログラミングの教科書に記載されているにもかかわらず、PLCのプログラミングではグローバル変数が使用されます。 メインループの煩雑さが軽減されることが、グローバル変数を採用する大きな理由です。心配しないでください。グローバル変数は通常、I/Oに関連して「控えめに」使用されています。

次のステップ

PLCとC言語プログラミングの詳細については、以下を参照してください。

  • PLCアプリケーションの寿命は数十年単位であることを理解し、コードのライフサイクルを振り返ってください。自分自身の理解と、PLCを保守する将来の技術者やコードを修正する将来のエンジニアのニーズのバランスを取ってください。

  • IEC 61131-3のプログラム言語を学び、望ましいコード構造と技法を確認してください。最善の方法をC言語プログラミングに取り入れてください。

  • 組み込みアプリケーションのスタイルガイドを作成し、継続的に改善してください。

  • タイマを追加してください。この記事では、ストラクチャードテキストを応用した技法を紹介しています。

おわりに

サイクルスキャンはPLCプログラミングの確実な機能です。I/Oを直接操作しないというスナップショットモデルは、予期しないバグを防ぐのに大いに役立ちます。また、プログラムをクリーンアップし、読みやすく保守しやすくします。

もう一度、IEC 61131-3言語とその固有のトラブルシューティングツールの威力を指摘したいと思います。IEC 61131-3のプログラミング言語は、システムのトラブルシューティングに必要なプログラミング経験のレベルを緩和します。機器の故障は避けられませんが起こった場合、収益に深刻な影響を与える可能性があります。一方、C言語や派生する高級言語は、ネットワークの観点からは簡単かもしれませんが、従来のPLCでDockerを搭載しているものはあまりありません。

ご健闘をお祈りします。

APDahlen

関連情報

関連する有益な情報については、以下のリンクを参照してください。

著者について

Aaron Dahlen氏、LCDR USCG(退役)は、DigiKeyでアプリケーションエンジニアを務めています。彼は、技術者およびエンジニアとしての27年間の軍役を通じて構築されたユニークなエレクトロニクスおよびオートメーションのベースを持っており、これは12年間教壇に立ったことによってさらに強化されました(経験と知識の融合)。ミネソタ州立大学Mankato校でMSEEの学位を取得したDahlen氏は、ABET認定EEプログラムで教鞭をとり、EETプログラムのプログラムコーディネーターを務め、軍の電子技術者にコンポーネントレベルの修理を教えてきました。彼はミネソタ州北部の自宅に戻り、このような記事のリサーチや執筆を楽しんでいます。




オリジナル・ソース(English)