解決したいこと
現在、シリアル通信(伝送コード:ASCII,データ区分:STX・ETX)を用いて機器の制御を行うとしています。
制御コードを作成したのですが、コマンドを送信したのにも関わらず、DataReceivedイベントが発生しません。
送受信あるいはどこに問題があるのか分からない状態です。
(VisualStudioのデバッグモードを使い、Writeまでエラーが出ないのは確認しています。)
解決の糸口を教えて頂きたいです。
通信機器専用ソフトでは、動作することを確認できています。
該当のソースコード
C#
1 public SerialPort CreatePort(string com,Property prop) 2 { 3 //シリアルポートの設定 4 SerialPort sport = new SerialPort() 5 { 6 PortName = com, 7 DataBits = 8,//データビット(通常、ASCIIコードは8ビット) 8 Parity = Parity.None,//パリティ 9 StopBits = StopBits.One,//ストップビット 10 Handshake = Handshake.None,//ハンドシェイク 11 Encoding = Encoding.ASCII,//テキストの伝送前変換と伝送後変換のバイト エンコーディングを取得または設定します。 12 WriteTimeout = prop.WriteTimeOut,//書き込みタイムアウト 13 ReadTimeout = prop.ReadTimeOut,//読み取りタイムアウト 14 NewLine = "\r\n",//ReadLine() メソッドと WriteLine(String) メソッドの呼び出しの末尾を解釈する際に使用する値を取得または設定します。 15 RtsEnable = false, 16 DtrEnable = false 17 }; 18 sport.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); 19 sport.ErrorReceived += Sport_ErrorReceived;// 20 // シリアルポートに接続 21 22 return sport; 23 } 24 25 //この関数内でオープン ⇒ 送信 26 private void button_Click(object sender, EventArgs e) 27 { 28 SerialPort sport = CreatePort("COM1",prop)//prop = 自作クラス 29 sport.Open();//ポートオープン 30 string txt = "MEASURE"; 31 //アスキー文字に変換 32 //MEASURE ⇒ 4D45415355524503 33 string txt_ASCII = ConvertToASCII(txt); 34 35 string command = $"02{txt_ASCII}03"; 36 var tmp = command.Split('-').Select(hex => Convert.ToByte(hex, 16)); 37 byte[] sendData = tmp.ToArray(); 38 sport.Write(sendData,0,data.Length); 39 } 40 41 public void DataReceivedHandler(object sender,SerialDataReceivedEventArgs e) 42 { 43 SerialPort sport = (SerialPort)sender; 44 45 if (!sport.IsOpen)//ここにブレークポイントを設置しても捕まらない 46 { 47 MessageBox.Show("ポートが開かれていません。"); 48 return; 49 } 50 else 51 { 52 string data = String.Empty; 53 54 try 55 { 56 data = sport.ReadLine(); 57 } 58 catch (Exception ex) 59 { 60 MessageBox.Show(ex.Message); 61 } 62 MessageBox.Show(data); 63 } 64 }
試したこと
送信時のコマンドをWrite(string command)で試したのですが、同様の結果でした。
補足情報(FW/ツールのバージョンなど)
VisualStudio2017
sendData の中身はどうなってます?
多分送りたいのは{0x02,0x4D,0x45,...,0x45,0x03}だとは思いますが
そうなってますか?
ozwk様
sendDataの中身は、下記のようになっております。
[0]=2,[1]=77,[2]=69,[3]=65,[4]=83,[5]=85,[6]=82,[7]=69,[7]=3
ConvertToASCII(txt)で16進数に変換したものを
さらにommand.Split('-').Select(hex => Convert.ToByte(hex, 16));で変換したのが間違いなのでしょうか。
16進数とか10進数とかは表記の問題なので数値的に合っていれば問題はないです。
ところでsport.Write(sendData,0,data.Length); のdataはなんですか?
コピペのミスですか?実際そうなってますか?
ozwk様
申し訳ありません。コピペのミスになっております。
下記が正しいコードになります。
sport.Write(sendData,0,sendData.Length);
ボーレートは合ってます?
ozwk様
ボーレートは、制御機器とPCをともに9600で設定しております。
機器の詳細はここに載せられますか?
あと、「コピペのミスになっております」とのことですが、
本当にコピーして貼り付けているならそんな器用な間違い方をしないと思うんですが
sport.Write(sendData,0,data.Length);
で動かしていたとかないですよね?
それとも質問文は1文字1文字打ち込み直したんでしょうか?
ozwk様
機器は下記になります。
・CD33-30N-422(オプテックスFA)
本来のコードは、sendDataのところに社内の製品名を用いていましたので、
コピーしてから修正を入れさせて頂きました。
sport.Write(sendData,0,data.Length);
のsportは、いつまで有効ですか?それが有効の間に返信が返ってきて受信できますか?
マニュアル探して見てみました
STX"MEASURE"ETX
のように2重引用符(0x22)が必要とかないですか?
tmp様
sportをDisposeしていないかということでしょうか?
ozwk様
メーカー担当者様から
2重引用符は必要ないとの回答を頂いています。
sportがローカル変数だからクリックイベントを抜けたら破棄されるのではないか
ということを言いたいのではないかと思います。
ozwk様
>sportがローカル変数だからクリックイベントを抜けたら破棄されるのではないか
送信・受信が完了する前にいクリックイベントが終わっていないかということでしょうか。
上記に関しては、検討ができておりませんでした。
お手数をお掛けしますが、どのようにして検討すればよいか教えて頂きたいです。
ものすごく単純には、sportをメンバ変数にするか、クリックイベント内でWriteした後ReadLine()で待ちます。
ozwk様
Write後にReadLine()を試してみたのですが、何も反応がありませんでした。
質問文のコードがReadLineだったんでそう書いてしまいましたけど
改行区切りではなさそうなので不適切でした
ozwk様
handShakeをRequestToSendに変更したところ、機器との通信が可能になりました。
長時間、お助け頂きありがとうございました。

回答2件
あなたの回答
tips
プレビュー