[[PageOutline]] = Yokogawa SMARTDAC+(GM/GPシリーズ)でのIOC作成 = [https://www.yokogawa.co.jp/solutions/services/oprex/oprex-measurement/oprex-data-acquisition/data-logger/modular-gm10/ Yokogawa SMARTDAC+(GMシリーズ)]用のIOCを立て続けに作ることになったので、その時の色々な経緯を書いておく。[[br]] どちらのシリーズも、GX90xxのモジュールを使うので、その参考になれば幸いである。[[br]] == cERLでMV2000をGP20に置き換え == cERLで使用していたMV2000は、IOCを落とすと本体の電源をON/OFFしない限り、IOCとの再接続ができないという問題を抱えていた。[[br]] 常時温度監視をするために使用していたので通常は問題ないが、何かの拍子にIOCが落ちたりすると、電源ON/OFFの事を忘れていたためにデータが取れていないということが何回かあったので、運転終了後に入れ替えることになった。[[br]] 候補としては、[https://www.chino.co.jp/ Chino]の[https://www.chino.co.jp/products/recorders/kr3000/ kr3000]等も考えたが、他の所で[https://www-linac.kek.jp/cont/epics/netdev/ netDev]のdarwinプロトコルを使用することでデータが取れることを聞いていたので、今回は[https://www.yokogawa.co.jp/solutions/services/oprex/oprex-measurement/oprex-data-acquisition/portable-data-acquisition/touch-screen-gp10-gp20/ Yokogawa GP20]を使用することにした。 測定ch構成は、 * 温度測定 48ch * 1~12 ch [https://www.chino.co.jp/products/sensors/r800/ chino 極低温工業用白金・コバルト測温抵抗体] * 13~48ch T型熱電対(銅コンスタンタン) * Alarm接点出力 なし 測温抵抗体は、測定電圧を変換表で換算することで温度を計算する仕様になっている。[[br]] この話は今回の本題ではないので割愛。 == netDev + Darwin == 始めにnetDevを環境にインストールする。[[br]] 今回は、[https://www-linac.kek.jp/cont/epics/netdev/]から1.0.4を取ってきた。(終わってから、J-PARCの山田さんが[https://github.com/shuei/netDev netDev 1.0.5]を作っていたことを知った。)[[br]] === netDevのインストール === {{{ $ cd インストールディレクトリ $ wget https://www-linac.kek.jp/cont/epics/netdev/netDev-1.0.4.tar.gz $ tar zxvf netDev-1.0.4.tar.gz $ mv netDev-1.0.4 1.0.4 $ cd 1.0.4 $ emacs -nw configure/RELEASE EPICS_BASE=/cerl/epics/R315.5/base $ make }}} === IOC === 実際にIOCを作成するにあたり、netDev上のdarwin プロトコルでの使用例が直には見つからなかった。[[br]] 冷凍機グループの中西さんが使っていると聞いていたので、使用しているレコードをサンプルとしてもらってきた。[[br]] そのサンプルを元に作成したDBファイル。 {{{ # Yokogawa GP10 Channel 001 ~ 050 record(channels, "$(USER):$(MODEL):VOL:CH001_050") { field(SCAN, "$(SCAN)") field(DTYP, "Darwin") field(NELM, "50") field(INP, "@$(IP)($(PORT))#001,050") # @IP(port)#CHs~CHe } }}} {{{$(PORT)}}}番号は{{{34151}}}で固定だが、{{{$(IP)}}}と共にst.cmdで指定するようにした。[[br]] ソースコードを確認したところ、{{{channels}}}レコードは最大チャネル数は90chだったので、1レコードで取得できるのはこれが最大らしい。[[br]] 各チャネルのデータは{{{CHxx}}}フィールドから個別に取得できるようになるので、通常は他のレコードにリンクして使用する。 実際にIOCを作る際には他のモジュールと同様に、{{{configure/RELEASE}}}と{{{xxxApp/src/Makefile}}}を修正する。 * configure/RELEASE {{{ : NETDEV=$(EPICS_BASE)/../modules/soft/netDev/1.0.4 : }}} * xxxApp/src/Makefile {{{ : ifneq ($(NETDEV),) xxxx_DBD += netDev.dbd xxxx_LIBS += netDev endif : }}} st.cmdにはiocInitの後で、[[br]] {{{ dbpf "$(USER):$(MODEL):VOL:CH001_050.MODE" "EL" }}} とすることで、各chの設定を読み込んでレコードに設定する。[[br]] この方法でGP20(50ch)は、問題なく通信できている。 == PF-AR RF温度測定システムの更新 == GP20のIOCは、更に多チャンネルを扱う、こちらの案件のための実験も兼ねていた。[[br]] チャネル数は、{{{analog 140ch + DIO 6ch}}} と {{{analog 80ch + DIO 3ch}}} なので、{{{netDev + darwin}}}の最大チャネル数を超えている。[[br]] HWも拡張モジュールを使用しないと対応できないので、subユニットを2つ追加する構成にした。[[br]] 当初考えていたHW構成は、 || slot || 1 || 2 || 3 || 4 || 5 || 6 || 7 || || Main || CPU || DO || AI || AI || AI || AI || EXT || || Sub1 || EXT || AI || AI || AI || AI || AI || EXT || || Sub2 || EXT || AI || AI || AI || AI || AI || - || GMのWeb画面から、通信(イーサネット)設定->サーバ設定 サーバリスト->DARWIN->チャネル変換→拡張タイプを設定した。[[br]] とりあえず、一番最後のchに熱電対を取り付けて実験してみた。 === netDev + darwinでの実験 === 1チャネルの数を増やさなくても、ユニット毎にレコードを設定すればデータの取得が可能なのではないかと考えた。 {{{ record(channels, "$(user):GM:CH001050") { field(SCAN, "$(SCAN)") field(DTYP, "Darwin") field(INP, "@$(IP)($(PORT))#001,050") # @IP(port)#CHs~CHe field(NELM, "50") field(FLNK, "$(user):GM:CH100150") } record(channels, "$(user):GM:CH100150") { field(DTYP, "Darwin") field(INP, "@$(IP)($(PORT))#100,150") # @IP(port)#CHs~CHe field(NELM, "50") } }}} エラーにはなるが、最後の熱電対のデータが取れているので、複数レコードでも通信自体はできているようだ。[[br]] その後色々デバッグしてみるが、どうしても140ch分のデータが出てこない。[[br]] tcpdumpでELコマンド(EL001,250)の出力を見てみると、 {{{ 001 C ,1 002 C ,1 003 C ,1 004 C ,1 005 C ,1 006 C ,1 007 C ,1 008 C ,1 009 C ,1 010 C ,1 : 049 C ,1 050 C ,1 101 C ,1 102 C ,1 : 149 C ,1 E150 C ,1 }}} となっていた。[[br]] ch番号を色々と変更しても、このch番号のデータに変化はない。 HW構成を色々と変えてみて、変化を確認してみた。 * DO moduleなし * 変わらず || slot || 1 || 2 || 3 || 4 || 5 || 6 || 7 || || main || CPU || AI || AI || AI || AI || - || EXT || || sub1 || EXT || AI || AI || AI || AI || AI || EXT || || sub2 || EXT || AI || AI || AI || AI || AI || - || * DO moduleなし,EXT module変更 * 変わらず || slot || 1 || 2 || 3 || 4 || 5 || 6 || 7 || || main || CPU || AI || AI || AI || AI || EXT || - || || sub1 || EXT || AI || AI || AI || AI || AI || EXT || || sub2 || EXT || AI || AI || AI || AI || AI || - || * sub1,sub2なし * サーバー設定 サーバーリストのDarwin設定をstandaloneに設定すると40chが見えた。 * 設定を変更しないとエラー(E1) || slot || 1 || 2 || 3 || 4 || 5 || 6 || 7 || || main || CPU || AI || AI || AI || AI || - || - || * DOユニットなし * darwin設定が standaloneままだと40chしか見えない * darwin設定が 拡張設定だと 50ch + 50ch || slot || 1 || 2 || 3 || 4 || 5 || 6 || 7 || || main || CPU || AI || AI || AI || AI || - || EXT || || sub1 || EXT || AI || AI || AI || AI || AI || EXT || || sub2 || EXT || AI || AI || AI || AI || AI || - || このことから、HW構成を変更することで対処しようとすると、 || slot || 1 || 2 || 3 || 4 || 5 || 6 || 7 || || main || CPU || DO || EXT || - || - || - || - || || sub1 || EXT || AI || AI || AI || AI || EXT || - || || sub2 || EXT || AI || AI || AI || AI || AI || EXT || || sub3 || EXT || AI || AI || AI || AI || AI || - || という構成にするしかないようだ。[[br]] 但し、電源とEXTが一つずつ追加することになり、今更変更(追加購入)はしたくない(できない)とのこと。 一応、Yokogawaには問い合わせを行ったが、FWでこの問題を解決しない限り、DARWINプロトコルを使うユーザー側のソフトウェアでの解決できなさそう。[[br]] 結局は仕様ということになりそうだが、今の所{{{netdev+ darwin}}}で動作可能な以下の構成に変更して動作試験をしてみた。[[br]] || slot || 1 || 2 || 3 || 4 || 5 || 6 || 7 || || main || CPU || DO || EXT || - || - || - || - || || sub1 || EXT || AI || AI || AI || AI || EXT || - || || sub2 || EXT || AI || AI || AI || AI || AI || EXT || || sub3 || EXT || AI || AI || AI || AI || AI || - || レコードはこのようなものにした。 {{{ record(channels, "$(user):GM:CH001040") { field(SCAN, "$(SCAN)") field(DTYP, "Darwin") field(INP, "@$(IP)($(PORT))#001,040") # @IP(port)#CHs~CHe field(NELM, "40") field(FLNK, "$(user):GM:CH101150") } record(channels, "$(user):GM:CH101150") { field(DTYP, "Darwin") field(INP, "@$(IP)($(PORT))#101,150") # @IP(port)#CHs~CHe field(NELM, "50") field(FLNK, "$(user):GM:CH201250") } record(channels, "$(user):GM:CH201250") { field(DTYP, "Darwin") field(INP, "@$(IP)($(PORT))#201,250") # @IP(port)#CHs~CHe field(NELM, "50") } }}} st.cmdには、iocInit後に以下のコマンドを実行して、HW設定を読み込ませる。 {{{ dbpf "$(USER):GM:CH001040.MODE" "EL" epicsThreadSleep 1 dbpf "$(USER):GM:CH101150.MODE" "EL" epicsThreadSleep 1 dbpf "$(USER):GM:CH201250.MODE" "EL" }}} epicsThreadSleepを入れないと{{{drvNetMpf: send error [32]}}}が発生する。[[br]] この状態でIOCを起動すると、エラーも出なくなって正常に動作する。 試しに、DO moduleをsub1に移動して、レコードも追加して実行してみた。 || slot || 1 || 2 || 3 || 4 || 5 || 6 || 7 || || main || CPU ||EXT || - || - || - || - || - || || sub1 || EXT || DO || AI || AI || AI || AI || EXT || || sub2 || EXT || AI || AI || AI || AI || AI || EXT || || sub3 || EXT || AI || AI || AI || AI || AI || - || {{{ record(channels, "$(user):GM:CH001006") { field(SCAN, "$(SCAN)") field(DTYP, "Darwin") field(INP, "@$(IP)($(PORT))#001,006") # @IP(port)#CHs~CHe field(NELM, "6") field(FLNK, "$(user):GM:CH011050") } }}} この状態で実行すると、以前と同じでエラーになってしまう。 {{{ drvNetMpf: *** mpf_timeout_handler("michkawa:pfarthrm:GM:CH011050"):2019.07/09 15:42:32.769832 *** drvNetMpf: *** mpf_timeout_handler("michkawa:pfarthrm:GM:CH001006"):2019.07/09 15:42:34.764932 *** parse_chan_response: Data Length dose not match: 8224, 208, 50, 0("michkawa:pfarthrm:GM:CH101150") drvNetMpf: *** mpf_timeout_handler("michkawa:pfarthrm:GM:CH011050"):2019.07/09 15:42:36.761678 *** parse_chan_response: Data Length dose not match: 8224, 208, 50, 0("michkawa:pfarthrm:GM:CH201250") drvNetMpf: *** mpf_timeout_handler("michkawa:pfarthrm:GM:CH001006"):2019.07/09 15:42:38.758844 *** parse_chan_response: Data Length dose not match: 8, 208, 50, 0("michkawa:pfarthrm:GM:CH101150") drvNetMpf: *** mpf_timeout_handler("michkawa:pfarthrm:GM:CH011050"):2019.07/09 15:42:40.755598 *** parse_chan_response: Data Length dose not match: 8224, 208, 50, 0("michkawa:pfarthrm:GM:CH201250") drvNetMpf: *** mpf_timeout_handler("michkawa:pfarthrm:GM:CH001006"):2019.07/09 15:42:42.752343 *** }}} netdev + darwinはDOモジュールには対応していない?[[br]]