tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトル連続したシリアル通信処理
記事No11229
投稿日: 2014/02/28(Fri) 22:13
投稿者レフティー
毎々お世話になっております。シリアル通信について教えて下さい。
以前より、カスタム基板との通信プログラムを作成しており、
流れは、
1.PC(アプリ)から基板へ、値の設定コマンド送信
2.基板からのレスポンスを受信(応答時間:およそ500msec)
といった単純なものです。

困っているのは、基板へ連続して値を設定したいのですが、(以下の流れ)
1.PC(アプリ)から基板のチャンネルAへ、値の設定コマンド送信
2.基板からのレスポンスを受信
3.PC(アプリ)から基板のチャンネルBへ、値の設定コマンド送信
4.基板からのレスポンスを受信
現状上手くいきません。

送信側プログラムは、
Public Sub SetTemp(ByVal Setval As Double)
        'チャンネルAへの設定
    Try
            F1.SerialPort1.Write("チャンネルAへのコマンドおよび設定値" & vbLf)
            manualEvent.Reset()
            bret = manualEvent.WaitOne(500, False)
            If bret = False Then
                MessageBox.Show("Timeout Error", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End If
        Catch ex As Exception
            MessageBox.Show(ex.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try

    'チャンネルBへの設定
    Try
            F1.SerialPort1.Write("チャンネルBへのコマンドおよび設定値" & vbLf)
            manualEvent.Reset()
            bret = manualEvent.WaitOne(500, False)
            If bret = False Then
                MessageBox.Show("Timeout Error", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End If
        Catch ex As Exception
            MessageBox.Show(ex.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try
    End Sub

といった具合で、受信側は、
Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
        Dim strDataReceived As String = ""
        Dim add As New AddDataDelegate(AddressOf AddData)

        Try
            strDataReceived = SerialPort3.ReadLine          'NewLine値まで読み込み
            comFlg = 3
            SerialPort3.DiscardInBuffer()                   '受信バッファクリアのつもり
            manualEvent.Set()
        Catch ex As Exception
            strDataReceived = ex.Message
        End Try
        TextBox1.Invoke(add, strDataReceived)
    End Sub

1.チャンネルAへのコマンド送信。スレッドをブロック
2.基板からの応答を受信。シグナル状態へセット
3.スレッドブロック解除、チャンネルBへのコマンド送信。再度スレッドをブロック
4.基板からの応答を受信。シグナル状態へセット
5.スレッドブロック解除
というシーケンスをイメージで作成したのですが、
2つ目のコマンド送信時にbretがFalseとなってしまい、タイムアウトエラーとなってしまいます。
アドバイスいただけますと助かります。

[ツリー表示へ]
タイトルRe: 連続したシリアル通信処理
記事No11230
投稿日: 2014/03/01(Sat) 09:52
投稿者オショウ
> 毎々お世話になっております。シリアル通信について教えて下さい。

  2ポート使って通信しているんですか?
  コマンド送信では、SerialPort1 で行っておられますが、受信の方
  では、イベント内で、SerialPort3 からReadLine されてます。
  しかしながらイベントは、SerialPort1 ?

  どういう接続で、どういう設定になっているのかを正しく知る必要
  があります。

  あと、受信イベントでは、信号線の変化でもイベントが発生するの
  で、イベントの種類を判定して文字を受信した場合にReadLineする
  ようにしておく必要があります。

以上。

[ツリー表示へ]
タイトルRe^2: 連続したシリアル通信処理
記事No11232
投稿日: 2014/03/03(Mon) 12:42
投稿者レフティー
オショウ様
アドバイスありがとうございます。

投稿内容の確認不足でした。誤記になります。
プログラム内では複数シリアルポートを使用していますが、
当該基板との通信は、送信、受信共に、シリアルポート1で行っております。

基板との接続は送信、受信、信号グランドの3線のみの配線であり、
フロー制御は行なっていない状況であります。

[ツリー表示へ]
タイトルRe^3: 連続したシリアル通信処理
記事No11239
投稿日: 2014/03/04(Tue) 12:15
投稿者OrientalMelody
SerialPort.DataReceivedイベントを使用して、受信の有無を判断されているようですが、
受信バイト数は何バイト以上くらいでも良いのですが、決まっているのでしょうか?

SerialPort.BytesToRead で該当バイト数になるまで、Do Loop Sleep等で待機後、
SerialPort.ReadLine()で取得という感じではいかがでしょうか?


> オショウ様
> アドバイスありがとうございます。
>
> 投稿内容の確認不足でした。誤記になります。
> プログラム内では複数シリアルポートを使用していますが、
> 当該基板との通信は、送信、受信共に、シリアルポート1で行っております。
>
> 基板との接続は送信、受信、信号グランドの3線のみの配線であり、
> フロー制御は行なっていない状況であります。

[ツリー表示へ]
タイトルRe^4: 連続したシリアル通信処理
記事No11244
投稿日: 2014/03/04(Tue) 22:14
投稿者レフティー
OrientalMelody様

アドバイスありがとうございます。

今回のケースでは、受信バイトは4バイト以上となっております。
コマンドによって受信データ長が変わります。

SerialPort.DataReceivedイベントしか頭にないといいますか、他の手法を考えもしませんでした。
今回は、"TextBox1.Invoke(add, strDataReceived)"をコメントアウトすることで
意図する動作となりました。残念なことに現象の理解には至っておりませんが、、、
オショウ様にもコメントいただきましたが、受信検知の他の方法も勉強したいと思います。

[ツリー表示へ]
タイトルRe: 連続したシリアル通信処理
記事No11235
投稿日: 2014/03/03(Mon) 17:18
投稿者オショウ
>             F1.SerialPort1.Write("チャンネルAへのコマンドおよび設定値" & vbLf)
>             manualEvent.Reset()
>             bret = manualEvent.WaitOne(500, False)
>             If bret = False Then
>                 MessageBox.Show("Timeout Error", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
>             End If

  強いて指摘するならば・・・

            manualEvent.Reset()
            F1.SerialPort1.Write("チャンネルAへのコマンドおよび設定値" & vbLf)
            bret = manualEvent.WaitOne(500, False)
            If bret = False Then
                MessageBox.Show("Timeout Error", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End If

  と言うことになると思います。
  これを試してダメならば、他の要因の問題となります。
  因みに、シリアルUSB変換アダプタを使っているとか・・・

以上。参考まで

[ツリー表示へ]
タイトルRe^2: 連続したシリアル通信処理
記事No11236
投稿日: 2014/03/03(Mon) 22:16
投稿者レフティー
オショウ様

アドバイスありがとうございます。
ご指摘の点、試してみます。

>因みに、シリアルUSB変換アダプタを使っているとか・・・

まさに、PC側は、シリアルUSB変換アダプタを使っております。
もしかして、この変換アダプタが何かフロー信号を発していたりするのでしょうか。

[ツリー表示へ]
タイトルRe^3: 連続したシリアル通信処理
記事No11237
投稿日: 2014/03/03(Mon) 23:08
投稿者オショウ
> まさに、PC側は、シリアルUSB変換アダプタを使っております。
> もしかして、この変換アダプタが何かフロー信号を発していたりするのでしょうか。

  デバイスのプロパティの詳細設定で、送受信時のドライバー内の
  タイムアウト値の設定ができる場合があります。

  大抵は、送受信ともゼロが設定されているはずですが、通信する
  器機側の都合で、ゼロで無い最小値に設定変更することで、一気
  に問題解決・・・と言う場合もあります。

※ 詳細設定画面でタイムアウト設定を変更できた場合・・・
  受信側のタイムアウト値のみを変更してみて下さい。

※ 先のコードの修正は必ず行ってください。

以上。参考まで

[ツリー表示へ]
タイトルRe^4: 連続したシリアル通信処理
記事No11243
投稿日: 2014/03/04(Tue) 22:07
投稿者レフティー
オショウ様

ご指摘いただいたコード修正を試してみましたが、
2回目の送信コマンドでタイムアウトとなってしまいました。
今回使用しているUSBコンバーターではタイムアウトの設定まではできませんでした。

改めて過去ログを検索してみると、
タイトル : VB2005で、シリアル通信について
のトピックのAMI殿の状況と非常に似通っていることに気づきました。
(l管理人様、過去ログの調査足らずですみません。)

AMI殿と同じく、DataRecievedイベント内の"TextBox1.Invoke(add, strDataReceived)"、
コメントアウトしたところ、タイムアウトにならず、連続したコマンド送信が上手くいきました。

残念ながら、自分で理由を理解できていない状況ではありますが、
動きとしては、思い通りのものとなりました。
お忙しいところ色々とアドバイスありがとうございました。

[ツリー表示へ]