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

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

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

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

Q&A

受付中

三菱電機製PLCとのソケット通信

moyashi27371
moyashi27371

総合スコア10

C#

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

3回答

0グッド

1クリップ

13819閲覧

投稿2018/11/03 11:59

前提・実現したいこと

三菱電機製のシーケンサ(Q03UDVCPU)とC#にてソケット通信を行っていますが
うまくいきません。
内臓イーサネットではうまく開通もできなかったのでQJ71E71-100を使用しています。
通信は開通しているのですが、コマンドを送ってもよくわからないのが返ってきてしまいます。
例として
• バイナリコード,3Eフレーム
• アクセス先: 接続局(自局)のQCPU
• コマンド: ワード単位の一括読出し(コマンド: 0401)
• デバイス: M100~M131(2ワード分)
を設定しています

発生している問題・エラーメッセージ

B5-5B-80-C0-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00

該当のソースコード

C#

1using System; 2using System.Text; 3using System.Net.Sockets; 4using System.Net; 5 6namespace PLCConnect 7{ 8 class Program 9 { 10 static void Main(string[] args) 11 { 12 Console.WriteLine("キーを押下で送信処理"); 13 Console.WriteLine("サーバーがすでに待機していることが条件"); 14 Console.ReadLine(); 15 16 17 try 18 { 19 //IPアドレスとポート番号を指定 20 IPAddress ipAddress = IPAddress.Parse("192.168.100.4"); 21 int port = 2000; 22 23 //シーケンサと接続 24 TcpClient client = new TcpClient(); 25 client.Connect(ipAddress, port); 26 27 if (client.Connected) Console.WriteLine("Connented"); 28 29 //接続完了確認 30 Console.WriteLine("接続完了"); 31 32 //ストリームを作成 33 NetworkStream stream = client.GetStream(); 34 35 string str; 36 //データレジスタM0の内容を読みだすコマンド 37 str = "5000" // サブヘッダ(固定値) 38 + "00FF" // ネットワーク番号(自局なので固定) 39 + "FF" // PC番号(自局なので固定) 40 + "FF03" // 要求先ユニットI/O番号(固定値) 41 + "00" // 要求先ユニット局番号(固定値) 42 + "0C00" // 要求データ長 43 + "1000" // CPU監視タイマ 44 + "0104" // コマンド(データレジスタをワード単位で一括読み出しするコマンド:0401) 45 + "0000" // サブコマンド 46 + "640000" // 先頭デバイス(0) 47 + "90" // デバイスコード(M) 48 + "0200"; // デバイス点数 49 50 Console.WriteLine("str=" + str); 51 52 //byte型に変換 53 byte[] tmp = Encoding.UTF8.GetBytes(str); 54 55 //送信 56 stream.Write(tmp, 0, tmp.Length); 57 Console.WriteLine("送信しました"); 58 59 //応答電文の受け取り配列 60 byte[] res = new byte[30]; 61 Console.WriteLine("受信します"); 62 63 64 stream.Read(res, 0, res.Length); 65 //受け取り完了確認 66 Console.WriteLine("受信完了"); 67 68 //受け取ったものの表示 69 foreach (int i in res) 70 { 71 Console.WriteLine("res=" + i); 72 } 73 74 string s = string.Empty; 75 76 s = BitConverter.ToString(res); 77 Console.WriteLine("s="+s); 78 79 } 80 catch (Exception e) 81 { 82 Console.WriteLine(e.Message); 83 84 } 85 finally 86 { 87 Console.WriteLine("キーを押下で終了"); 88 Console.ReadLine(); 89 } 90 91 } 92 } 93} 94

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

回答3

0

実際に実機につないで試してみました。

2点、問題があります。

c#

1byte[] tmp = Encoding.UTF8.GetBytes(str);

このまま変換すると16進数の文字列が正しくバイナリに変換されません。
moonphaseさんの追記にあるように16進数文字列を変換する必要があります。

c#

1 + "00FF" // ネットワーク番号(自局なので固定)

ネットワーク番号の設定が間違っています。正しくは00ですね。
(多分PC番号を余分につけてしまっているのではと思います)

この2か所を修正したところ、バイナリでD0 00 ~の応答が返ってきました。

ちなみに、最初のエラーメッセージはどこからきているものでしょうか?
そのまま実行したら応答待ちで該当のエラーメッセージは出ませんでした。

内蔵EthernetではOpenできなかったとのことですが、
試せる環境が無いので推測ですが、ネットワークパラメータから設定しているのではないかと思われます。
内蔵Ethernetの設定はPCパラメータに項目があります。

投稿2018/11/29 10:46

kanolog

総合スコア12

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

0

データ長間違ってませんか?

+ "0C00" // 要求データ長 ↓ + "1800" // 要求データ長

以下追記

あと、文字列の16進数をバイトにしたい場合は以下関数を通してください

C#

1public static byte[] StringToBytes(string str) 2 { 3 var bs = new List<byte>(); 4 for (int i = 0; i < str.Length / 2; i++) 5 { 6 bs.Add(Convert.ToByte(str.Substring(i*2, 2), 16)); 7 } 8 // "01-AB-EF" こういう"-"区切りを想定する場合は以下のようにする 9 // var bs = str.Split('-').Select(hex => Convert.ToByte(hex, 16)); 10 return bs.ToArray(); 11 } 12

以下変更を行う

c#

1byte[] tmp = Encoding.UTF8.GetBytes(str); 23byte[] tmp = StringToBytes(str)

投稿2018/11/03 12:28

編集2018/11/03 12:33
moonphase

総合スコア6619

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

moyashi27371

2018/11/03 12:56

回答していただいたことを試してみましたがうまくいきませんでした。

0

byte[] tmp = Encoding.UTF8.GetBytes(str);

これでは、単に文字列コードをバイナリにしてるだけなのでダメな気がしますが。
tmpのデータはどうなってるか見てみればどうでしょう


C#

1byte[] tmp=new byte[]{ 2 0x50,0x00, // サブヘッダ(固定値) 3 0x00,0xff, // ネットワーク番号(自局なので固定) 4 0xff, // PC番号(自局なので固定) 5 ... 6};

というかんじで

投稿2018/11/03 12:07

編集2018/11/03 12:16
y_waiwai

総合スコア86074

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
86.02%

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

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

質問する

関連した質問

同じタグがついた質問を見る

C#

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