VBでシリアル通信がうまくいきません

このQ&Aのポイント
  • VBでシリアル通信がうまくいかない原因を教えてください
  • 現在、VBのシリアルポートメソッドを使用してRS232-C通信を行っていますが、別のPCから文字を送っても受信できません。キーボードを押しっぱなしにすると受信結果が表示されます。
  • ソースコードを記載していますので、詳しい方は教えてください
回答を見る
  • ベストアンサー

VBでシリアル通信がうまくいきません

VisualBasicのシリアルポートメソッドを使い、RS232-C通信を試そうとしている初心者です。 現在、別のPCからTeratermより文字を送り、自分のPCで受信結果を得ようとしているのですが 別PCから単発で文字を送っても、自分のPCでは反応せず キーボードを押しっぱなしにすると、自分のPCのウィンドウに受信結果が表示されます。 一体、何が原因なのでしょうか? さっぱり、わからず途方に暮れています。 下記にソースコードを記載しますので、詳しい方は教えて下さると幸いです。 ------------------------------------------------------------------------ Public Delegate Sub MyDelegate(ByVal intData As Integer) Private Sub AddData(ByVal str As String) TextBox1.Text = str End Sub Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived Dim dlgByte As MyDelegate = New MyDelegate(AddressOf AddData) Dim ByteRead(SerialPort1.BytesToRead - 1) As Byte SerialPort1.Read(ByteRead, 0, SerialPort1.BytesToRead) For i As Integer = 0 To ByteRead.Length - 1    Me.Invoke(dlgByte, ByteRead(0)) Next End Sub ------------------------------------------------------------------------

質問者が選んだベストアンサー

  • ベストアンサー
  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.2

SerialPort1がデザイナで配置したSerialPortなら、そのプロパティを見てイベントのDataReceivedのところにその関数名があればOKです。 デザイナで配置した物でないならもちろん「イベントに登録する」というコードを書く必要があります。

その他の回答 (1)

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.1

> TextBox1.Text = str TextBox1.Text = TextBox1.Text + str にしないと下のInvokeで常に一文字分で上書きされます。 複数バイトを受信していても、見た目には「常に最後の一文字だけが表示されている」ようにしか見えないでしょう。 > Private Sub SerialPort1_DataReceived(以下略) このメソッドはシリアルポートのイベントとして正しく登録されていますか? > Me.Invoke(dlgByte, ByteRead(0)) 引数はByteRead(i)でないとせっかく読んだデータの先頭しか渡りません。 あとAddDataの引数型がStringでデリゲートの引数型がIntegerで実際に渡している引数の型がByteという不整合っぷりが問題になっている可能性があります。 デリゲートの引数型をStringにして、Invokeで渡す引数をToString()でString変換してから渡す方が確実そうな……

Macchomu
質問者

お礼

ご回答ありがとうございます。 初心者なものでわからないもので >> Private Sub SerialPort1_DataReceived(以下略) > このメソッドはシリアルポートのイベントとして正しく登録されていますか? は前に宣言等が必要ということでしょうか?

