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

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

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

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

Q&A

2回答

1930閲覧

C# SerielPortで機器の初期化でレスポンスが戻ってこない

TrainRain

総合スコア20

C#

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

0グッド

1クリップ

投稿2018/12/03 06:27

編集2018/12/03 07:30

こんにちは。

前提・実現したいこと

先日はXORについてご回答いただき、ありがとうございました。

Windows10を使ってVisual Studo 2017でWindows Formアプリケーションのプロジェクトを作っています。
DensoのQK20-ICというICカード読み取り機でICカードを読もうとしています。

試したこと

QK20-ICのセットアップは完了しており、COM4に接続しています。
他のアプリケーションでは動作しているので、接続は確実です。

まず、Initializeしてみようとしています。

Formに

C#

1SerialPort ComIcCard; 2TextBox ReceivedData;

を配置しました。

これでシリアルポートを初期化してコマンドを実行しているだけなので、レスポンスが戻って当然と思っているのですが、戻ってきません。
原因のヒントなどアドバイスをいただければ幸いです。

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

ComIcCard_DataReceivedで待ち受けているがレスポンスが戻ってこない。
レスポンスイベントが発生しません。

該当のソースコード

C#

1 private void Initialize_Click(object sender, EventArgs e) 2 { 3 var command = 排他的論理和XOR(); 4 OpenRS232C(); 5 string text = System.Text.Encoding.ASCII.GetString(command.ToArray()); 6 ComIcCard.Write(text);//\b\0\u0005\0\u0001\0\0\u0001\r 7 } 8 9 delegate void SetTextCallback(string text); 10 private void Response(string text) 11 { 12 if (ReceivedData.InvokeRequired) 13 { 14 SetTextCallback d = new SetTextCallback(Response); 15 BeginInvoke(d, new object[] { text }); 16 } 17 else 18 { 19 ReceivedData.AppendText(text + "\r\n"); 20 } 21 } 22 23 private void ComIcCard_DataReceived(object sender, SerialDataReceivedEventArgs e) 24 { 25 try 26 { 27 string receivedtext = ComIcCard.ReadLine(); 28 Response(receivedtext); 29 } 30 catch (Exception ex) 31 { 32 string error = ex.Message; 33 } 34 } 35 36 public bool OpenRS232C() 37 { 38 ComIcCard = new SerialPort() 39 { 40 PortName = "COM4", 41 BaudRate = 9600, 42 Parity = Parity.None, 43 DataBits = 8, 44 StopBits = StopBits.One 45 }; 46 ComIcCard.DataReceived += ComIcCard_DataReceived; 47 try 48 { 49 ComIcCard.Open(); 50 } 51 catch (Exception ex) 52 { 53 ProjectData.SetProjectError(ex); 54 ProjectData.ClearProjectError(); 55 return false; 56 } 57 return true; 58 }

C#

1 public List<byte> InitializeCommands = new List<byte> { 0x08, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x01 }; 2 3 public List<byte> 排他的論理和XOR() 4 { 5 byte answer0 = 0x08 ^ 0x00; 6 byte answer1 = (byte)(answer0 ^ 0x05); 7 byte answer2 = (byte)(answer1 ^ 0x00); 8 byte answer3 = (byte)(answer2 ^ 0x01); 9 byte answer4 = (byte)(answer3 ^ 0x00); 10 byte answer5 = (byte)(answer4 ^ 0x00); 11 byte answer6 = (byte)(answer5 ^ 0x01); 12 InitializeCommands.Add(answer6); 13 return InitializeCommands; 14 }
//メインのリセット(初期化)コマンドは、9バイトのコマンドからなる。 //各値の意味は次のとおり。 //----------------------------------------------------------------------------- // 値 byte数 説明 //----------------------------------------------------------------------------- //RCB 08h 1byte リーダライタコマンド //----------------------------------------------------------------------------- //LEN(length) 00h 05h 2byte DAT部(CLA, INS, P1, P2, Le)の長さ(=5byte)。 //CLA(clear?) 00h 1byte 固定 //INS(insert?) 01h 1byte メインリセットコマンド //P1 00h 1byte 固定 //P2 00h 1byte 固定 //Le(?) 01h 1byte 固定 //----------------------------------------------------------------------------- //BCC ? 1byte ブロック検査符号。RCBからBCCまでの排他的論理和を00hにする値。->ちなみに13。16進数では0x0D。

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

Intel Pentium(R) CPU 4415 Y 1.60GHz RAM 8GB Windows10Pro 64bit 1803 17134.345 Microsoft Visual Studio Community 2017 Version 15.8.5 VisualStudio.15.Release/15.8.5+28010.2036 Microsoft .NET Framework Version 4.7.03056 インストールされているバージョン:Community

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

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

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

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

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

guest

回答2

0

まず、そのICカードリーダのコマンド体系はどういうものであるのか、初期化部分だけでいいので提示してください。

コードを見るに、そのICカードリーダというのはバイナリデータのコマンド/レスポンスになると思われますが、コードではデータの読み出しにreadlineを使ってます。
これはテキストデータを1行読み出すというメソッドになります。
また、データ送信にしても、バイナリデータをムリヤリ文字列として送信してるようにみえますが、これもまたまずいかと思われます

投稿2018/12/03 06:43

y_waiwai

総合スコア87747

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

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

TrainRain

2018/12/03 07:24

コメントありがとうございます。 バイナリにしてみます。 マニュアルを読み込めていないのですが、初期化コマンドは、 0x08, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x01, 0x13(XORの計算値) でOKと思います。 質問に追記します。
y_waiwai

2018/12/03 07:44

送信をバイナリ送信にして、受信イベント中でもデータ構成を見てメッセージ終了を判断する、ってテですね
TrainRain

2018/12/03 09:13

var command = 排他的論理和XOR(); OpenRS232C(); //バイナリデータを送信する。Write(byte[] buffer, int offset, int count) ComIcCard.Write(command.ToArray(), 0, 9);//\b\0\u0005\0\u0001\0\0\u0001\r としてみたのですが、依然DataReceivedは発生しませんでした。 イベントが発火しさえすればと思うのですが…。なにが欠けているでしょう?
y_waiwai

2018/12/03 09:27

ボーレートやパリティ、ビット長はあってるか、実際に送信してるか、ホンマに受信してないのか、オシロで信号を確認してみるとかですねー
guest

0

確認事項として、DataReceivedイベントが発生していないのでしょうか?
それとも発生して、ReadLineが帰ってこないのでしょうか?

後者である場合、SerialPort.ReadLineメソッドにあるようにNewLine値まで読み込もうとしますので、NewLine値(\r\n)を受信するまで帰ってこなくなります。
(正確にはSerialPort.ReadTimeoutに設定した時間ですが、規定値はInfiniteTimeoutとなっています)
ですので、ご使用機器の通信プロトコルを確認してください。
コマンドの終端がNewLine値ではない場合、SerialPort.ReadLineメソッドを使用するのは不適切となります。

送信コマンドはASCIIコードでの送信が正しいのでしょうか?
ぱっと見た感じ、バイナリでの送信が正しそうなデータだと思います。

投稿2018/12/03 06:46

YAmaGNZ

総合スコア10242

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

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

TrainRain

2018/12/03 07:20

コメントありがとうございます。 DataReceivedイベントが発生しません。 バイナリにしてみます。
TrainRain

2018/12/03 07:45

var command = 排他的論理和XOR(); OpenRS232C(); //バイナリデータを送信する。Write(byte[] buffer, int offset, int count) ComIcCard.Write(command.ToArray(), 0, 9);//\b\0\u0005\0\u0001\0\0\u0001\r としてみたのですが、依然DataReceivedは発生しませんでした。
YAmaGNZ

2018/12/03 11:22

ぱっと見た感じ合ってそうですので、y_waiwaiさんがおっしゃる通り、通信設定を確認、プロトコルアナライザー等のシリアルをモニタできる環境を調えて実際の通信データを確認するのが解決の早道のような気はします。 私は使用したことがありませんが、PortMon(https://technet.microsoft.com/ja-jp/sysinternals/bb896644)が使えるかもしれません。 モニタ出来るようであれば、実際に通信を行っている他のアプリケーションの通信もモニタできるはずですから、比べてみるとよろしいかと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問