こんにちは、ENGかぴです。
VB.NET(Visual Basic2022)のデスクトップアプリでシリアルポート(SerialPort)を実装してシリアル通信を行う方法や存在するシリアル通信のポートを検索してデバイス名を含めて表示する方法をまとめました。
外部機器のArduino UNOとシリアル通信を行い動作確認を行います。以下はVisual Basic 2022をVB2022とします。
VB.NET(VB2022)のデスクトップアプリで動作確認したことを下記リンクにまとめています。
VB.NET(VB2022)のデスクトップアプリ開発でできること
SerialPortを実装する
スタートメニューからVisual Studio 2022を起動し、VB2022のプロジェクトを作成します。初期配置されているフォームにボタンを実装しイベントを追加します。
毎回スタートメニューから開くのが面倒な場合はタスクバーにピン止めもしくはスタートメニューのVisual Studio 2022を左クリックで選択した状態でデスクトップにリンクコピーしても良いと思います。
広告
PR:わからないを放置せず、あなたにあったスキルを身に着けるコツを教える テックジム 「書けるが先で、理解が後」を体験しよう!
SerialPortを使って作成するアプリ
本記事ではシリアル通信のCOMポートを選択して外部機器と通信をするアプリを作成します。
テキストボックスにデータを入力し「送信」を押すと外部機器に入力したデータを送信します。外部機器からの受信した文字列を下のテキストボックスに表示します。
作成したアプリと外部機器(Adruino UNO)をUSB接続でシリアル通信を行います。
プロジェクトの作成
プロジェクトの作り方は下記記事のVisual Studio(VB2022)のプロジェクトを作成する を参考にしてください。
Visual Studio 2022によるVBの開発環境の作り方
本記事ではプロジェクト名とソリューション名を「SerialTest」にしています。
SerialPortの追加
初期で配置されているForm1.vb[デザイン]にSerialPortを追加します。ツールボックスのコンポーネントからSerialPortを選択します。(すべてのWindowsフォームからも選択できます。)Form1を任意の名称に変更している場合はForm1を変更した名前に置き換えて下さい。
SerialPortを選択した状態でフォーム内を左クリック、またはSerialPortを選択してダブルクリックするとSerialPortが追加されます。SerialPortはSerialPort1のように追加した順に番号が付加されます。
SerialPort1を選択するとプロパティが表示されます。私が良く使用しているプロパティについてまとめました。
項目 | 説明 |
---|---|
PortName | 通信ポートを指定します。 例)COM1、COM10 |
BaudRate | 通信のボーレートを指定します。 例)115200、9600、19200 |
Databits | データのビット数を指定します。(最近は8ビットのものが多い) 例)7、8 |
Parity | パリティーチェックの使用方法を指定します。 例)None、Odd、Even、Mark、Space |
StopBits | ストップビットを指定します。 例)One、Two、OnePointFive |
Handshake | データ交換のフロー制御のハンドシェークを指定します。 例)None、XOnXOff、RequestTosend、RequestToSendXOnXOff |
ReadBufferSize | 読み取りバッファーのサイズを指定します。 このサイズを超える前にRead()でデータを読み込む必要があります。 |
WriteBufferSize | 送信するデータを一時保管するサイズを指定します。 このサイズを超えて送信する場合は分割する必要があります。 |
通信相手となる外部機器の通信仕様を確認するのが一番ですが、最近ではPortNameとボーレート以外のプロパティは変更せずデフォルト値で動作することが多い印象です。
基本的にRtsEnabled及びDtrEnableはデフォルトの通りFalseで指定し、通信できなければ必要に応じてTrueを指定する確認方法でよいと思います。
コントロールの実装
SerialPortの動作確認を行うため各種コントロールをFormに追加します。コントロールの実装とイベントの追加の方法を下記記事にまとめています。
VB.net(VB2022)のボタンの実装とイベントの追加方法
Formにツールボックスからコントロールを追加し、一部のプロパティを変更します。
GroupBox1の中にComboBox1、ComboBox2、Button1、Button2を配置します。GroupBox1のTextプロパティを「シリアル通信」に変更します。
ComboBox1はSerialPort1のPortName(COMポート)の指定に使用します。ComboBox2はシリアル通信のBaudRate(ボーレート)の指定に使用します。どちらもソースコードで選択肢を追加します。
Button1はCOMポートの再検索に使用します。Textプロパティを「再検索」に変更します。BackColorプロパティをWebタブからLightGreenに変更します。
Button2はCOMポートの設定(PortName、ボーレート、その他)の条件でポートを開きます。Textプロパティを「オープン」に変更します。BackColorプロパティをWebタブからLightGreenに変更します。
Button3はTextbox1に入力した文字の送信に使用します。Textプロパティを「送信」に変更します。BackColorプロパティをWebタブからLightGreenに変更します。
Button4はTextbox2のクリアに使用します。Textプロパティを「テキストクリア」に変更します。BackColorプロパティをWebタブからLightGreenに変更します。
Textbox1は送信する文字列を入力します。デバッグで文字を入力するのは手間なのでTextプロパティを「Serial Test 1234」に変更します。この文字列はデバッグで任意の文字に変更できます。
Textbox2は外部機器から受信した文字列を表示します。MultiLineプロパティにTrueを指定します。ReadOnlyプロパティをTrueを指定して文字を書き込めないようにします。ReadOnlyプロパティをTrueにするとデフォルトでBackColorがControl色になるためBackColorプロパティをWebタブからWhiteに変更します。
広告
マイベスト3年連続1位を獲得した実績を持つ実践型のプログラミングスクール
変数の宣言
アプリで共通する変数を宣言する場合はフォームクラス内で変数を宣言する必要があります。VBの場合はDimでメモリに変数を割り当てます。
Public Class Form1
Structure TYP_COMRING
Dim rp As Integer
Dim wp As Integer
Dim dat() As Byte
End Structure
Dim RxRing As TYP_COMRING’受信したデータを管理
End Class
例ではアプリ全体で使用できるTYP_COMRINGの型の変数をRxRingで宣言しています。クラス内で宣言した場合はアプリを終了しない限りメモリを割り当てた状態になります。
RxRingはSerialPort1で受信したデータを格納するために使用します。wpで格納場所を更新しながら受信したデータを格納します。rpは受信したデータを表示したときに更新します。
wpとrpの差で受信したデータの有無を確認しTextbox2に文字列として表示します。
イベントの追加
Button1などのコントロールに対してイベントの追加を行う必要があります。エディターを選択している状態でF7を押すか、右クリックで表示されるメニュー「コードの表示(C)」を選択するとコードの編集画面(Form1.vb)に遷移します。次のイベントを追加します。
- フォームを呼び出したときに一度だけ処理するLoadイベント
- SerialPort1がデータを受信したときに呼び出すDataReceivedイベント
- Timer1がインターバルの間隔で呼び出された時に処理するTickイベント
- Button1をクリックしたときに呼び出すClickイベント
- Button2をクリックしたときに呼び出すClickイベント
- Button3をクリックしたときに呼び出すClickイベント
- Button4をクリックしたときに呼び出すClickイベント
1~6のイベントは、クリックとダブルクリックで追加することができます。フォームのLoadイベントはForm1[デザイン]をダブルクリックすると追加されます。ButtonのClickイベントはButton1~Button4をダブルクリックするとがイベントが追加されます。
Loadイベント、Clickイベント以外を追加する場合もあるため、以下ではコードエディターでSerialPort1のDataReceivedイベントを追加する方法を説明します。
コントロール選択でSerialPort1を選択します。コントロール選択の横にあるイベント一覧からDataReceivedを選択するとイベントが追加できます。イベントを選択すると自動でイベントのハンドラが生成されます。
Private Sub SerialPort1_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
'処理を追加
End Sub
自動生成されたサブルーチンの後方にHandles SerialPort1.DataReceivedのように記述されている部分がイベントの発生要因になります。生成したサブルーチンに処理を追加します。
PR:わからないを放置せず、あなたにあった最低限のスキルを身に着けるコツを教える テックジム 「書けるが先で、理解が後」を体験しよう!
フォームを読み込んだ時に初期化
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ComboInit() 'Comboboxを初期化する
RxRingInit() 'RxRingの初期化を行う
End Sub
Form1_Load()関数はForm1が読み込まれた時に一度だけイベントが発生します。自作の関数でComboBoxの初期化、RxRingの初期化を行います。
'Comboboxを初期化する
Private Sub ComboInit()
ComPortChk() 'ComboBox1の初期化(ポートの検索)
ComboBox2.Items.Add("9600")
ComboBox2.Items.Add("19200")
ComboBox2.Items.Add("115200")
ComboBox2.Text = "115200"
End Sub
ComboInit()関数はComboBoxの初期化を行います。ComboBox1の初期化はComPortChk()関数で行います。
ComboBox2はItemsプロパティのAdd()メソッドで選択肢を追加しています。初期の表示のためTextプロパティに115200を指定しています。
'存在するポートを検索する
Private Sub ComPortChk()
Dim comno() As String = SerialPort.GetPortNames
Dim i As Integer
ComboBox1.Items.Clear() 'アイテムをクリア
If comno.Length = 0 Then
ComboBox1.Text = "COMポートがみつかりません。"
Else
For i = 0 To comno.Length - 1
ComboBox1.Items.Add(comno(i))
Next
ComboBox1.Text = comno(0)
End If
End Sub
SerialPortクラスのGetPortNames()メソッドで存在するCOMポートの番号を取得します。複数存在することがあるためcomno[]配列で格納しています。取得したCOMポートをComboBox1に追加します。追加を繰り返すと同じCOMポートが追加されてしまうため、ItemsプロパティをClear()メソッドでクリアします。
COMポートが存在する場合はComboBox1のItemsプロパティのAdd()メソッドで追加します。ComboBox1の初期表示のためTextプロパティに配列の0番目の文字列を指定しています。
SerialPort1が受信したデータを格納
Private Sub SerialPort1_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
Dim sz As Integer = SerialPort1.BytesToRead
Dim i As Integer
Dim rxdat(sz - 1) As Byte
SerialPort1.Read(rxdat, 0, sz)
For i = 0 To sz - 1
RxRingSet(rxdat(i))
Next
End Sub
SerialPortクラスのBytesToRead()メソッドで受信したバイト数をSerialPort1の受信バッファから取得します。rxdat()はSerialPort1に保管されているデータを一時格納するために使用します。
SerialPortクラスのRead()メソッドでSerialPort1に保管されているデータを読み込みます。第1引数にデータの格納先のアドレスを指定します。第2引数にデータの読み込みのオフセットを指定します。第3引数にデータ数を指定します。次に一時保管したrxdat()のデータをRxRingに格納します。
'RxRingのwpを更新する
Public Sub RxRingSet(ByVal dat As Byte)
RxRing.dat(RxRing.wp) = dat
RxRing.wp += 1
If RxRing.wp = RxRing.dat.Length Then
RxRing.wp = 0
End If
End Sub
RxRingSet()関数はSerialPort1から取得したデータをRxRingのwpを更新しながら格納する自作の関数です。
引数に格納するデータを指定します。RxRing.dat[]にデータを格納するとwpを更新します。wpの更新がRxRing.dat[]の総数を超えると0に戻します。
Timer1のインターバル処理
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Dim sz As Integer
Dim i As Integer
sz = RxRing.wp - RxRing.rp
If sz < 0 Then
sz += RxRing.dat.Length
End If
If sz > 0 Then
For i = 0 To sz - 1
TextBox2.Text &= Chr(RxRing.dat(RxRing.rp))
RingRpAdd()
Next
End If
End Sub
Timer1のEnabledをTrueにするとインターバル毎にTimer_Tick()のイベントが発生します。インターバル毎に受信データのサイズをwpとrpの差を計算して確認します。サイズが0未満の場合はwpがRxRing.dat[]の総数を超えて0に戻ったことになるためRxRing.dat[]の総数を加えてサイズとします。
サイズが0より大きい場合はTextBox2のTextプロパティに文字を追加します。RxRing.dat[]のデータをChr()メソッドで文字コードに対応する文字に置き換えて追加します。
文字を追加すると同時にRingRpAdd()関数でRxRing.rpを更新して受信データを処理したと判断します。
'RxRingのrpを更新する
Private Sub RingRpAdd()
RxRing.rp += 1
If RxRing.rp >= RxRing.dat.Length Then
RxRing.rp = 0
End If
End Sub
RingRpAdd()関数はRxRingのrpを更新する自作の関数です。rpはデータの読み込みが完了した場合に更新します。
RxRing.rpを+1してrpを更新します。rpの更新がRxRing.dat[]の総数を超えると0に戻します。
Button1をクリック
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ComPortChk() '存在するポートを検索する
End Sub
Button1をクリックするとButton1_Click()のイベントが発生します。Button1はCOMポートを再検索する処理を追加します。処理はフォームを読み込んだ時に初期化で使用しているComPortChk()関数で行います。
Button2をクリック
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
PortOpen() 'ポートをオープンする
End Sub
'ポートをオープンする
Private Sub PortOpen()
Try
With SerialPort1
.Close() 'ポートを閉じる
.PortName = ComboBox1.Text
.BaudRate = ComboBox2.Text
.DataBits = 8
.Parity = Parity.None
.StopBits = StopBits.One
.Handshake = Handshake.None
.RtsEnable = False
.DtrEnable = False
.Open() 'ポートをオープンする
End With
Timer1.Enabled = True
Catch ex As Exception
MsgBox(ComboBox1.Text & "をオープンできませんでした。", MsgBoxStyle.OkOnly)
End Try
End Sub
Button1をクリックするとButton2_Click()のイベントが発生します。COMポートをオープンする処理を追加します。処理は自作のPortOpen()関数で行います。
COMポートのオープンに失敗した場合にアプリが強制終了しないようにTry Catch文で処理を行います。Tryの部分に処理する内容を追加します。Catchの部分には失敗したときの処理を追加します。
SerialPort1の設定を指定します。Close()メソッドで現在のCOMポートをクリアします。PortNameとBaudRateの設定はComboBox1、ComboBox2で選択した値を使用します。残りの項目は通信相手に合わせた固定の値を指定します。Open()メソッドでCOMポートをオープンします。
PR:無料トライアル実施中【PC専用】AIスライド資料作成ツールの利用:イルシル
Button3をクリック
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
If SerialPort1.IsOpen Then
SerialPort1.Write(TextBox1.Text)
End If
End Sub
Button3をクリックするとButton3_Click()のイベントが発生します。TextBox1のTextプロパティに指定されている(テキストに入力した文字列)を送信する処理を追加します。
COMポートがオープンしていない状態で送信しようとするとアプリが強制終了してしまうので、COMポートの状態をIsOpenメソッドで確認します。COMポートがオープンしている場合はWrite()メソッドの引数に文字列を指定してデータを送信します。
Button4をクリック
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
TextBox2.Clear()
End Sub
Button4をクリックするとButton4_Click()のイベントが発生します。TextBox2のTextプロパティに指定されている(テキストに入力した文字列)をクリアする処理を追加します。
Clear()メソッドでTextBoxのTextプロパティをクリアします。
ポート検索でデバイス名を表示する方法
COMポートを検索するとCOM1やCOM7とCOM番号が表示されます。COM番号のみの表示の場合、複数ポートが存在する場合に対象の機器がどれかが分かりにくいことがあります。デバイス名を表示して対象の機器を判別しやすくする方法をまとめました。
デバイス名を取得するためにレジスタを参照する必要があります。WMI(Windows Management Instrumentation)を使用してレジスタの情報を取得するためSystem.Management.dllを追加します。
ソリューションエクスプローラー内のMy projectを選択して参照設定を開きます。ダブルクリックするか右クリックから「開く」を選択すると参照設定が表示されます。「追加(A)」をクリックします。
アセンブリからSystem.Managementを一覧から選択しチェックを入れて「OK」をクリックするとプロジェクトSystem.Managementがインポートされて使用することができます。
System.Managementで使用するWin32_SerialPortクラスについては下記リンクに詳細があります。
Win32_SerialPort クラス – Win32 apps | Microsoft Learn
Win32_SerialPortクラスからデバイス名を表示するためNameプロパティを使用します。WMIから取得したデバイス名を表示する例は以下の通りです。
'存在するポートを検索する
Private Sub ComPortChk2()
Dim mngstr As New Management.ManagementObjectSearcher("Select * from Win32_SerialPort")
Dim mc As Management.ManagementObjectCollection
Dim serial As Management.ManagementBaseObject
Dim comno() As String = SerialPort.GetPortNames
Dim i, j As Integer
Dim serialcnt As Integer
Dim comcnt As Integer
Dim strno As Byte
Dim str As String
Dim comstr As String
mc = mngstr.Get()'Searcherの結果を取得
serialcnt = mc.Count
comcnt = comno.Length
ReDim ComInfo(serialcnt - 1)
For Each serial In mc
ComInfo(i).dvicename = serial("Name")
strno = InStr(ComInfo(i).dvicename, "(COM")
If strno <> 0 Then
strno += 1
comstr = ""
For j = 0 To 6
str = Mid(ComInfo(i).dvicename, strno + j, 1)
If str <> ")" Then
comstr &= str
Else
Exit For
End If
Next
ComInfo(i).comno = comstr
End If
i += 1
Next
ComboBox1.Items.Clear() 'アイテムをクリア
If serialcnt = 0 Then
ComboBox1.Text = "COMポートがみつかりません。"
Else
For i = 0 To ComInfo.Length - 1
ComboBox1.Items.Add(ComInfo(i).dvicename)
Next
ComboBox1.Text = ComInfo(0).dvicename
End If
End Sub
System.Management(NameSpace名)内で定義されているクラスを使用します。デバイス名を取得するためにManagementObjectSearcher()クラスの変数としてmngstrをインスタンス化します。引数は管理情報に対するクエリを指定します。
例はシリアル通信ポートの情報が格納しているWin32_SerialPortクラスからすべての情報を取得する命令(クエリ)を指定しています。
ManagementObjectSearcher()で取得した結果をGet()メソッドで取得し、ManagementObjectCollectionクラスの変数のmcに格納します。
For Each分は指定した要素の分だけ繰り返すループです。ManagementBaseObjectクラスの変数のserialが要素になりますが、INによってmcの情報が引き継がれた状態でループします。
ManagementBaseObjectクラスは引数でプロパティ指定することができます。Win32_SerialPortクラスのプロパティからNameを指定して取得した結果をComInfo[].dvicenameに格納します。
取得したデバイス名にCOMXXとCOM番号が入っていますが、デバイス名を含めた状態ではCOMポートのオープンに使用できないためCOM番号のみを指定できるようにデバイス名からCOMXXの部分だけを抜き取ったデータを準備する必要があります。
InStr()メソッドで「(COM」が含まれていることを確認し、Cの位置から「)」までの文字列を連結してCOMXXのデータを生成しComInfo[].comnoに格納しています。
ComboBox1の表示にComInfo[].dvicenameを使用しCOMポートのオープンにComInfo[].comnoを使用することでデバイス名で選択したCOMポートをオープンすることができます。
動作確認(デバッグ)
イベントの処理を追加した後は動作確認(デバッグ)を行います。デバッグは実際のアプリケーションの動作を模擬して実行するものです。デバッグの開始はエディタ上部の「▶開始」(赤枠)をクリックすると開始します。
Arduino UNOをUSB接続して待機させます。デバッグの開始でアプリをスタートし、接続先をArduino Uno(COM10)を選択します。COM10は使用する環境によって番号が異なることがあります。ボーレートをArduino UNOと揃えて115200を選択します。
オープンをクリックするとCOMポートがオープンします。Textbox1にArduino UNOに送信する文字を入力します。(入力するのが面倒なのでTextプロパティにSerial Test 1234を指定しています。)
「送信」をクリックするとArduino UNOに文字列を送信します。Arduino UNOからの返信は下のテキストボックスに表示されます。動作確認の結果では複数回送信を押した結果が表示されています。「テキストクリア」をクリックすると受信した文字列をクリアできます。
Arduino UNOのUSBを抜いて再検索するとCOMポートが消えていることも確認できました。また、再度接続し「再検索」をクリックするとArduino UNOのCOMポートが表示されることも確認できました。
コードのデバッグを行う場合は、コードエディタでブレークポイントを置くことで一時的にプログラムを停止させることができます。
ブレークポイントはコードエディターの最左部分をクリックして●マークが表示されれば設置できています。例ではButton3がクリックされた時に発生したイベントの先頭部分にブレークポイントを置いています。この状態でButton3をクリックするとブレークポイントでプログラムが一時停止します。
F11を押すとステップ実行になるため1行ずつ内容を確認しながらデバッグを行うことができます。上部の「▶続行(C)」をクリックするとブレークポイント状態から通常の動作に復帰します。
ソースコード全体
以下のソースコードはコンパイルして動作確認をしております。コメントなど細かな部分で間違っていたりやライブラリの更新などにより動作しなくなったりする可能性があります。参考としてお使いいただければと思います。
Imports System.IO.Ports
Public Class Form1
#Const MNI_ENABLE = 1'1:WMI有 0:WMI無し
Const RXRGSZ As Integer = 64
Structure TYP_COMRING
Dim rp As Integer
Dim wp As Integer
Dim dat() As Byte
End Structure
Structure COM_PORT
Dim dvicename As String
Dim comno As String
End Structure
Dim RxRing As TYP_COMRING '受信したデータを管理
Dim ComInfo() As COM_PORT
Dim selectComNo As Integer
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ComboInit() 'Comboboxを初期化する
RxRingInit() 'RxRingの初期化を行う
End Sub
'RxRingの初期化を行う
Private Sub RxRingInit()
RxRing.wp = 0
RxRing.rp = 0
ReDim RxRing.dat(RXRGSZ - 1)
End Sub
'Comboboxを初期化する
Private Sub ComboInit()
#If MNI_ENABLE Then
ComPortChk2()
#Else
ComPortChk() 'ComboBox1の初期化(ポートの検索)
#End If
ComboBox2.Items.Add("9600")
ComboBox2.Items.Add("19200")
ComboBox2.Items.Add("115200")
ComboBox2.Text = "115200"
End Sub
'存在するポートを検索する
Private Sub ComPortChk()
Dim comno() As String = SerialPort.GetPortNames
Dim i As Integer
ComboBox1.Items.Clear() 'アイテムをクリア
If comno.Length = 0 Then
ComboBox1.Text = "COMポートがみつかりません。"
Else
For i = 0 To comno.Length - 1
ComboBox1.Items.Add(comno(i))
Next
ComboBox1.Text = comno(0)
End If
End Sub
'存在するポートを検索する
Private Sub ComPortChk2()
Dim mngstr As New Management.ManagementObjectSearcher("Select * from Win32_SerialPort")
Dim mc As Management.ManagementObjectCollection
Dim serial As Management.ManagementBaseObject
Dim comno() As String = SerialPort.GetPortNames
Dim i, j As Integer
Dim serialcnt As Integer
Dim comcnt As Integer
Dim strno As Byte
Dim str As String
Dim comstr As String
mc = mngstr.Get()
serialcnt = mc.Count
comcnt = comno.Length
ReDim ComInfo(serialcnt - 1)
For Each serial In mc
ComInfo(i).dvicename = serial("Name")
strno = InStr(ComInfo(i).dvicename, "(COM")
If strno <> 0 Then
strno += 1
comstr = ""
For j = 0 To 6
str = Mid(ComInfo(i).dvicename, strno + j, 1)
If str <> ")" Then
comstr &= str
Else
Exit For
End If
Next
ComInfo(i).comno = comstr
End If
i += 1
Next
ComboBox1.Items.Clear() 'アイテムをクリア
If serialcnt = 0 Then
ComboBox1.Text = "COMポートがみつかりません。"
Else
For i = 0 To ComInfo.Length - 1
ComboBox1.Items.Add(ComInfo(i).dvicename)
Next
ComboBox1.Text = ComInfo(0).dvicename
End If
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
#If MNI_ENABLE Then
ComPortChk2() '存在するポートを検索する
#Else
ComPortChk() '存在するポートを検索する
#End If
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
PortOpen() 'ポートをオープンする
End Sub
'ポートをオープンする
Private Sub PortOpen()
Try
With SerialPort1
.Close() 'ポートを閉じる
#If MNI_ENABLE Then
.PortName = ComInfo(selectComNo).comno
#Else
.PortName = ComboBox1.Text
#End If
.BaudRate = ComboBox2.Text
.DataBits = 8
.Parity = Parity.None
.StopBits = StopBits.One
.Handshake = Handshake.None
.RtsEnable = False
.DtrEnable = False
.Open() 'ポートをオープンする
End With
Timer1.Enabled = True
Catch ex As Exception
MsgBox(ComboBox1.Text & "をオープンできませんでした。", MsgBoxStyle.OkOnly)
End Try
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
SerialWrite()
End Sub
Private Sub SerialWrite()
If SerialPort1.IsOpen Then
SerialPort1.Write(TextBox1.Text)
End If
End Sub
Private Sub SerialPort1_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
Dim sz As Integer = SerialPort1.BytesToRead
Dim i As Integer
Dim rxdat(sz - 1) As Byte
SerialPort1.Read(rxdat, 0, sz)
For i = 0 To sz - 1
RxRingSet(rxdat(i))
Next
End Sub
'RxRingのwpを更新する
Public Sub RxRingSet(ByVal dat)
RxRing.dat(RxRing.wp) = dat
RxRing.wp += 1
If RxRing.wp = RxRing.dat.Length Then
RxRing.wp = 0
End If
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Dim sz As Integer
Dim i As Integer
sz = RxRing.wp - RxRing.rp
If sz < 0 Then
sz += RxRing.dat.Length
End If
If sz > 0 Then
For i = 0 To sz - 1
TextBox2.Text &= Chr(RxRing.dat(RxRing.rp))
RingRpAdd()
Next
End If
End Sub
'RxRingのrpを更新する
Private Sub RingRpAdd()
RxRing.rp += 1
If RxRing.rp >= RxRing.dat.Length Then
RxRing.rp = 0
End If
End Sub
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
TextBox2.Clear()
End Sub
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
selectComNo = ComboBox1.SelectedIndex
End Sub
End Class
MNI_ENABLEの値を0から0以外に切り替えることでデバイス名の表示を切り替えることができます。
コントロールの番号やイベントハンドラーなどのプロパティ名などを変更している場合はソースコードのイベントハンドラーをお使いのイベントハンドラーに置き換えて使用してください。
動作確認のため使用したArduinoのソースコードは以下の通りです。
void setup() {
Serial.begin(115200);
}
void loop() {
while(Serial.available()){
Serial.write(Serial.read());
}
}
受信した文字列をそのまま返信するソースコードです。
関連リンク
VB.NET(VB2022)のデスクトップアプリで動作確認したことを下記リンクにまとめています。
VB.NET(VB2022)のデスクトップアプリ開発でできること
マイクロソフトはVisual Studio以外にもVSCodeという便利なエディターを提供しています。下記リンクではVSCodeのインストールの仕方からC言語開発環境の作り方までをまとめています。
最後まで、読んでいただきありがとうございました。
VB.netでシリアル通信を使用することでArduino UNOなどシリアル通信ができるマイコンに対して任意の電文を送信するデバッグができるようになります。