none
RS232のコマンド通信を行いたい RRS feed

  • 質問

  • win vista

    32bit

    下記プログラムにおいて

    コマンド送信

         ComSerialPort.Write("SNDA" & vbCr)

    このコマンドを送信した際、上手くデータが帰ってきませんでした。ポート開放通信は上手くできましたが、このコマンド送信で上手くデータが帰ってきませんでした。

    どのようにコマンド送信を変更したら宜しいでしょうか?

    Imports System
    Imports System.Collections.Generic
    Imports System.ComponentModel
    Imports System.Data
    Imports System.Drawing
    Imports System.Text
    Imports System.Windows.Forms
    Public Class RS232CForm

        Dim pos As Integer
        Dim pos2 As Integer
        Dim pos3 As Integer


        Dim rhex As Byte
        ' フォームのLoadイベントハンドラ
        Private Sub RS232CForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

            With ComSerialPort
                .PortName = "COM1"                  ' 通信ポートはCOM4
                .BaudRate = 9600                    ' 通信速度は9600bps
                .DataBits = 8                      ' データ長は8ビット
                .Parity = IO.Ports.Parity.None     ' パリティチェックなし
                .StopBits = IO.Ports.StopBits.One


                ' ストップビットは1
                ' ハードウェアによるハンドシェイク
                .Handshake = IO.Ports.Handshake.RequestToSend
                .RtsEnable = False
                .DtrEnable = False

            End With

        End Sub

        ' 通信開始ButtonのClickイベントハンドラ
        Private Sub ConnectButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ConnectButton.Click

            Try
                ' 通信ポートが開いているかどうかの判定
                If ComSerialPort.IsOpen = False Then
                    ' 通信ポートを開く場合の処理
                    ComSerialPort.Open()            ' 通信ポートを開く
                    ConnectButton.Text = "通信停止"
                Else
                    '   通信ポートを切断する場合の処理
                    ComSerialPort.Close()           ' 通信ポートを切断
                    ConnectButton.Text = "通信開始"
                End If
            Catch ex As Exception
                ' 通信ポートの接続・切断時のエラー処理
                MessageBox.Show(ex.Message, "接続エラー", _
                    MessageBoxButtons.OK, MessageBoxIcon.Error)
            End Try

        End Sub

        ' 送信ButtonのClickイベントハンドラ
        Private Sub SendButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SendButton.Click

            ComSerialPort.Write("R" & vbLf)


        End Sub

        ' デリゲート型の宣言
        Delegate Sub RecieveDataDelegate(ByVal RecieveData As String)


        ' デリゲート型のプロシージャを宣言
        Private Sub SetRecieveData(ByVal DataString As String)

            RecieveDataTextBox.Text &= DataString

        End Sub

        ' SerialPortコントロールのDataReceivedイベントハンドラ
        Private Sub ComSerialPort_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles ComSerialPort.DataReceived

            Dim RecieveData As String

            ' デリゲート型の変数の宣言と生成
            Dim recieve As New RecieveDataDelegate(AddressOf SetRecieveData)

            Try
                ' データの受信





                rhex = ComSerialPort.ReadByte

                Dim bytearray(ComSerialPort.BytesToRead - 1) As Byte
                Dim uni As Encoding = Encoding.Unicode
                Dim ecSjis As Encoding = Encoding.GetEncoding("shift-jis")
                ComSerialPort.Read(bytearray, 0, ComSerialPort.BytesToRead)
                Dim uniBytes As Byte() = Encoding.Convert(ecSjis, uni, bytearray)
                RecieveData = uni.GetString(uniBytes)




            Catch ex As Exception

            End Try

            'デリゲート型のプロシージャを呼び出す
            Invoke(recieve, RecieveData)

        End Sub

        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            ComSerialPort.Write("SNDA" & vbLf)
        End Sub


        Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
            TextBox1.Text = RecieveDataTextBox.Text
        End Sub

        Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
            pos = RecieveDataTextBox.Text.IndexOf("S", pos + 1)


            TextBox1.Text = RecieveDataTextBox.Text.Substring(pos, 4)

            pos2 = RecieveDataTextBox.Text.IndexOf("D", pos2 + 1)


            TextBox2.Text = RecieveDataTextBox.Text.Substring(pos2, 4)


            pos2 = RecieveDataTextBox.Text.IndexOf("P", pos2 + 1)


            TextBox3.Text = RecieveDataTextBox.Text.Substring(pos2, 4)


            Dim drow As DataRow



            drow = テーブルDataSet1.Tables("テーブル1").NewRow
            drow("フィールド1") = TextBox3.Text



            テーブルDataSet1.Tables("テーブル1").Rows.Add(drow)

            Me.Validate()
            BindingSource1.EndEdit()

            テーブル1TableAdapter1.Update(テーブルDataSet1.テーブル1)

        End Sub

        Private Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click
            ComSerialPort.Write("SNDA<CR>" & vbLf)
        End Sub

        Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click
            ComSerialPort.Write("SNDA" & vbCr)
        End Sub
    End Class

          
    2015年7月8日 2:34

