VisualBasicとArduino間のシリアル通信方法

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
non
記事: 1097
登録日時: 13年前

VisualBasicとArduino間のシリアル通信方法

#1

投稿記事 by non » 10年前

PCとArduinoをシリアル通信したいのです。PC側はVisualBasicのSerialコントロールを使います。一応、通信はできたのですが、やりたいことはpcから大量のデータをできるだけ高速にArduinoに送信したいのです。Arduinoのバッファは128バイトとの事で、たくさんは蓄えられません。そこで、1バイト(数バイト単位でもよいけど)送信したら、コールバックし、確認後また次の1バイトを送りたいのですが、VisualBasic側でどのような処理をすればよいのでしょう。一般にはDataReceivedイベントで受信を待つのでしょうけど、この関数に飛んだら、元の処理の途中にどうやって戻ればよいのでしょう。このイベントって終わったからって元の処理に戻ってはくれないのでしょうね。
このようにすれば良いよと言う方法をご存じの方、お教えください。もちろん、ArduinoはTXとRXだけで、フロー制御もできません。現在は充分受信が間に合うように、sleepを入れてます。
non

non
記事: 1097
登録日時: 13年前

Re: VisualBasicとArduino間のシリアル通信方法

#2

投稿記事 by non » 10年前

DataReceivedイベントに割り込みで飛んで、元の処理にはもどるようですね。
DataReceivedでグローバル変数
serialState = 1
にしておき、
元の処理で

コード:

            Do
                System.Threading.Thread.Sleep(10)
            Loop While serialState = 0
で、フラグが立つまで待ちたかったのですが、serialStateが1にならず永久ループで、先に進みません。

部分ではわかりにくいでしょうからVBのコードを貼ります

コード:

Public Class Form1
    Dim comNo As Integer
    Dim Data(100) As Byte
    Dim serialState As Integer
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        'シリアルポートの確立
        ' シリアルポートのオープン
        SerialPort1.PortName = ListBox1.SelectedItem
        ' シリアルポートの通信速度指定
        SerialPort1.BaudRate = 9600
        ' シリアルポートのパリティ指定
        SerialPort1.Parity = IO.Ports.Parity.None
        ' シリアルポートのビット数指定
        SerialPort1.DataBits = 8
        ' シリアルポートのストップビット指定
        SerialPort1.StopBits = IO.Ports.StopBits.One
        ' シリアルポートのオープン
        SerialPort1.Open()
        serialState = 0

        For i = 0 To 99
            serialState = 0
            SerialPort1.Write(Data, i, 1)
            'この3行が問題です
            Do
                System.Threading.Thread.Sleep(10)
            Loop While serialState = 0
        Next

    End Sub
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        GetSerialPortNames() '接続されているCOMポートの表示
        Dim count As Byte = 0
        For i = 0 To 99
            Data(i) = count
            count = count + 1
        Next
    End Sub

    '接続されているCOMポートを表示し、最後のCOMポートを選択する
    Sub GetSerialPortNames()
        ' Show all available COM ports.
        For Each sp As String In My.Computer.Ports.SerialPortNames
            ListBox1.Items.Add(sp)

        Next
        comNo = ListBox1.Items.Count - 1
        ListBox1.SelectedIndex = comNo
    End Sub
    'COMポートの選択
    Private Sub ListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged
        comNo = ListBox1.SelectedIndex
    End Sub
    'SerialPortの中でFormコントロールを直接扱うことができない。セカンダリスレッド(2次スレッドのため)
    '対処として、Invokeメソッドを使う
    Delegate Sub PrintDataDelegate(ByVal sdata As String)  'デリゲート宣言
    'フォームクラスで実行したいメソッド
    Private Sub PrintData(ByVal sdata As String)
        TextBox1.Text &= sdata + vbCrLf
    End Sub

    Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
        Dim ReceiveData As String = ""
        Try
            ReceiveData = SerialPort1.ReadLine
        Catch ex As Exception
            ReceiveData = ex.Message
        End Try
        'MsgBox(ReceiveData)   これはデバッグのためです。
        Dim area As New PrintDataDelegate(AddressOf PrintData) 'インスタンス化 引数には呼び出されるメソッドのアドレス
        Me.Invoke(area, ReceiveData) 'デリゲートしたメソッドの実行
        serialState = 1
    End Sub
End Class
non

non
記事: 1097
登録日時: 13年前

Re: VisualBasicとArduino間のシリアル通信方法

#3

投稿記事 by non » 10年前

なんか自己レスばっかりですね。

C言語で考えれば、変数にvolatileをつけないとだめですね。でも、VBに、volatileってあるの?ないですよね。
どうすればいいのでしょう・・・・?
non

non
記事: 1097
登録日時: 13年前

Re: VisualBasicとArduino間のシリアル通信方法

#4

投稿記事 by non » 10年前

再び、自己レス。
あの3行を下のようにしたら動きました。

コード:

            Do
                Application.DoEvents()
            Loop While serialState = 0
いやーもうちょっと、自分で調べてから、質問すればよかった。(^_^;)

でも、しばらく解決にせずに、大量のデータを送るときの方法論について考えを募集します。よろしく。
non


ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: VisualBasicとArduino間のシリアル通信方法

#6

投稿記事 by ISLe » 10年前

non さんが書きました:もちろん、ArduinoはTXとRXだけで、フロー制御もできません。
ソフトウェアフロー制御も実装できないということですか?

non
記事: 1097
登録日時: 13年前

Re: VisualBasicとArduino間のシリアル通信方法

#7

投稿記事 by non » 10年前

naohiro19さんへ
動画を見ました。有益な情報は含まれていなかったようです。それとも、見逃しましたか。
無料会員登録したので、混雑で止まって途切れ途切れでしたので。

ISLe さんへ
ソフトウェアフローってのはXon,Xoffの制御コードを使う方法ですよね。
Arduinoで用意されているライブラリではXon,Xoffの設定を行うことができません。
自作すればよいのでしょうけど、1から全部作るのは、能力とパワーが足りません。
ですから、安易にコールバックしてみました。チェックサムを返してもよいかも知れません。
non

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: VisualBasicとArduino間のシリアル通信方法

#8

投稿記事 by ISLe » 10年前

既存の規格で作られた通信機器と送受信するのが最終目的なのでしょうか。

そうでなければ受信側は適当に決めた応答コードを返すだけで良いのでは。
安易なコールバックというのが既にそういうものかもしれませんが。

送信側は受信可能サイズでまとめて送れば良いのでは。
サイズ固定だと困るならネゴシエーションすれば良いですし。

non
記事: 1097
登録日時: 13年前

Re: VisualBasicとArduino間のシリアル通信方法

#9

投稿記事 by non » 10年前

>そうでなければ受信側は適当に決めた応答コードを返すだけで良いのでは。

やっぱり、そうなりますよね。1バイトごとにコールバックするのは非効率なので、数十バイト送ってチェックサムをつけることにしました。
これで、解決にします。
non

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: VisualBasicとArduino間のシリアル通信方法

#10

投稿記事 by ISLe » 10年前

『ACK NAK』をキーワードに検索すると良いかもしれません。

閉鎖

“C言語何でも質問掲示板” へ戻る