Changes between Version 1 and Version 2 of epics/yokogawa/gm_series


Ignore:
Timestamp:
07/17/19 11:29:53 (6 years ago)
Author:
Tetsuya Michikawa
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • epics/yokogawa/gm_series

    v1 v2  
    44
    55[https://www.yokogawa.co.jp/solutions/services/oprex/oprex-measurement/oprex-data-acquisition/data-logger/modular-gm10/ Yokogawa SMARTDAC+(GMシリーズ)]用のIOCを立て続けに作ることになったので、その時の色々な経緯を書いておく。[[br]]
    6 どちらのシリーズも、GX90xxのモジュールを使うので、その参考になれば幸いである。[[br]]
     6どちらのシリーズもGX90xxのモジュールを使い、制御系もほぼ同じ様に使えるので、その参考になれば幸いである。[[br]]
    77
    88== cERLでMV2000をGP20に置き換え ==
     
    9797
    9898GP20のIOCは、更に多チャンネルを扱う、こちらの案件のための実験も兼ねていた。[[br]]
    99 チャネル数は、{{{analog 140ch + DIO 6ch}}} と {{{analog 80ch + DIO 3ch}}} なので、{{{netDev + darwin}}}の最大チャネル数を超えている。[[br]]
     99こちらで使用するチャネル数は、{{{analog 140ch + DIO 6ch}}} と {{{analog 80ch + DIO 3ch}}} なので、{{{netDev + darwin}}}の最大チャネル数を超えている。[[br]]
    100100
    101101HWも拡張モジュールを使用しないと対応できないので、subユニットを2つ追加する構成にした。[[br]]
     
    111111とりあえず、一番最後のchに熱電対を取り付けて実験してみた。
    112112
    113 === netDev + darwinでの実験 ===
     113=== netDev + darwin ===
    114114
    1151151チャネルの数を増やさなくても、ユニット毎にレコードを設定すればデータの取得が可能なのではないかと考えた。
     
    157157
    158158となっていた。[[br]]
    159 ch番号を色々と変更しても、このch番号のデータに変化はない。
     159レコードのINPフィールドのch番号を色々と変更しても、このch番号に変化はない。
    160160
    161161HW構成を色々と変えてみて、変化を確認してみた。
     
    288288
    289289netdev + darwinはDOモジュールには対応していない?[[br]]
     290
     291最終的には設置場所や予算の関係で、当初の構成でないとダメだということになったので、netDev + darwin を諦めて、modbusで実装することにした。
     292
     293=== modbus ===
     294
     295以前modbusを使ったIOCを作成しようとしたが、色々と知識不足で断念した経緯があった。[[br]]
     296
     297modbusモジュールをPF EPICS環境にインストール。
     298
     299{{{
     300[epics@pfrproc1 ~]$ cd /pf/epics/R315.5/modules/soft/
     301[epics@pfrproc1 soft]$ mkdir modbus
     302[epics@pfrproc1 soft]$ cd modbus/
     303[epics@pfrproc1 modbus]$ wget https://github.com/epics-modules/modbus/archive/R2-10-1.tar.gz
     304[epics@pfrproc1 modbus]$ tar zxvf R2-10-1.tar.gz
     305[epics@pfrproc1 modbus]$ mv modbus-R2-10-1 2-10-1
     306[epics@pfrproc1 modbus]$ cd 2-10-1
     307[epics@pfrproc1 2-10-1]$ emacs -nw configure/RELEASE
     308
     309#SUPPORT=/corvette/home/epics/devel
     310#-include $(TOP)/../configure/SUPPORT.$(EPICS_HOST_ARCH)
     311
     312#ASYN=$(SUPPORT)/asyn-4-31
     313ASYN=$(EPICS_BASE)/../modules/soft/asyn/4-31/
     314
     315#EPICS_BASE=/corvette/usr/local/epics-devel/base-3.15.5
     316EPICS_BASE=/pf/epics/R315.5/base
     317
     318[epics@pfrproc1 2-10-1]$ make
     319}}}
     320
     321次にiocを作成した。[[br]]
     322modbusはasynPortDriverを使うようなので、asynも有効にする。
     323
     324{{{
     325[michkawa@pfrproc6 ~]$ mkdir -p epics/modbus/pfarthrm/
     326[michkawa@pfrproc6 ~]$ cd epics/modbus/pfarthrm/
     327[michkawa@pfrproc6 pfarthrm]$ makeBaseApp.pl -t pfModules pfarthrm
     328[michkawa@pfrproc6 pfarthrm]$ makeBaseApp.pl -i -t pfModules pfarthrm
     329[michkawa@pfrproc6 pfarthrm]$ emacs -nw configure/RELEASE
     330
     331ASYN   = $(EPICS_BASE)/../modules/soft/asyn/4-31
     332#STREAM = $(EPICS_BASE)/../modules/soft/stream/2-7-7
     333MODBUS  = $(EPICS_BASE)/../modules/soft/modbus/2-10-1
     334
     335EPICS_BASE = /pf/epics/R315.5/base
     336}}}
     337
     338src/Makefileには、
     339
     340{{{
     341    ifneq ($(MODBUS),)
     342        pfarthrm_DBD += modbusSupport.dbd
     343        pfarthrm_LIBS += modbus
     344    endif
     345}}}
     346
     347を追加して、asynで必要なdriverを設定する。
     348今回は{{{IPPort}}}ドライバなので、
     349
     350{{{
     351    pfarthrm_DBD += drvAsynIPPort.dbd           # IP Port Driver
     352}}}
     353を設定。
     354
     355dbファイルは、普通のasynPortDriverの書き方。
     356
     357{{{
     358record(ai, "$(R)") {
     359    field(DTYP, "asynFloat64")
     360    field(INP,  "@asyn($(PORT) $(OFFSET))$(TYPE)")
     361    field(SCAN, "1 second")
     362    field(FLNK, "$(FLNK)")
     363}
     364}}}
     365
     366ややこしいのがst.cmdの書き方で、{{{drvModbusAsynConfigure}}}を使って、アクセスするレジスタや範囲、型を指定する方法らしい。
     367
     368[https://cars9.uchicago.edu/software/epics/modbusDoc.html#Creating_a_modbus_port_driver Creating a modbus port driver]
     369
     370更に話がややこしいのが、GM用のmodbusレジスタの設定。
     371
     372[https://web-material3.yokogawa.com/IM04L55B01-01JA.pdf?_ga=2.35954336.1696056082.1563237256-1465924258.1537346367 データアクイジションシステム GM ユーザーズマニュアル ]
     373
     374マニュアルを見れば一応書いてはあるが、マニュアル中のレジスタマップにあるレジスタ番号をそのまま使うのではなく、レジスタマップの一番最初の数値をオフセットとして引いた値をアドレスとして使用する必要がある。[[br]]
     375始めは、レジスタ値をそのまま書いていたが、アドレス設定が16bit分しかないのに何でマニュアルのアドレス値がそれをオーバーしているのかが不思議だった。結局マニュアルをしっかり読めということだ。[[br]]
     376
     377この2つの設定のどことどこが対応するかを理解するまでが苦労した。[[br]]
     378
     379実際の例として、今回の構成で各モジュールへのレジスタへアクセスするには、以下の様に設定する。
     380
     381
     382|| slot || 1    || 2    || 3    || 4    || 5    || 6    || 7   ||
     383|| Main || CPU  || DO   || AI   || AI   || AI   || AI   || EXT ||
     384|| Sub1 || EXT  || AI   || AI   || AI   || AI   || AI   || EXT ||
     385|| Sub2 || EXT  || AI   || AI   || AI   || AI   || AI   || -   ||
     386
     387mainの3番モジュール(AI)
     388
     389 * db(template)
     390{{{
     391record(ai, "$(R)") {
     392    field(DTYP, "asynFloat64")
     393    field(INP,  "@asyn($(PORT) $(OFFSET))$(TYPE)")
     394    field(SCAN, "1 second")
     395    field(FLNK, "$(FLNK)")
     396}
     397}}}
     398
     399 * db(substitutions)
     400{{{
     401file "db/Ykgw_GM_ai.template" {
     402    pattern { R,                   PORT,         OFFSET,  TYPE,          FLNK }
     403            {"RFA:ARE:GM90:0101", "GM_E1_A1_2",  0,       "FLOAT32_LE", "RFA:ARE:GM90:CAV1:WTMPIN"}
     404            {"RFA:ARE:GM90:0102", "GM_E1_A1_2",  2,       "FLOAT32_LE", "RFA:ARE:GM90:CAV1:WTMPO"}
     405            {"RFA:ARE:GM90:0103", "GM_E1_A1_2",  4,       "FLOAT32_LE", "RFA:ARE:GM90:CAV1:CTMP"}
     406            {"RFA:ARE:GM90:0104", "GM_E1_A1_2",  6,       "FLOAT32_LE", "RFA:ARE:GM90:MASK_SIC:WTMPIN"}
     407            {"RFA:ARE:GM90:0105", "GM_E1_A1_2",  8,       "FLOAT32_LE", "RFA:ARE:GM90:MASK_SIC:WTMPO"}
     408            {"RFA:ARE:GM90:0106", "GM_E1_A1_2",  10,      "FLOAT32_LE", "RFA:ARE:GM90:MASK:WTMPO"}
     409            {"RFA:ARE:GM90:0107", "GM_E1_A1_2",  12,      "FLOAT32_LE", "RFA:ARE:GM90:CAV2:WTMPIN"}
     410            {"RFA:ARE:GM90:0108", "GM_E1_A1_2",  14,      "FLOAT32_LE", "RFA:ARE:GM90:CAV2:WTMPO"}
     411            {"RFA:ARE:GM90:0109", "GM_E1_A1_2",  16,      "FLOAT32_LE", "RFA:ARE:GM90:CAV2:CTMP"}
     412            {"RFA:ARE:GM90:0110", "GM_E1_A1_2",  18,      "FLOAT32_LE", ""}
     413                   :
     414}}}
     415
     416 * st.cmd
     417{{{
     418drvAsynIPPortConfigure ("$(DEV)", "172.28.14.101:502")
     419modbusInterposeConfig("$(DEV)", 0, 1000,0)
     420drvModbusAsynConfigure("GM_E1_A1_2", "$(DEV)",  1, 4,  1100, 20,  7,  1000, "GM_E1")
     421}}}
     422
     423この設定で必要なのは、
     424 * {{{drvModbusAsynConfigure}}}の4番目の引き数{{{4}}}を、マニュアルのファンクションコードに合わせること
     425 [[Image(GM_function_table.png,400)]]
     426 * {{{drvModbusAsynConfigure}}}の5番目の引き数{{{1100}}}は、レジスタマップを参照することになるが、今回例示するモジュールのレジスタは、下図の{{{チャネル0101のデータの下位ワード - 0x400001}}}なので、{{{1100}}}を設定する
     427
     428 [[Image(GM_modbus_addr_table.png,400)]]
     429 * modbusのデータは16bit単位なので、連続するアドレスにアクセスして32bit浮動小数点に分解する場合には2bitずつoffsetを設定し、アクセスするデータ長も2倍で設定する。({{{drvModbusAsynConfigure}}}の6番目の引き数{{{20}}})
     430 * {{{drvModbusAsynConfigure}}}の7番目の引き数{{{7}}}は、modbus device support の{{{FLOAT32_LE}}}を表していて、DBファイルのINPフィールドの{{{$(TYPE)}}}の部分と合わせる必要がある。