関連するQ&A

  • VB2010 シリアル受信した情報を表示する

    VB2010 シリアル受信した情報を表示する フォームが表示されたらポートを開けてテキストボックスに文字を表示させたいです。 送られてくる情報はSTXとETXで挟まれた数十文字のアスキー文字です。 フォーム表示中は、teratermやハイパーターミナルで接続不可エラーが出ますし その逆でteratermやハイパーターミナルで接続している時にはcomポートエラーが出ます。 teratermやハイパーターミナルではシリアルで受信した文字が表示されています。 そのような状況で下記、シンプルなコードを作りましたが表示されません。 テキストボックスが何も変化しない状態です。なんでもいいので、テキストボックスに受信した情報を出してみたいです。 http://msdn.microsoft.com/ja-jp/library/cc720852.aspx を参考に受信部分に使っています。 Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Call SerialPort1.Open() End Sub Delegate Sub AddDataDelegate(ByVal str As String) Private Sub AddData(ByVal str As String) TextBox1.Text = TextBox1.Text + str 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 = SerialPort1.ReadLine Catch ex As Exception strDataReceived = ex.Message End Try TextBox1.Invoke(add, strDataReceived) End Sub End Class

  • vb2005で受信関数を以下の作成しています。

    vb2005で受信関数を以下の作成しています。 Private Sub r_SerialPort1_DataReceived(ByVal sender As Object, _  ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) _  Handles SerialPort1.DataReceived  Dim tmp As Integer  Try   tmp = SerialPort1.BytesToRead '受信バイト数取得 SerialPort1.Read(s_RxBuff, s_RxCont, tmp) 'データ読込み s_RxCont = s_RxCont + tmp '受信バイト数更新  Catch ex As Exception s_Status = c_ErrTRP 'ポートエラー(受信) End Try End Sub この関数で割込みが入るのですが、tmp=の所でbreakし読出そうとしてSerialPort1をウォッチすると、 "ポートは閉じられています"と表示されていて、Catch方向に進むのですが、何故こんなことが起こるのでしょうか? 宜しくお願いします。

  • 'Button1を押したらポートオープン

    'Button1を押したらポートオープン Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 'シリアルポートを設定。 SerialPort1.PortName = SerialPortComboBox.Text SerialPort1.BaudRate = SerialBpsComboBox.Text Select Case SerialParityComboBox.Text Form3.SerialPort1.Parity = IO.Ports.Parity.None 'データ長 SerialPort1.DataBits = SerialDataBitsComboBox.Text 'RTSラインを有効にする SerialPort1.RtsEnable = True '送信タイムアウト SerialPort1.WriteTimeout = 3000 Try 'ポートをオープン SerialPort1.Open() 'いざ送信 'SerialPort1.Write(Chr(&HC)) 'ケーブルが外れた場合などのタイムアウトエラーなら、 Catch ex As Exception MsgBox(ex.Message, MsgBoxStyle.Critical, "シリアル通信エラー") SerialPort1.Close() Exit Sub End Try '送信バッファが空になるまで待って、 While SerialPort1.BytesToWrite > 0 My.Application.DoEvents() End While ''''''''''''文字送信 'シリアルポート送信データをSJISに指定 SerialPort1.Encoding = System.Text.Encoding.GetEncoding(932) Dim Settei As String '送信文字代入 Settei = "A.1=" & vbCrLf 'いざ送信 SerialPort1.Write(Settei) '送信バッファが空になるまで待って、 While SerialPort1.BytesToWrite > 0 My.Application.DoEvents() End While 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 = SerialPort1.ReadLine Catch ex As Exception strDataReceived = ex.Message End Try TextBox1.Invoke(add, strDataReceived) End Sub ///////// 文字を送信した後に相手から帰ってきます。 送信した後の受信の部分ですが、これで正しいか教えて頂きたいです。

  • シリアルポートから送られてくる文字の指定方法

    現在VB2010で作成中のアプリと測定器のデーターをシリアル通信で記録採取したと考えています。 測定機からの通信が下記の通りにPCに送られてきますが、必要な部分の採取す方法が分かりませんので教えてください。 ハイパーターミナルでの測定器からの文字受信は12文字送られてきます。 VBで作成中のアプリでは5文字目から9文字目のみをテキストに表示したいと思いますが、分かる方教えてください。現在制作中のソースも一部表示しますので、よろしくお願いします。今年から勉強してる、初心者です。 Delegate Sub AddDataDelegate(ByVal str As String) Private Sub AddData(ByVal str As String) '受信データー表示' If SerialPort1.IsOpen = False Then 'シリアルポートをオープンしていないときは、処理しない Return End If '受信データー読み込み Dim data As String data = SerialPort1.ReadExisting()    上記のソースが受信するようにしていますが、受信データーは1s毎に更新されておりますその都度テキストへ表示するようにしたいと思います。データーが更新されても、数値は残るようにしたいと思います。

  • シリアル受信データをファイルに書き出したい

    マイコンとPCをCOMポートで通信し、受信データをファイルに書き出したいのです。 やってみたこと1.と2.の間を埋める技術についてアドバイスをお願いします。 1.キーボード入力したテキストボックスの内容をファイルに書き出す ⇒書けました、OK     Dim xxx As New System.IO.StreamWriter("e:xxx.txt", False, System.Text.Encoding.Default) xxx.WriteLine(TextBox1.Text) xxx.Close() 2.サンプルコードでシリアル通信 ⇒受信データがテキストボックスに表示されました、OK     以下サイトを参考に勉強中、テキストボックス部分を抜粋させて頂きます     (http://www.kana-soft.com/tech/sample_0008_4.htm#1) 3.2.で表示されたテキストボックスの内容を、1.のように書き出したいのですが   上手くいきません。'■から'■間に xxx.WriteLine(RcvTextBox.Text) 書いてみましたが   e:xxx.txtは作成されません。delegate、invokeの理解不足が原因かと思うのですが、   調べ回るうちに・・・限界みたいです。(^_^;) (抜粋) '===== Private Delegate Sub Delegate_RcvDataToTextBox( data As String ) '===== Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived Try '受信データを読み込む. Dim data As String data = SerialPort1.ReadExisting() '受信したデータをテキストボックスに書き込む. Dim args(0) As Object args(0) = data Invoke(New Delegate_RcvDataToTextBox(AddressOf Me.RcvDataToTextBox), args) Catch ex As Exception MsgBox( ex.Message ) End Try End Sub '===== Private Sub RcvDataToTextBox( data As String ) '受信データをテキストボックスの最後に追記する. If IsNothing( data ) = False Then RcvTextBox.AppendText( data ) End If '■     Dim xxx As New System.IO.StreamWriter("e:xxx.txt", False, System.Text.Encoding.Default) xxx.WriteLine(RcvTextBox.Text) xxx.Close()     '■ End Sub ===== 以上、駄目出しをよろしくお願いします。

  • VB2010で、シリアル通信をするには

    VB2010で、シリアル通信をするには シリアルポートをopenしようとすると、エラーで弾かれてしまいます。 どのように対処したら良いですか? 使っているソースコードは、下記の通り。 Private Sub ButtonRsStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonRsStart.Click Try '例外処理のはじまり If SerialPort1.IsOpen = True Then 'ポートはオープン済み MessageBox.Show("すでに" & SerialPort1.PortName & "は接続されています。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error) Exit Sub End If SerialPort1.PortName = "COM1" 'オープンするポート名を格納 SerialPort1.Open() 'ポートオープン PORT_STATE.Text = "OPEN" Catch ex As Exception '例外処理 MessageBox.Show(ex.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try End Sub --------------- エラーが発生する場所は、「Catch 」になります。 エラーメッセージは、「ポート 'COM1' へのアクセスが拒否されました。」です。 何が原因なのか、さっぱり分かりません。 ヒントになりそうな解答を頂けないでしょうか?

  • VB2010 COMポートからのバイナリ受信

    オシロスコープからの画像データ(40kバイト程度のtifファイル)をPCのCOMポートから受信し 保存するプログラムを作成しているのですが、受信データを正しくPC上に保存できません。 具体的には下記のコードでtifファイルは作成されますが、容量が数kバイトで明らかに不足 しています。 MsgBoxを有効にして受信バッファサイズや書込み長さを確認しましたが、「OK」ボタンを押す たびに下記の表示になります。COMポートのバッファサイズが4096バイトなので「dat.Length」 をすべて足し合わせると本来の受信データサイズになると思うのですが、PC上に作成された ファイル容量から「dat」が常に上書きされているような気がします。 正しく保存するにはどのような修正が必要でしょうか? 【MsgBoxを有効にしたときの表示値(OKを押すたびに数値が変わる)】 「dat.Length」 183 4075 4072 4092 4088 4084 4085 4092 4059 4078 3910 0 0 ・ ・ ・ 「ByteToRead」 4060 1508 324 908 2334 1785 70 227 400 0 0 ・ ・ ・ 【作成したコード】 Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As_ System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived ' シリアルポートからデータ受信 Dim dat As Byte() = New Byte(SerialPort1.BytesToRead - 1) {} SerialPort1.Read(dat, 0, dat.GetLength(0)) 'MessageBox.Show(dat.Length) 'MessageBox.Show(SerialPort1.BytesToRead) File.WriteAllBytes("C:\test1.tif", dat) SerialPort1.DiscardInBuffer() End Sub 【環境】 OS:Win7 VB:2010 ポート設定:SerialPortクラス標準からポート番号以外は変更なし

  • VB添削

    このプログラムは 例えば3 3 4とテキストボックスに数字が打ち込まれると 3×3行列が4個分 のテキストボックスがでてきます。 ここに数字を打ち込んでいき、ボタン2を押すと3×3のテキスト トボックスが出てくると同時に足し算した結果が出てくるようにしたいです。 以下のプログラムはできたところまで作成しています。 どこを直せばよいのでしょうか。 Public Class Form1 Private number As Integer Private rows As Integer Private columns As Integer Private Sub Form11_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load For i As Integer = 1 To 3 AddHandler Me.Controls("TextBox" & i).TextChanged, AddressOf TextBox_TextChanged Next End Sub Private Sub TextBox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) If System.Text.RegularExpressions.Regex.IsMatch(CType(sender, TextBox).Text, "[^0-9]") Then MessageBox.Show("数字で入力してください", Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Error) With CType(sender, TextBox) .Text = .Text.Substring(0, .Text.Length - 1) .SelectionStart = .Text.Length End With End If Dim cnt1 As Integer Dim cnt2 As Integer Dim cnt3 As Integer If Integer.TryParse(TextBox1.Text, cnt1) And Integer.TryParse(TextBox2.Text, cnt2) And Integer.TryParse(TextBox3.Text, cnt3) Then For k = 1 To cnt3 For i = 1 To cnt1 For j = 1 To cnt2 Dim tb As TextBox = New TextBox() tb.Name = "tb" + i.ToString() Me.Controls.Add(tb) tb.Top = (i - 1) * 28 + 55 tb.Left = (j - 1) * 30 + 40 * (cnt2 * (k - 1)) + 10 tb.Width = 25 Next Next Next End If End Sub Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Me.Bounds = New Rectangle(10, 10, 1350, 800) Me.AutoScroll = True End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim sum As Double Dim cnt As Integer = 0 For i As Integer = 1 To rows For j As Integer = 1 To columns Dim tb As TextBox = New TextBox() cnt += 1 : If cnt > rows * columns Then cnt = 1 tb.Name = "tb" + cnt.ToString Me.Controls.Add(tb) tb.Top = (i - 1) * 30 + (80 + 40 * rows) tb.Left = (j - 1) * 60 + 10 tb.Width = 40 sum = 0 For k As Integer = 1 To number sum += Double.Parse(CType(Me.Controls("tb" + (cnt + (rows * columns * (k - 1))).ToString()), TextBox).Text) Next tb.Text = sum.ToString() Next Next End Sub Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged End Sub Private Sub TextBox2_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox2.TextChanged End Sub Private Sub TextBox3_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox3.TextChanged End Sub End Class

  • VB2008でデリゲートの代わりにラムダ式が使えるというので、試してみ

    VB2008でデリゲートの代わりにラムダ式が使えるというので、試してみたのですが、うまくいきません。 試したコードは下記です。WindowsFormアプリで、Form1にButton1とLabel1を貼りつけております。 Button1を押すとLabel1に"はじめました"と表示し、2秒待ってから"おわりました"と表示するつもりです。 デリゲートを使った(2)は意図した動作をしますが、ラムダ式を使った(1)はLabel1に何も表示しません。 このようなことはできないのでしょうか? Public Class Form1 Private Delegate Sub longTaskDelegate() Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Label1.Text = "" Dim dlg As New longTaskDelegate(AddressOf LongTask) dlg.BeginInvoke(AddressOf longTaskCallback, dlg) End Sub Private Sub longTaskCallback(ByVal ar As IAsyncResult) Dim dlg As longTaskDelegate = DirectCast(ar.AsyncState, longTaskDelegate) dlg.EndInvoke(ar) End Sub Private Delegate Sub displayMessageDelegate(ByVal msg As String) Private Sub DisplayMessage(ByVal msg As String) If Label1.InvokeRequired Then Label1.Invoke(Function() Label1.Text = msg) ' --- (1) 'Label1.Invoke(New displayMessageDelegate(AddressOf Me.DisplayMessage), msg) ' --- (2) Else Label1.Text = msg End If End Sub Private Sub LongTask() DisplayMessage("はじめました") System.Threading.Thread.Sleep(2000) DisplayMessage("おわりました") End Sub End Class

  • VBで倍数を出したい

    VBで倍数を出したい よろしくお願いします。 おそらく基本なんだと思うのですが、さっぱりわかりません。 TextBox Label Buttonと並んでいて、 TextBoxに入った整数に対し、 Buttonを1度押すたびに、 Labelに倍数が表記されていく、 という趣旨なのですが。 まず、前段階として下記を作らされました。 Public Class Form1 Dim i As Integer Dim m As Integer Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click i = TextBox1.Text lblmessage.Text = i + m m = lblmessage.Text End Sub End Class このように、labelの数字がどんどん変わっていくのはできたのですが、問題は、 Text…10 Label…10    20    30    40    50    60    70    80    90    100 となり、しかも一度に出るのではなく、Buttonひと押しにつき一つの解が出ね 次の一押しで改行され解が出る。 かつ、100で打ち止めにすること…だそうです。 いちおうめちゃくちゃですが、みんな風に作りました。 Public Class Form1 Dim a As Integer Dim b As Integer Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim b As Integer = 10 a = TextBox1.Text lblMessage.Text = a & ControlChars.CrLf & a + b End Sub End Class どうかヒントだけでもお願いします。

専門家に質問してみよう