PCとArduinoをシリアル通信したいのです。PC側はVisualBasicのSerialコントロールを使います。一応、通信はできたのですが、やりたいことはpcから大量のデータをできるだけ高速にArduinoに送信したいのです。Arduinoのバッファは128バイトとの事で、たくさんは蓄えられません。そこで、1バイト(数バイト単位でもよいけど)送信したら、コールバックし、確認後また次の1バイトを送りたいのですが、VisualBasic側でどのような処理をすればよいのでしょう。一般にはDataReceivedイベントで受信を待つのでしょうけど、この関数に飛んだら、元の処理の途中にどうやって戻ればよいのでしょう。このイベントって終わったからって元の処理に戻ってはくれないのでしょうね。
このようにすれば良いよと言う方法をご存じの方、お教えください。もちろん、ArduinoはTXとRXだけで、フロー制御もできません。現在は充分受信が間に合うように、sleepを入れてます。
VisualBasicとArduino間のシリアル通信方法
Re: VisualBasicとArduino間のシリアル通信方法
DataReceivedイベントに割り込みで飛んで、元の処理にはもどるようですね。
DataReceivedでグローバル変数
serialState = 1
にしておき、
元の処理で
で、フラグが立つまで待ちたかったのですが、serialStateが1にならず永久ループで、先に進みません。
部分ではわかりにくいでしょうからVBのコードを貼ります
DataReceivedでグローバル変数
serialState = 1
にしておき、
元の処理で
で、フラグが立つまで待ちたかったのですが、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
Re: VisualBasicとArduino間のシリアル通信方法
なんか自己レスばっかりですね。
C言語で考えれば、変数にvolatileをつけないとだめですね。でも、VBに、volatileってあるの?ないですよね。
どうすればいいのでしょう・・・・?
C言語で考えれば、変数にvolatileをつけないとだめですね。でも、VBに、volatileってあるの?ないですよね。
どうすればいいのでしょう・・・・?
non
Re: VisualBasicとArduino間のシリアル通信方法
再び、自己レス。
あの3行を下のようにしたら動きました。 いやーもうちょっと、自分で調べてから、質問すればよかった。(^_^;)
でも、しばらく解決にせずに、大量のデータを送るときの方法論について考えを募集します。よろしく。
あの3行を下のようにしたら動きました。 いやーもうちょっと、自分で調べてから、質問すればよかった。(^_^;)
でも、しばらく解決にせずに、大量のデータを送るときの方法論について考えを募集します。よろしく。
non
Re: VisualBasicとArduino間のシリアル通信方法
ソフトウェアフロー制御も実装できないということですか?non さんが書きました:もちろん、ArduinoはTXとRXだけで、フロー制御もできません。
Re: VisualBasicとArduino間のシリアル通信方法
naohiro19さんへ
動画を見ました。有益な情報は含まれていなかったようです。それとも、見逃しましたか。
無料会員登録したので、混雑で止まって途切れ途切れでしたので。
ISLe さんへ
ソフトウェアフローってのはXon,Xoffの制御コードを使う方法ですよね。
Arduinoで用意されているライブラリではXon,Xoffの設定を行うことができません。
自作すればよいのでしょうけど、1から全部作るのは、能力とパワーが足りません。
ですから、安易にコールバックしてみました。チェックサムを返してもよいかも知れません。
動画を見ました。有益な情報は含まれていなかったようです。それとも、見逃しましたか。
無料会員登録したので、混雑で止まって途切れ途切れでしたので。
ISLe さんへ
ソフトウェアフローってのはXon,Xoffの制御コードを使う方法ですよね。
Arduinoで用意されているライブラリではXon,Xoffの設定を行うことができません。
自作すればよいのでしょうけど、1から全部作るのは、能力とパワーが足りません。
ですから、安易にコールバックしてみました。チェックサムを返してもよいかも知れません。
non
Re: VisualBasicとArduino間のシリアル通信方法
既存の規格で作られた通信機器と送受信するのが最終目的なのでしょうか。
そうでなければ受信側は適当に決めた応答コードを返すだけで良いのでは。
安易なコールバックというのが既にそういうものかもしれませんが。
送信側は受信可能サイズでまとめて送れば良いのでは。
サイズ固定だと困るならネゴシエーションすれば良いですし。
そうでなければ受信側は適当に決めた応答コードを返すだけで良いのでは。
安易なコールバックというのが既にそういうものかもしれませんが。
送信側は受信可能サイズでまとめて送れば良いのでは。
サイズ固定だと困るならネゴシエーションすれば良いですし。
Re: VisualBasicとArduino間のシリアル通信方法
>そうでなければ受信側は適当に決めた応答コードを返すだけで良いのでは。
やっぱり、そうなりますよね。1バイトごとにコールバックするのは非効率なので、数十バイト送ってチェックサムをつけることにしました。
これで、解決にします。
やっぱり、そうなりますよね。1バイトごとにコールバックするのは非効率なので、数十バイト送ってチェックサムをつけることにしました。
これで、解決にします。
non
Re: VisualBasicとArduino間のシリアル通信方法
『ACK NAK』をキーワードに検索すると良いかもしれません。