質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

2回答

2449閲覧

SerialPortでコマンドを送受信できない(RS422A)

_iitenki

総合スコア10

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

1クリップ

投稿2022/04/07 06:00

解決したいこと

現在、シリアル通信(伝送コード: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

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ozwk

2022/04/07 06:23 編集

sendData の中身はどうなってます? 多分送りたいのは{0x02,0x4D,0x45,...,0x45,0x03}だとは思いますが そうなってますか?
_iitenki

2022/04/07 06:38

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));で変換したのが間違いなのでしょうか。
ozwk

2022/04/07 06:51

16進数とか10進数とかは表記の問題なので数値的に合っていれば問題はないです。 ところでsport.Write(sendData,0,data.Length); のdataはなんですか? コピペのミスですか?実際そうなってますか?
_iitenki

2022/04/07 06:56

ozwk様 申し訳ありません。コピペのミスになっております。 下記が正しいコードになります。 sport.Write(sendData,0,sendData.Length);
ozwk

2022/04/07 06:59

ボーレートは合ってます?
_iitenki

2022/04/07 07:01

ozwk様 ボーレートは、制御機器とPCをともに9600で設定しております。
ozwk

2022/04/07 07:13 編集

機器の詳細はここに載せられますか? あと、「コピペのミスになっております」とのことですが、 本当にコピーして貼り付けているならそんな器用な間違い方をしないと思うんですが sport.Write(sendData,0,data.Length); で動かしていたとかないですよね? それとも質問文は1文字1文字打ち込み直したんでしょうか?
_iitenki

2022/04/07 07:22

ozwk様 機器は下記になります。  ・CD33-30N-422(オプテックスFA) 本来のコードは、sendDataのところに社内の製品名を用いていましたので、 コピーしてから修正を入れさせて頂きました。
tmp

2022/04/07 07:39

sport.Write(sendData,0,data.Length); のsportは、いつまで有効ですか?それが有効の間に返信が返ってきて受信できますか?
ozwk

2022/04/07 07:43

マニュアル探して見てみました STX"MEASURE"ETX のように2重引用符(0x22)が必要とかないですか?
_iitenki

2022/04/07 07:53

tmp様 sportをDisposeしていないかということでしょうか?
_iitenki

2022/04/07 07:54

ozwk様 メーカー担当者様から 2重引用符は必要ないとの回答を頂いています。
ozwk

2022/04/07 07:59 編集

sportがローカル変数だからクリックイベントを抜けたら破棄されるのではないか ということを言いたいのではないかと思います。
_iitenki

2022/04/07 08:05

ozwk様 >sportがローカル変数だからクリックイベントを抜けたら破棄されるのではないか 送信・受信が完了する前にいクリックイベントが終わっていないかということでしょうか。 上記に関しては、検討ができておりませんでした。 お手数をお掛けしますが、どのようにして検討すればよいか教えて頂きたいです。
ozwk

2022/04/07 08:22

ものすごく単純には、sportをメンバ変数にするか、クリックイベント内でWriteした後ReadLine()で待ちます。
_iitenki

2022/04/07 10:21

ozwk様 Write後にReadLine()を試してみたのですが、何も反応がありませんでした。
ozwk

2022/04/07 11:56

質問文のコードがReadLineだったんでそう書いてしまいましたけど 改行区切りではなさそうなので不適切でした
_iitenki

2022/04/08 06:19

ozwk様 handShakeをRequestToSendに変更したところ、機器との通信が可能になりました。 長時間、お助け頂きありがとうございました。
guest

回答2

0

自己解決

ハンドシェイクをNONEからrequestToSendに変更することで、値を取得することができました。

投稿2022/04/08 10:48

_iitenki

総合スコア10

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

まずは、シリアルポートの出力がきちんと出ているかをチェックしましょう
オシロスコープを用意して、そこんところの波形を見てみよう

投稿2022/04/07 08:07

y_waiwai

総合スコア87747

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問