回答

  • それっぽい機種のPDFを見つけてみてみましたが、ハンドシェイクに関する記載がありませんが、ハンドシェイクは必要なのでしょうか?
    ハンドシェイクで送信待ちしたままになっているような気が…

    まずはポート番号の確認と、ハンドシェイクを変更して確認してみたらどうでしょう。

        Private Sub RS232CForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    
            With ComSerialPort
                .PortName = "COM1"                  ' 通信ポートはCOM4 'ポート4?ポート1
                .BaudRate = 9600                    ' 通信速度は9600bps
                .DataBits = 8                      ' データ長は8ビット
                .Parity = IO.Ports.Parity.None     ' パリティチェックなし
                .StopBits = IO.Ports.StopBits.One
    
    
                '' ストップビットは1
                '' ハードウェアによるハンドシェイク
                '.Handshake = IO.Ports.Handshake.RequestToSend
                '.RtsEnable = False
                '.DtrEnable = False
    
                .Handshake = IO.Ports.Handshake.None
    
                .Encoding = System.Text.Encoding.ASCII
                .NewLine = vbCr
                .ReadTimeout = 1000
                .WriteTimeout = 1000
                .Open()
    
                Try
                    .WriteLine("REST")
                Catch ex As Exception
                    'ハンドシェイクで受け付けてもらえない場合にエラー
                    MessageBox.Show("受信してもらえませんでした")
                    Return
                End Try
                .WriteLine("REST") '念のため再度リセット
    
                .WriteLine("SNDA")
                Try
                    Dim receive = .ReadLine()
                    If (receive.Length > 0) Then
                        MessageBox.Show("受信しました")
                    Else
                        MessageBox.Show("受信失敗しました")
                    End If
                Catch ex As Exception
                    MessageBox.Show("応答がありませんでした")
                End Try
    
            End With
    
        End Sub


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)


    • 編集済み gekkaMVP 2015年7月8日 22:53 WriteをWriteLineに修正
    • 回答の候補に設定 星 睦美 2015年7月17日 8:10
    • 回答としてマーク kirua777 2015年7月20日 6:04
    2015年7月8日 4:03

