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


Ignore:
Timestamp:
07/17/19 11:29:53 (5 years ago)
Author:
michkawa
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)}}}の部分と合わせる必要がある。