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

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

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

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

シリアルポート

シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

Q&A

解決済

2回答

5746閲覧

[C#]シリアル通信で複数機器からのデータをさばきたい

entaro12345

総合スコア75

C#

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

シリアルポート

シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

0グッド

0クリップ

投稿2020/04/17 02:27

編集2020/04/17 04:07

前提・実現したいこと

PCのUSBに接続してシリアル通信するプログラム(C#、Form)を実装しています。
特定の機器(1台)からの通信ではなく、多数の機器からのデータ受信を処理しなくてはいけません。
ただ、現状のソースコードではうまくデータ処理ができないような気がしているのですが、
どのように修正すればいいのかわからないのでお力を貸していただきたいです。

※現時点で、検証するにも機器が1台しかないので、複数台稼働時の検証ができないのですが、
その時に備えたいと考えております。

※※現時点で、1台のみの処理は問題なく動作しています。

追記:
下記のソースコードの☆☆部分に送信元へデータを返す処理があるのですが、
その部分が多数の機器の場合に違う機器へ返してしまう可能性を恐れています。

該当のソースコード

c#

1private void SerialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) 2{ 3 if (serialPort != null && serialPort.IsOpen) 4 { 5 try 6 { 7 // 受信データを読み込む 8 SerialPort sp = (SerialPort)sender; 9 string sChildData = sp.ReadExisting(); 10 // 改行を削除 11 sChildData = sChildData.Replace("\r\n", ""); 12 13 if (17 < sData.Length) { 14 sData = sData.Substring(sData.Length - 18, 18); 15 if (string.IsNullOrEmpty(sBefData) || sBefData != sData) 16 { 17 // サーバーへ受信データを流す 18 for (int i = 0; i < 4; i++) 19 { 20 // 渡すデータ部分(後ろ18桁)を取得 21 iSeq++; 22 var parameters = new Dictionary<string, string>() 23 { 24 { "data", sData }, 25 { "sqno", iSeq.ToString() }, 26 }; 27 var content = new FormUrlEncodedContent(parameters); 28 29 try { 30 sTargetName = sData.Substring(0, 4); 31 sReturnVal = GetResponseAPI(API_PATH + API_SEND_DATA, content); 32 // 画面へ受信データを出力 33 this.Invoke(new Action<string>(this.appendText), DateTime.Now + " " + sData + Environment.NewLine); 34 sBefData = sData; 35 break; 36 } catch { 37 this.Invoke(new Action<string>(this.appendText), DateTime.Now + " " + "失敗しました" + Environment.NewLine); 38 } 39 try { 40 // ☆☆送信元の機器へsReturnValのデータを送信する 41 } catch { 42 } 43 44 } 45 46 sData = string.Empty; 47 sReturnVal = string.Empty; 48 } 49 } 50 } 51 catch (Exception ex) 52 { 53 logger.Error(ex.Message); 54 } 55 } 56} 57 58private string GetResponseAPI(string sApiUrl, FormUrlEncodedContent sContent) 59{ 60 string sVal = string.Empty; 61 var task = Task.Run(() => { 62 return HttpPost(sApiUrl, sContent); 63 }); 64 string response = task.Result; 65 JArray data = (JArray)JsonConvert.DeserializeObject(response); 66 foreach (JObject obj in data) 67 { 68 JValue val = (JValue)obj["return_data"]; 69 sVal = (string)val.Value; 70 this.Invoke(new Action<string>(this.appendText), DateTime.Now + " ReturnData:" + sVal + Environment.NewLine); 71 } 72 73 return sVal; 74}

補足情報(FW/ツールのバージョンなど)

Windows 10
Visual Studio 2017
c#/Windows Form/.Net Framewrok 4.7.1

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

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

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

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

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

dodox86

2020/04/17 03:03

> ただ、現状のソースコードではうまくデータ処理ができないような気がしているのですが、 > どのように修正すればいいのかわからないのでお力を貸していただきたいです。 質問者さんとしてどこがまずい気がしているのか、最終的にどうしたいのかが分からないと、回答者側からどのように修正すればとの提言もできないと思います。低評価は私がしたものではありませんが、そういったところが低評価につながったものと思われます。 > 機器が1台しかないので、複数台稼働時の検証ができないのですが、 そういった場合は対象機器のシミュレータ(想定するデータの送受信ができるもの)を自分で作って対抗させます。そうでないと実機をいきなりつなげても、自由にデバッグできませんよね。 シリアルポートが無くてできないという場合は、仮想シリアルポートを増やすソフトもあります。"com0com"で検索してみてください。http://com0com.sourceforge.net/
entaro12345

2020/04/17 04:07

アドバイス等ありがとうございます。 懸念している点については、追記いたしました。
guest

回答2

0

ベストアンサー

下記のソースコードの☆☆部分に送信元へデータを返す処理があるのですが、
その部分が多数の機器の場合に違う機器へ返してしまう可能性を恐れています。

受信に際してデリゲートのSerialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)を使われているわけですが、この引数のobject sender はご自身のコードでSerialPort sp = (SerialPort)sender;と取り出しているように、接続先のCOMポートの回線です。
ですので、このspを適切に送信対象に使うかぎり、違う機器へデータを返してしまうことはありません。

SerialDataReceivedEventHandler - System.IO.Ports

投稿2020/04/17 05:07

dodox86

総合スコア9232

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

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

entaro12345

2020/04/17 05:15

ありがとうございます。 違う機器へデータを返してしまうことはないとの回答で安心しました。
dodox86

2020/04/17 05:25

私はあまりこのデリゲートを使わないので未確認ですが、senderは恐らく、SeraiPort.OpenやSendしたときのインスタンスオブジェクトと同じものがきていると思います。たぶん。
guest

0

ふつう、シリアル通信というのは1対1の通信となります
そういうことで、複数の通信相手となると、COMポートを増やしてそれぞれの通信を担当させることとなります。
コード上では、このような場合、SerialPortを複数使って、COM番号でそれぞれの通信の処理を行うことになりますね。

#RS485なんかで、1対多の場合もありますが、それはまたべつのおはなし.

投稿2020/04/17 04:11

編集2020/04/17 04:20
y_waiwai

総合スコア87981

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

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

entaro12345

2020/04/17 05:15

ありがとうございます。 通常1対1なのですね!
dodox86

2020/04/17 05:21

> 通常1対1なのですね! ああ、なるほど。entaro12345さんはそもそも、シリアル通信はLANみたいに1対Nの繋がり方があると思われていたのですね。質問が出た理由のひとつが分かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.39%

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

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

質問する

関連した質問