すべての返信

  • それっぽい機種のPDFを見つけてみてみましたが、ハンドシェイクに関する記載がありませんが、ハンドシェイクは必要なのでしょうか?
    ハンドシェイクで送信待ちしたままになっているような気が…

    まずはポート番号の確認と、ハンドシェイクを変更して確認してみたらどうでしょう。

        Private Sub RS232CForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    
            With ComSerialPort
                .PortName = "COM1"                  ' 通信ポートはCOM4 'ポート4?ポート1
                .BaudRate = 9600                    ' 通信速度は9600bps
                .DataBits = 8                      ' データ長は8ビット
                .Parity = IO.Ports.Parity.None     ' パリティチェックなし
                .StopBits = IO.Ports.StopBits.One
    
    
                '' ストップビットは1
                '' ハードウェアによるハンドシェイク
                '.Handshake = IO.Ports.Handshake.RequestToSend
                '.RtsEnable = False
                '.DtrEnable = False
    
                .Handshake = IO.Ports.Handshake.None
    
                .Encoding = System.Text.Encoding.ASCII
                .NewLine = vbCr
                .ReadTimeout = 1000
                .WriteTimeout = 1000
                .Open()
    
                Try
                    .WriteLine("REST")
                Catch ex As Exception
                    'ハンドシェイクで受け付けてもらえない場合にエラー
                    MessageBox.Show("受信してもらえませんでした")
                    Return
                End Try
                .WriteLine("REST") '念のため再度リセット
    
                .WriteLine("SNDA")
                Try
                    Dim receive = .ReadLine()
                    If (receive.Length > 0) Then
                        MessageBox.Show("受信しました")
                    Else
                        MessageBox.Show("受信失敗しました")
                    End If
                Catch ex As Exception
                    MessageBox.Show("応答がありませんでした")
                End Try
    
            End With
    
        End Sub


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)


    • 編集済み gekkaMVP 2015年7月8日 22:53 WriteをWriteLineに修正
    • 回答の候補に設定 星 睦美 2015年7月17日 8:10
    • 回答としてマーク kirua777 2015年7月20日 6:04
    2015年7月8日 4:03
  • こんにちは

    機種はなんでしょう?  検索すると、Puritan Bennett 800 なんてのがありましたが。
    この機械のマニュアルにはサンプルはありませんか? あれば、それを参考するのが近道と思いますが、、、、

    ネットで見れるマニュアルだと、ハンドシェイクが必要な気がします。
    従って、 RTS/DTR を False で動くでしょうか?
    また、受信できないとの事ですが、全くデータが受信できないという事でしょうか? どこまで動いたかの情報があるとより、多くの情報が得られると思います。

    gekkaさん、

    > .Write("SNDA")

    では、改行コード(CR)が送られないと思いますが、理解が違っているでしょうか?
    あと、 "念のため再度リセット" ですぐに次のコマンドを送ると内部初期化が走り、正しく認識できない機械もあるようです。私の知っているのが古いものだけかも知れませんが。

    参考までに

    • 回答の候補に設定 星 睦美 2015年7月17日 8:10
    2015年7月8日 15:54
  • 個人的には、DTR,RTSはとりあえずONにしといていいのでは、とおもっています。
    (フロー制御が問題になることは少ないから+TeraTermとかが「フロー制御なし」でそういう動作をするから)
    ただ、ごくまれにDTRがONになるとバッファリセット、みたいな機器もあるので一概にどうこう言えませんが。
    .Handshake = HandShake.None
    .RtsEnable = True
    .DtrEnable = True

    あ、そもそもケーブルがどういう結線になっているか、とかの問題もありますね。クロス・ストレートとか、RIがONにならないとダメとか。
    TeraTermとかのターミナルソフトで繋げば応答は帰ってくるのでしょうか?


    jzkey

    • 回答の候補に設定 星 睦美 2015年7月17日 8:10
    2015年7月8日 18:30
  • ありがとうございます。

    検証できる環境が5日後なので後ほど検証してみたいと思います。

    2015年7月8日 19:17
  • 指摘ありがとうございます。WriteではなくWriteLineが正しいです。
    コード直しておきました。

    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    2015年7月8日 22:57
  • 時間が少ないのであれば、まずは232Cのターミナルとして動作するフリーウェアなどで通信できることを確認した方が良いでしょう。

    特に物理的な仕様については、最初によく確認して下さい。シリアルケーブルの結線方法は様々なので、市販のクロスケーブルの中にはRTS/CSTやDTR/DSRを結線していない物もあります。チップセットの仕様でRTS/CSTやDTR/DSRなどの制御出力を持たない場合もあります。

    甕星

    • 回答の候補に設定 星 睦美 2015年7月17日 8:10
    2015年7月9日 7:44