【VB.NET】シリアル受信7CHデータをSPLITして個別表示<配列宣言ではまる>

VB.NETのシリアル受信プログラム、3年間食わず嫌いでしたが、ようやくちょこちょこいじりだしました。結局、プログラムは慣れしかありませんので、慣れればその環境が良いと思えるようになるということだとあきらめてやってます。暇と根気がないとできませんので、いつでもできるわけではありません。
●何故VB.NETかというと、
①VBAでは、処理速度が遅すぎて将来困る。
(冬にスキーターン解析用GNSS_RTKシステムのリアルタイムグラフィック作りたい)
②Processingでは、ツールボックスなどオブジェクトUIが弱い点とExcelとのリンクができない点でVB.NETに負けている。
③C#でいけばいいと思ったが、VB.NETのほうがVBAに近いので手ごろ感があるので、VB.NETからVSに入るほうがよい。
一般的なメリットデメリットの記事はたくさんあります。
https://www.fenet.jp/dotnet/column/language/884/

初心者からプロまで、幅広く人気なVB.NETとは?特徴も併せてご紹介

シリアル受信7CHデータを処理する準備にSPLITを使ってみた。
受信データは、6分力センサからFx,FyFz,Mx,MyMz,setNoの7個の
整数がASCIIで送信されてきます。速度は10msec前後で115200bpsです。

Form1(デザイン)は、ボタン2個、TextBox10個、ListBox1個作っておきます。
Form1.vbのコードは、GISTにアップしてあります。

https://gist.github.com/dj1711572002/b8468b3afb09ff1b5bd751a2fd0adb02以下、機能別に解説しておきます。

■全体の概要
シリアル受信のコンテック社様からコピペした基本ソースは
2つのSUB関数からできてます。
①Private Sub PrintData(ByVal sdata As String) 表示する関数
②Private Sub SerialPort1_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
シリアルポート受信関数です。マルチタスクで受信します。

データの流れ沿って解説していきます。

■第一段:VB側の受信データは、receivedData as Stringです。
全7chデータがカンマ区切りで1本のSTRING変数で受信されます

Private Sub SerialPort1_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
Dim ReceivedData As String = ” ” ‘受信データ用変数を宣言しますTryReceivedData = SerialPort1.ReadLine ‘データを受信しますCatch ex As Exception
ReceivedData = ex.Message ‘例外処理を行いますEnd Try
‘Invokeメソッドにより実行されるメソッドへのデリゲートの宣言を行い、受信データを表示します
Dim adre As New DataDelegate(AddressOf PrintData)
Me.Invoke(adre, ReceivedData)End Sub


■第二段:PrintData()でデータを処理する
SerrialPort1_DataReceived()では、表示処理するとエラーがでたので
PrintData()にデータ処理と表示機能をまとました。
受信データは、ReceiveDataからsdataとして引数として渡されます。
■第三段:SPLITでカンマ区切りのデータをばらす(配列宣言ではまった)
SPLITの使い方はMSDOCにあります。
https://docs.microsoft.com/ja-jp/dotnet/api/microsoft.visualbasic.strings.split?view=netcore-3.1

以下上記リンクから抜粋 例文
Dim testString As String = “Look at these!”
‘ Returns an array containing “Look”, “at”, and “these!”.
Dim testArray() As String = Split(testString)

何もパラメータをつけてない場合はデフォルトで空白文字がデリミタになります。

▼配列宣言ではまった
①SPLIT
受け取る文字列配列をその場でDim宣言することが手間とトラブル防止になります。私は、上部で配列宣言してから、Redimしたのですが、エラーから抜け出せなくなってしまい、サンプル通りにSplit行で配列宣言をしたらエラーから抜け出せました。未だ、原因わからないのですが、初心者のうちは、サンプル通りにコピペしていったほうがいいと感じました。
②宣言の位置
CLASSとかメソッド(関数)を使ったプログラミングあまりしてこんかったので、メソッド内で宣言した変数がプログラムポインタがメソッドを抜け出した瞬間にゼロになってしまって、不思議な現象ではまりました。
CLASS内で共通して使う変数はCLASS直下で宣言しないとだめなことを怠ってしまって1日無駄しました。

 

パラメーター

Expression
String

必須。 部分文字列および区切り記号を含む String 型の式。

Delimiter
String

省略可能。 文字列の区切りを識別するために使用する任意の 1 文字。 Delimiter が省略された場合、空白文字 (” “) が区切り記号として使用されます。

Limit
Int32

省略可能。 入力文字列を分割する場合の部分文字列の最大数。 既定値の -1 は、Delimiter 文字列が出現するたびに入力文字列が分割されることを示しています。

Compare
CompareMethod

省略可能。 部分文字列を評価する場合に使用する比較を示す数値。 値については、「設定」を参照してください。

戻り値

String[]

String 配列 Expression が長さ 0 の文字列 (“”) の場合、Split は、長さ 0 の文字列を含む単一要素の配列を返します。 Delimiter が長さ 0 の文字列である場合、または Expression に Delimiter がない場合に、Split は Expression 型の文字列を含む単一要素の配列を返します。

■第4段:printData()コード(GIST
デバッグ用に無駄な部分がついてますが、やっていることは単純で、

sdataをSPLITしてdStr文字列配列にばらして、整数2次元配列dataAry(dataNo,i)に格納してます。
 SPLITの結果は、dSTr()をTextBox4-10に表示させてます。
dataAry()は、60万個までRedimで確保してありますが、エラーになりません。

Private Sub PrintData(ByVal sdata As String)
Dim dataNo As IntegerDim delimiter As String = “,”
Dim dataAry(,) As Integer
Dim dcount As String
Timer1.Interval = 1
‘タイマー開始
Timer1.Enabled = True
‘TextBox1.text=sdata
dcount = sdata & “:” & TextBox2.Text
ListBox1.Items.Add(dcount)
Dim dStr() As String = Split(sdata, delimiter, -1, CompareMethod.Text)
If (dStr.Length > 6) Then
dataNo = CInt(TextBox2.Text) + 1ReDim dataAry(600000, dStr.Length)
For i = 0 To dStr.Length – 1
dataAry(dataNo, i) = CInt(dStr(i))
TextBox2.Text = dataNo
TextBox3.Text = dStr.Length
TextBox4.Text = dStr(0)
TextBox5.Text = dStr(1)
TextBox6.Text = dStr(2)
TextBox7.Text = dStr(3)
TextBox8.Text = dStr(4)
TextBox9.Text = dStr(5)
TextBox10.Text = dStr(6)
‘ Debug.Print(CStr(dataNo) & “,” & CStr(i) & “,” & CStr(dataAry(dataNo, i)))Next
End If
End Sub

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です