= T&D TR-73U おんどとり用IOC = 今回は、RS-232Cで取得したバイナリデータをStreamDeviceでwaveformとして取得し、sequencerでデータ変換するパターン。 == 通信マニュアル == * 会社サポートに問い合わせて、パスワードを教えてもらってダウロード == 接続 == [http://www.tandd.co.jp/product/dataloggers/tr73u/ T&D TR-73U]からデータを取得するには、[http://www.tandd.co.jp/product/dataloggers/tr73u/option.html 専用のRS-232Cケーブル(TR-07C)]で接続する必要がある。そこから先はいつも通りのMOXAのEther-Serialコンバータで接続する。 || baud rate || 19200 || || parity || none || || data bits || 8 || || stop bits || 1 || || flow ctrl || none || == 通信フォーマット == 現在値のデータを取得するコマンドだけを実装する。 データはlittle endian * 測定値要求コマンド 送信 || 項目名 || サイズ(byte) || 説明 || || SOH || 1 || 0x01固定 || || コマンド || 1 || || || コマンド予備 || 1 || || || データ長 || 2 || データの長さ || || データ || 4~ || || || SUM || 2 || チェックSUM SOH~データまでの総和 || 受信 || 項目名 || サイズ(byte) || 説明 || || SOH || 1 || 0x01固定 || || コマンド || 1 || || || 応答コード || 1 || ACK(0x06),etc || || データ長 || 2 || データの長さ || || データ || 0~ || || || SUM || 2 || チェックSUM SOH~データまでの総和 || データフォーマットは[wiki:Epics/tandd/manual マニュアル]を参照。 == protocol file == 今回のデータは固定長なので、Max_Inputでデータ長を設定。[[br]] ターミネーター、セパレーターは"なし"に設定。[[br]] プロトコルファイルは以下の様になる。 {{{ Terminator = ""; # setWakeup { out 0x00; } getData { ExtraInput = Ignore; InTerminator = ""; ReplyTimeout = 3000; MaxInput = 26; separator = ""; out 0x01 0x33 0x00 0x04 0x00 0x00 0x00 0x00 0x00 0x38 0x00; in "%0r"; @replytimeout{;} } }}} '''%0r'''のところをwaveformとして取り込んで、sequenceで処理する。 == sequence file == 必要なデータをwaveformから切り出して、データ用のレコードに設定する。[[br]] データ取得用レコードをPROCしてからデータが出力されるまでにタイムラグがあるので、0.5秒待ちを入れる。[[br]] データの収集間隔は現在は5秒に設定。 {{{ program sncTR73U unsigned char wfByte[26]; assign wfByte to "{user}:getData"; int wfProc; assign wfProc to "{user}:getData.PROC"; float vals[3]; assign vals[0] to "{user}:getTemperature"; assign vals[1] to "{user}:getHumidity"; assign vals[2] to "{user}:getPressure"; int wkup; assign wkup to "{user}:wakeup"; int ack; int i; int hsbIndex; int lsbIndex; /*unsigned short chkSum;*/ unsigned int shtVal; float calcVal; ss sncTR73U { state init { when () { } state getData } state getData { when (delay(5)) { wkup = TRUE; pvPut(wkup, SYNC); } state setWakeup } state setWakeup { when (pvPutComplete(wkup)) { for(i=0 ; i<26 ; i++) { wfByte[i] = 0; } wfProc = 1; pvPut(wfProc); } state waitGetData } state waitGetData { when (delay(0.5)) { pvGet(wfByte); ack = wfByte[2]; } state calcData when (delay(3)) { printf("Read Timeout\n"); } state getData } state calcData { when (ack == 0x06) { for(i=0, hsbIndex=5, lsbIndex=6 ; i<3 ; i++, hsbIndex+=2, lsbIndex+=2) { shtVal = (wfByte[hsbIndex] | (wfByte[lsbIndex] << 8)); calcVal = shtVal; if(i != 2) { calcVal -= 1000; } vals[i] = calcVal / 10.0; printf("Calc Val: vals[%d]=%.1f\n", i, vals[i]); pvPut(vals[i]); } } state getData when (ack == 0x00) { } state getData } } }}} == db file == {{{ record(bo, "$(user):wakeup") { field(DESC, "Set wakeup device") field(DTYP, "stream") field(OUT, "@TR73U.proto setWakeup $(DEV)") } record(waveform, "$(user):getData") { field(DESC, "Get data binary") field(DTYP, "stream") field(INP, "@TR73U.proto getData $(DEV)") field(NELM, "26") field(FTVL, "UCHAR") } record(ai, "$(user):getTemperature") { field(DESC, "Get temperature") field(EGU, "degC") field(PREC, "1") } record(ai, "$(user):getHumidity") { field(DESC, "Get humidity") field(EGU, "percent") field(PREC, "1") } record(ai, "$(user):getPressure") { field(DESC, "Get atmosphere pressure") field(EGU, "hPa") field(PREC, "1") } }}}