Version 2 (modified by michkawa, 11 years ago) (diff) |
---|
T&D TR-73U おんどとり用IOC
今回は、RS-232Cで取得したバイナリデータをStreamDeviceでwaveformとして取得し、sequencerでデータ変換するパターン。
通信マニュアル
- 会社サポートに問い合わせて、パスワードを教えてもらってダウロード
接続
T&D TR-73Uからデータを取得するには、専用の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~データまでの総和
データフォーマットはマニュアルを参照。
protocol file
今回のデータは固定長なので、Max_Inputでデータ長を設定。
ターミネーター、セパレーターは"なし"に設定。
プロトコルファイルは以下の様になる。
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から切り出して、データ用のレコードに設定する。
データ取得用レコードをPROCしてからデータが出力されるまでにタイムラグがあるので、0.5秒待ちを入れる。
データの収集間隔は現在は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") }
Attachments (2)
-
tr73u_com_protocol.pdf
(71.8 KB) -
added by michkawa 11 years ago.
通信プロトコル仕様書
-
TR73U.tar.gz
(5.4 KB) -
added by michkawa 11 years ago.
EPICS IOC
Download all attachments as: .zip