いつもお世話になります。
設備シーケンサーがRS-232C経由で吐き出すデータをラズベリーパイ3で受け取り、ファイルに書き込む処理を作成しています。
当方の環境はラズベリーパイ3 MODEL B、2017-09-07-raspbian-stretch、python3.5.3となります。
シーケンサーとラズパイはエレコムのUC-SGTと言うUSB・RS232変換ケーブルで接続していて、ケーブルのUSB側をラズパイのUSBに挿しています。UC-SGTはラズパイでは自動的に認識されました。
python3で利用するために/etc/udev/rules.d/99-local.rulesに必要事項を記入して固定して使えるようにしています。
これで連続してシーケンサーからのデータを受信できていますが、ごくまれに以下のような例外エラーが発生いたします。
read failed: device reports readiness to read but returned no data (device disconnected or multiple access on port?) [Errno 2] could not open port /dev/ttyUSB_UC-SGT: [Errno 2] No such file or directory: '/dev/ttyUSB_UC-SGT'
処理プログラムは以下のようになります。
python
1import sys 2import serial 3import time 4import re 5import datetime as dt 6 7def setfilenm(pNow): 8 rFnm = '' #変数初期化 9 #日付の替わる時間 10 dHh = dt.datetime.strptime(str(pNow.year) + '-' + str(pNow.month) + '-' + str(pNow.day) + ' 00:00:00', '%Y-%m-%d %H:%M:%S') 11 #開始日時 12 dSt = dt.datetime.strptime(str(pNow.year) + '-' + str(pNow.month) + '-' + str(pNow.day) + ' 08:00:00', '%Y-%m-%d %H:%M:%S') 13 #終了日時 14 dEd = dt.datetime.strptime(str(pNow.year) + '-' + str(pNow.month) + '-' + str(pNow.day) + ' 21:00:00', '%Y-%m-%d %H:%M:%S') 15 #日付の変更時から朝8時までは前日の夜勤となる 16 if pNow >= dHh and pNow < dSt: 17 #取得日時より1日減算 18 pNow = pNow - dt.timedelta(days=1) 19 rFnm = str(pNow.year) + '-' + str(pNow.month).zfill(2) + '-' + str(pNow.day).zfill(2) + '-Y.CSV' 20 else: 21 # 当日の日勤範囲内であれば日勤となる 22 if pNow >= dSt and pNow < dEd: 23 rFnm = str(pNow.year) + '-' + str(pNow.month).zfill(2) + '-' + str(pNow.day).zfill(2) + '-D.CSV' 24 else: 25 #そうでなければ夜勤となる 26 rFnm = str(pNow.year) + '-' + str(pNow.month).zfill(2) + '-' + str(pNow.day).zfill(2) + '-Y.CSV' 27 28 return rFnm 29 30def recdata(rFn, rDt): 31 # データをファイルに書き込む(追記モード) 32 fs = open(rFn, 'a') 33 fs.write(rDt + '\n') 34 fs.flush() 35 fs.close() 36 37def main(): 38 try: 39 # デバイスIDは固定しておくこと 40 ser = serial.Serial('/dev/ttyUSB_UC-SGT', 9600, timeout=3) 41 time.sleep(2) 42 #print(ser.portstr) 43 44 while 1: 45 # 通信データバッファクリア 46 rStr = '' 47 # シリアル通信でデータを受信 48 rStr = ser.readline() 49 # ヌル文字と改行コードを取り去る 50 rStr = rStr.decode('utf-8').replace('\x00','') 51 rStr = re.sub(r'[\n\r]+','',rStr) 52 #print(len(rStr)) 53 if len(rStr.replace(' ', '')) == 0: 54 continue 55 else: 56 # 作業時刻を取得 57 dNow = dt.datetime.today() 58 # 作業時間を文字列に変換 59 rDT = dt.datetime.strftime(dNow, '%Y-%m-%d %H:%M:%S') 60 # 作業時刻と取得データを連結する 61 rTxt = rDT + ',' + rStr 62 # 読み込んだデータの表示 63 print(rTxt) 64 # 作業時刻よりファイル名を設定 65 fnm = setfilenm(dNow) 66 # データを書き込む 67 recdata(fnm, rTxt) 68 #print(fnm) 69 except KeyboardInterrupt: 70 pass 71 except: 72 # 例外エラーが発生してもエラー内容を記録して処理は続行させる 73 print("例外エラー:", sys.exc_info()[1]) 74 main() 75 76if __name__ == '__main__': 77 main() 78
『例外が発生しても処理を続ける』記述がこれで良いのかはわかりませんが、rStr = ser.readline()でエラーが発生してもその後は復帰し、データは取り続けているいることは確認できています。
エラーの内容からラズパイ側でないかと思い調べましたが解決に至っていません。
エラーの発生するタイミングがランダムであり、それがデータ受信のタイミングであるとうまくありませんので解決策を探しています。お心当たりの情報がありましたらご教授いただきたくよろしくお願いいたします。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/10/13 06:39