HIL SCADA ¶
シリアル接続ウィジェット¶
シリアル接続ウィジェットは、カスタム UI 内でシリアル通信リンクを確立するために使用されます。
主な目的は、選択されたCOMポートで、指定されたパラメータを使用してシリアル接続を確立することです。確立された接続は、確立されたシリアル接続オブジェクトを保持する特別な識別子(変数)を介して取得できます。接続オブジェクトは、すべてのマクロおよび式スクリプトから書き込みと読み取りの両方にアクセスできます。
注記
接続オブジェクト自体はクラスのオブジェクトである シリアル()
は、PySerial Pythonライブラリのクラスの一つです。利用可能な関数の詳細については、PySerialのウェブサイト(https://pythonhosted.org/pyserial/pyserial_api.html)。
カスタム UI はマルチスレッド アプリケーションであり、すべての監視ウィジェットはスレッドを使用して定期的にデータを読み取るため、シリアル ポートへの書き込みとシリアル ポートからの読み取りは、書き込み/読み取り操作の重複を防ぐためにスレッド間で同期する必要があります。
この目的のために、シンプルなロック機構が用いられます。シリアルポートへの排他アクセスを必要とする通信シーケンスにおいて、他のスレッドがアクセスできないようにポートをロックするという考え方です。
以下に、シリアル接続ウィジェットの一般的な使用例を示します。
使い方の例¶
まず、シリアル接続ウィジェットのプロパティ ダイアログ内で、必要な接続識別子名を設定します。

指定した名前の識別子は、すべてのマクロおよび式スクリプトで同じ名前の変数として使用できます。この識別子は、クラスの接続オブジェクトを保持します。 シリアル()
このクラスのすべての関数が使用可能になります。
次の 2 つの簡単な方法でポートをロックし、コードをスレッドセーフにすることができます。
専用の接続オブジェクトを使用することができます
ロック()
そしてロック解除()
関数。シリアル接続オブジェクトを呼び出すことによってロック()
関数は、そのシリアルポートを明示的にロックします。ロック後は、シリアルポートへの書き込みと読み取りがスレッドセーフになります。シリアルポートの操作が終わったら、次の関数を呼び出してロックを解除する必要があります。ロック解除()
関数。
注記
ポートがロックされた後は、同じ接続オブジェクトを使用する他のスレッドの速度低下を防ぐために、後続のコードはできるだけ短くする必要があります (シリアル読み取り/書き込み呼び出しのみを含めることが望ましい)。
警告
以前ロックされていたポートを再度ロック解除するには、 ロック解除()
関数。何らかの例外が発生した場合、 ロック解除()
関数を呼び出す必要があります。そのため、Python 試す/最後に
ステートメントを使用する必要があります。
例:
# シリアル接続オブジェクトを使用してポートをロックしますserial_con.lock ( ) # この行から、ロックされたシリアル ポートの使用はスレッドセーフになります# 注: ポートをロックした後、コードはできるだけ短くする必要があります#シリアル ポートからの読み取り/書き込みを試みますtry : # 接続が開かれているかどうかを確認しますif serial_con.isOpen (): # COM ポートに何かを書き込みますserial_con.write ( "RST" ) # 1 行読み取りますdata = serial_con.readline ( )最後に: #ロックを解除する必要があります。そうしないと、ポートは他のスレッドに対してもロックされたままになりますserial_con.unlock ( )
接続オブジェクトの
シリアルロック
属性とPythonと
ステートメントです。この場合、シリアルポートのロックとロック解除、または例外処理を明示的に行う必要はありません。と
ステートメントはそれを自動的に処理します。
例:
# `with` ステートメントのコンテキスト内でシリアルポートを使用したすべてのシリアル読み取り/書き込み操作はスレッドセーフです。 serial_con.serial_lock : #コンテキストの先頭で、'with' ステートメントはシリアルポートを自動的にロックします。 #注 1: 'with' ステートメントは例外発生時にシリアルポートのロックを自動的に解除します。 # 注 2: コンテキスト内のコードはできるだけ短くする必要があります。 # 接続が開かれているかどうかを確認します。 if serial_con.isOpen (): # COM ポートに何かを書き込むserial_con.write ( " RST" ) # 1行読み取りdata = serial_con.readline () # コンテキストの末尾で、'with' ステートメントはシリアルポートのロックを解除します。