VB.net(VB2022)のTrackBarの実装とイベントの追加方法

組み込みエンジニア
本記事はプロモーションが含まれています。

こんにちは、ENGかぴです。

Visual Basic 2022はMicroSoft社がVisual Studioで提供している開発環境です。Visual Basic2022のデスクトップアプリでトラックバー(TrackBar)の実装とイベントの追加方法をまとめました。

TrackBarを実装したアプリの動作確認として、TrackBarのスライダーを操作したときに外部機器に電文を送信します。外部機器はSeeeduino XIAO(拡張基板:Seeed Studio XIAO Expansion board)を使用します。

Visual Studio Community 2022のインストール方法については下記記事にまとめています。

Visual Studio 2022によるVBの開発環境の作り方

Visual Basic 2022を以下ではVB2022とします。

TrackBarを実装する

VB2022のプロジェクトを作成します。初期配置されているフォームにボタンを実装しイベントを追加します。プロジェクトの作り方は下記記事を参考にしてください。

Visual Studio 2022によるVBの開発環境の作り方

本記事ではプロジェクト名とソリューション名を「trackbar」にしています。

スポンサーリンク

TrackBarを使って作成するアプリ

本記事で作成するアプリの動作画面
本記事で作成するアプリの動作画面

本記事ではTrackBarのスライダーを操作して生成した電文をシリアル通信を使って外部機器に送信するアプリを作成します。シリアル通信の実装は下記記事のものを流用して実装しています。

VB.net(VB2022)のSerialPortの実装とイベントの追加方法

シリアル通信のGroupBox部分を流用して使用しています。

TrackBarの追加

Form1.vb[デザイン]にTrackBarを追加します。ツールボックスのすべてのWindows FormsからTrackBarを選択します。Form1を任意の名称に変更している場合はForm1を変更した名前に置き換えて下さい。

TrackBarの追加
TrackBarの追加

TrackBarを選択した状態でForm1.vb[デザイン]内を動くマウスのポインタが選択したコントロールのアイコンになっているので、左クリックするとボタンが配置されます。左クリックした状態でマウスを移動することでサイズを調整しながら配置することもできます。

マウスによる配置の移動やサイズの移動もできますが、コントロールのプロパティで直接指定する方法もあります。プロパティで直接指定する方法でボタンの位置とサイズを指定する方法を説明します。本記事で使用するプロパティ項目は以下の通りです。

項目説明
Maximumスライダーの最大値を指定します。
RGB LEDの操作量の最大である255を指定しています。
SmallChangeスライダーが移動するポジションの数を指定します。
方向キーで操作量が5変化するように指定しています。
TickFrequency目盛りの数を指定します。
サイズに対する割合で目盛りが振られます。
Locationフレーム上部左端から見た時のコントロール左上の座標を指定する。
Sizeコントロールのサイズを指定します。
使用するプロパティの項目

デザインの画面ではスライダーが青色になっていますが、デバッグ中やアプリとして動作させるとスライダーの色がコントロール色(環境によって青のまま使用出来たりします)になってしまいます。スライダーの色を変更するプロパティがないためデフォルトの状態で使用しています。

自作のコントロールを作成することでスライダーの色を変更することができますがデフォルトの状態でも問題なく使用できるため問題ないと思います。

広告

その他コントロールの実装

各種コントロールをFormに各種コントロール追加します。コントロールの実装とイベントの追加の方法を下記記事にまとめています。

VB.net(VB2022)のボタンの実装とイベントの追加方法

ツールボックスからコントロールを追加し、一部のプロパティを変更します。

コントロールの追加
コントロールの追加

GroupBox1の中にComboBox1、ComboBox2、Button1、Button2を配置します。GroupBox1のTextプロパティを「シリアル通信」に変更します。

ComboBox1はSerialPort1のPortName(COMポート)の指定に使用します。ComboBox2はシリアル通信のBaudRate(ボーレート)の指定に使用します。どちらもソースコードで選択肢を追加します。

Button1はCOMポートの再検索に使用します。Textプロパティを「再検索」に変更します。BackColorプロパティをWebタブからLightGreenに変更します。

以下で追加するコントロールの赤文字がサイズ、青文字がロケーションとします。ロケーションとサイズは目安なので任意でも問題ありません。

GroupBox2を配置しTextプロパティを「操作盤」に変更します。GroupBox2の中にLabel1~6、TrackBar1~3を配置します。

Label1はTrackBar1の値の表示に使用します。Label2はTrackBar2の値の表示に使用します。Label3はTrackBar3の値の表示に使用します。

Label4~6は表示用のラベルとして使用します。それぞれのTextプロパティを「RED:」、「GREEN:」、「BLUE:」に変更します。

変数の宣言

アプリで共通する変数を宣言する場合はフォームクラス内で変数を宣言する必要があります。VBの場合はDimでメモリに変数を割り当てます。

Public Class Form1

    Dim timTrack As Integer'トラックバー操作後、データ送信遅延

End Class

例ではアプリ全体で使用できるtimTrackを宣言しています。クラス内で宣言した場合はアプリを終了しない限りメモリを割り当てた状態になります。

timTrackはTrackBar1~3を操作したときにタイマをスタートする用途で使用します。タイムアップしたときにTrackBar1~3の値をシリアル通信で外部機器に送信します。

広告

イベントの追加

TrackBar1などのコントロールに対してイベントの追加を行う必要があります。エディターを選択している状態でF7を押すか、右クリックで表示されるメニュー「コードの表示(C)」を選択するとコードの編集画面(Form1.vb)に遷移します。次のイベントを追加します。

  1. フォームを呼び出したときに一度だけ処理するLoadイベント
  2. ComboBox1でCOMポートを選択したときに呼び出すSelectedIndexChangedイベント
  3. Timer1がインターバルの間隔で呼び出された時に処理するTickイベント
  4. TrackBar1を操作したときに呼び出すValueChangedイベント
  5. TrackBar2を操作したときに呼び出すValueChangedイベント
  6. TrackBar3を操作したときに呼び出すValueChangedイベント

1のフォームのLoadイベントはForm1[デザイン]をダブルクリックすると追加されます。2のイベントはComboBox1をダブルクリックすると追加されます。4~6のValueChangedイベントはコードエディターでイベントを追加します。

ValueChangedイベントを追加する方法
ValueChangedイベントを追加する方法

コントロール選択でTrackBar1を選択します。コントロール選択の横にあるイベント一覧からValueChangedを選択するとイベントが追加できます。イベントを選択すると自動でイベントのハンドラが生成されます。

Private Sub TrackBar1_ValueChanged(sender As Object, e As EventArgs) Handles TrackBar1.ValueChanged
    '処理を追加
End Sub

自動生成されたサブルーチンの後方にHandles TrackBar1.ValueChangedのように記述されている部分がイベントの発生要因になります。

イベントに処理を追加する

イベントが発生した時の処理を追加します。イベントの追加で作成したサブルーチンに処理を追加します。処理の内容は以下の通りです。

  1. フォームを読み込んだ時に初期化を行う。
  2. COMポートを検索して選択する。(詳細はVB.net(VB2022)のSerialPortの実装とイベントの追加方法を参照してください。)
  3. Timer1のインターバル毎にタイマを管理して外部機器に電文を送出する。
  4. TrackBar1~3のスライダーの値を取得する。

フォームを読み込んだ時に初期化

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    ComboInit() 'Comboboxを初期化する
    RxRingInit() 'RxRingの初期化を行う
    LabelInit() 'Labelを初期化する
End Sub

Form1_Load()関数はForm1が読み込まれた時に一度だけイベントが発生します。自作の関数でComboBoxの初期化、RxRingの初期化、Labelの初期化を行います。

COMポートを検索して選択する

接続可能なCOMポートが複数ポート表示されることがあります。複数のポートから選択した項目の番号をイベントにより取得します。

Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
    selectComNo = ComboBox1.SelectedIndex
End Sub

SelectedIndexChangedイベントはComboBoxで項目を選択すると発生するイベントです。SelectedIndexメソッドで項目の番号を取得してselectComNoに格納します。

選択したCOMポートで接続を行う場合にselectComNoに格納している番号からCOM番号を選択して接続します。

広告

Timer1のインターバル処理

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick

    If timTrack > TIME_UP Then
        timTrack -= 1
    End If

    If timTrack = TIME_UP Then
        timTrack = TIME_OFF
        SerialWrite()'電文を送信
    End If
End Sub

Timer1のEnabledをTrueにするとインターバル毎にTimer1_Tick()のイベントが発生します。インターバル毎にタイマーを更新します。タイムアップすると自作のSerialWrite()関数で外部機器に電文を送出します。

Private Sub SerialWrite()
    Dim buf(5) As Byte

    buf(0) = Asc("V")
    buf(1) = 3
    buf(2) = Label1.Text
    buf(3) = Label2.Text
    buf(4) = Label3.Text
    buf(5) = GetSum(buf)

    If SerialPort1.IsOpen Then
        SerialPort1.Write(buf, 0, buf.Length)
    End If

End Sub

外部機器に送出する電文を生成します。電文は任意のルールを定めて外部機器と通信するために使用します。

1バイト目はヘッダーとして文字の”V”をセットします。2バイト目は3バイト目以降のデータ数をセットします。3~5バイト目はTrackBar1~3で取得したデータをセットします。6バイト目は1バイトから5バイトまでを加算したSUMをセットします。

SerialPortクラスのIsOpenメソッドでCOMポートが接続しているかを確認し、正常であればWrite()メソッドで電文を送信します。第1引数は送信するデータのアドレスを指定します。第2引数はデータのオフセットを指定します。第3引数に送信するデータ数を指定します。

TrackBar1~3のスライダー値を取得する

Private Sub TrackBar1_ValueChanged(sender As Object, e As EventArgs) Handles TrackBar1.ValueChanged
    Label1.Text = TrackBar1.Value
    timTrack = TIME_TX
End Sub

Private Sub TrackBar2_ValueChanged(sender As Object, e As EventArgs) Handles TrackBar2.ValueChanged
    Label2.Text = TrackBar2.Value
    timTrack = TIME_TX
End Sub

Private Sub TrackBar3_ValueChanged(sender As Object, e As EventArgs) Handles TrackBar3.ValueChanged
    Label3.Text = TrackBar3.Value
    timTrack = TIME_TX

End Sub

TrackBarを操作するとスライダーの変化を検出してValueChangedイベントが発生します。イベント内で現在のスライダーの値をラベルに表示します。またtimTrackタイマをセットすることで外部機器への電文送信のトリガーをセットします。

電文送信のトリガーはイベント内で電文を送信すると通信頻度が多くなるためイベント発生から任意のタイミングを遅延して電文を送信するようにしています。例ではスライダーの操作からTIME_TXの間電文の送信を遅延するようにしています。

スポンサーリンク

Seeeduino XIAOの構成

Seeeduino XIAOの構成
Seeeduino XIAOの構成

Seeeduino XIAOと拡張基板を使用します。RGB LEDにはGrove Mech keycapを使用します。アプリのスライダーを操作して生成した電文でRGB LEDの点灯パターンを変更します。下記記事にRGB LEDを操作する方法をまとめています。

Seeeduino XIAOでRGB LEDを操作する

参考記事ではボタンでRGB LEDを操作していますが、ボタンがアプリ(シリアル通信を含む)に置き換わったイメージです。

Seeeduino XIAOは受信した電文をチェックし、健全な電文であればRGM LEDのパターンを指定する値に使用します。以下は、電文のチェックの例です。

void RxDataChk(void){
 
  if( rx.buf[ rp ] != 'V' ){ //ヘッダーの確認 
    //電文のヘッダーが不一致
  }
  else{
    //受信したデータのサイズ確認
    sumchk = CalcSum(&Rcvdata[0],allsz-1);
    if( sumchk == Rcvdata[allsz-1]){//SUMのチェック
      red = Rcvdata[2]; //REDの値
      green = Rcvdata[3]; //GREENの値
      blue = Rcvdata[4]; //BLUEの値
    }
  }
}

受信データのスタート(ヘッダー)が’V’であれば電文のスタートとみなします。ヘッダの後はサイズが続くためデータ数を確認して電文の全体のサイズを確認します。

受信データの健全性を確認するためSUMを計算し、電文の最後に付加しているSUMと一致するか確認します。SUMが一致すると正常なデータとして電文を受け入れRGB LEDを操作する値を格納します。

Seeeduino XIAOのソースコード:

#include <Adafruit_NeoPixel.h>
#include <U8x8lib.h>
#include <Wire.h>
#include <TimerTC3.h>

#define TIME_UP 0
#define TIME_OFF -1
#define BASE_CNT 10 //10msがベースタイマとなる
#define TIM_RX_WAIT 5
#define NUMPIXELS 1 // Popular NeoPixel ring size
#define BUTTON_PIN   7
#define PIXEL_PIN    6
#define LED_FL 5
#define RING_SZ 256
#define BUF_SZ 64

struct RING_MNG{
  uint8_t wp;
  uint8_t rp;
  uint8_t buf[RING_SZ];
};

Adafruit_NeoPixel pixels(NUMPIXELS, PIXEL_PIN, NEO_GRB  + NEO_KHZ800);
U8X8_SSD1306_128X64_NONAME_SW_I2C u8x8( SCL, SDA, U8X8_PIN_NONE);
RING_MNG rx;
uint8_t Rcvdata[BUF_SZ];
uint8_t red;
uint8_t green;
uint8_t blue;
int8_t cnt10ms;
int16_t timled;
int8_t  timRxWait = TIME_OFF;

/*** Local function prototypes */
void mainTimer(void);
void TimerCnt(void);
void mainApp(void);
void RxDataChk(void);
uint8_t CalcSum(uint8_t *buf, uint8_t sz);
void ReadPointerAdd(void);
void OlcdSet(void);

void setup() {
  
  pinMode(BUTTON_PIN, INPUT_PULLDOWN);
  Serial.begin(115200);

  u8x8.begin();
  u8x8.setFlipMode(1);   // set number from 1 to 3
  u8x8.setFont(u8x8_font_5x8_r);
  u8x8.setCursor(0, 0);
  u8x8.print("Mech keycap   ");
  u8x8.setCursor(0, 2);
  u8x8.print("RED:          ");
  u8x8.setCursor(0, 4);
  u8x8.print("GREEN:        ");
  u8x8.setCursor(0, 6);
  u8x8.print("BLUE:         ");

  red = 0;
  green = 0;
  blue = 0;
  pixels.begin();
  pixels.clear();
  pixels.show(); // Initialize all pixels to 'off'

  TimerTc3.initialize(1000);
  TimerTc3.attachInterrupt(TimerCnt);
}

void loop() {

  mainTimer();
  mainApp(); 
}

/* メイン処理 */
void mainApp(void){

  while( Serial.available()){
    rx.buf[rx.wp] = Serial.read();
    if( ++rx.wp >= RING_SZ ){ //次にデータを入れる場所を更新
      rx.wp = 0;
    }
  }

  RxDataChk();

  if( timled == TIME_UP){
    timled = LED_FL;
    pixels.setPixelColor(0,red,green,blue);
    pixels.show();
  }
}
/* callback function add */
void TimerCnt(void){
  ++cnt10ms;
}
/* Timer Management function add */
void mainTimer(void){

  if( cnt10ms >= BASE_CNT ){
    cnt10ms -=BASE_CNT; //10msごとにここに遷移する

    if( timled > TIME_UP ){
      timled--;
    }

    if( timRxWait > TIME_UP){
      timRxWait--;
    }
  }
}

/* RX function add */
void  RxDataChk(void){
  uint8_t i;
  int rxsz;
  uint8_t sz;
  uint8_t allsz;
  uint8_t *adrs;
  uint8_t rp = rx.rp;
  uint8_t chkdat[2];
  uint8_t sumchk;

  if( timRxWait == TIME_UP){
    timRxWait = TIME_OFF;
    ReadPointerAdd();    
  }  

  rxsz = rx.wp - rx.rp; //受信データ数の算出
  if( rxsz < 0 ){
    rxsz = rxsz + RING_SZ;
  }

  if( rxsz == 0 ){
    timRxWait = TIME_OFF;
  }
  else{
    if( timRxWait == TIME_OFF ){
      timRxWait = TIM_RX_WAIT;
    }

    if( rx.buf[ rp ] != 'V' ){ //ヘッダーの確認
      ReadPointerAdd(); 
    }
    else{
      if(rxsz >= 2){
        for(uint8_t i=0; i< 2; i++ ){  //ヘッダーのチェックのため一時保存
          chkdat[i] = rx.buf[rp];
         if(++rp >= RING_SZ){
          rp=0;
         }
        }

        sz = chkdat[1] & 0x3F;
        allsz = sz + 3; //+3:header + sz +sum

        if( rxsz >= allsz ){
          timRxWait = TIME_OFF;

          for(i=0; i < sizeof(Rcvdata); i++){
            Rcvdata[i] = 0;
          }          

          for(i=0; i < allsz; i++ ){
            Rcvdata[i] = rx.buf[rx.rp];
            ReadPointerAdd();
          }

          sumchk = CalcSum(&Rcvdata[0],allsz-1);

          if( sumchk == Rcvdata[allsz-1]){ //チェックサムが一致するか
            red = Rcvdata[2];
            green = Rcvdata[3];
            blue = Rcvdata[4];
            OlcdSet();
          }
        }
      }
    }
  }
}
/* ChkSum function add */
uint8_t CalcSum(uint8_t *buf, uint8_t sz=0){
    uint8_t ret = 0;

    for(uint8_t i=0; i < sz; i++ ){
      ret += (*buf);
      buf++; 
    }
    return ret;
}
/* 読み込み位置の更新 */
void ReadPointerAdd(void){
    
  if(++rx.rp >= sizeof(rx.buf) ){
    rx.rp = 0;
  }
}

/* OLEDの文字をセット*/
void OlcdSet(void){
  char chr[17];

  sprintf(&chr[0],"RED:   %3d",red);
  u8x8.drawString(0,2,&chr[0]);
  sprintf(&chr[0],"GREEN: %3d",green);
  u8x8.drawString(0,4,&chr[0]);
  sprintf(&chr[0],"BLUE:  %3d",blue);
  u8x8.drawString(0,6,&chr[0]);
}

OledSet()関数はSeeeduino XIAOの拡張基板のOLEDにアプリから受信したスライダー値を表示します。電文を受信すると「RED:」「GREEN:」「BLUE:」の後ろにスライダーの値を表示します。

動作確認(デバッグ)

デバッグ開始の方法
デバッグ開始の方法

イベントの処理を追加した後は動作確認(デバッグ)を行います。デバッグは実際のアプリケーションの動作を模擬して実行するものです。デバッグの開始はエディタ上部の「▶開始」(赤枠)をクリックすると開始します。

動作確認の結果
動作確認の結果

Seeeduino XIAOをUSB接続して待機させます。デバッグの開始でアプリをスタートし、Seeeduino XIAOに接続するポートを選択します。COM7は使用する環境によって番号が異なることがあります。ボーレートは115200を選択します。

オープンをクリックするとCOMポートがオープンします。スライダーを操作するとOLEDの値が更新されると同時にSeeeduino XIAOに接続しているRGB LEDの点灯パターンが変更できます。

VB2022のスライダーでRGB LEDを操作した結果
VB2022のスライダーでRGB LEDを操作した結果

スライダーの値を変更すると例のようにRGB LEDの点灯パターンが変わることが確認できました。

Seeeduino XIAOのUSBを抜いて再検索するとCOMポートが消えていることも確認できました。また、再度接続し「再検索」をクリックするとSeeeduino XIAOのCOMポートが表示されることも確認できました。

コードのデバッグを行う場合は、コードエディタでブレークポイントを置くことで一時的にプログラムを停止させることができます。

ブレークポイントでデバッグする方法
ブレークポイントでデバッグする方法

ブレークポイントはコードエディターの最左部分をクリックして●マークが表示されれば設置できています。例ではButton1がクリックされた時に発生したイベントの先頭部分にブレークポイントを置いています。この状態でButton1をクリックするとブレークポイントでプログラムが一時停止します。

F11を押すとステップ実行になるため1行ずつ内容を確認しながらデバッグを行うことができます。上部の「▶続行(C)」をクリックするとブレークポイント状態から通常の動作に復帰します。

PR:(即戦力のスキルを身に着ける:DMM WEBCAMP 学習コース(はじめてのプログラミングコース))

ソースコード全体

以下のソースコードはコンパイルして動作確認をしております。コメントなど細かな部分で間違っていたりやライブラリの更新などにより動作しなくなったりする可能性があります。参考としてお使いいただければと思います。

Imports System.IO.Ports

Public Class Form1

    Dim timTrack As Integer
    Const RXRGSZ As Integer = 64
    Const TIME_UP As Byte = 0
    Const TIME_OFF As Int16 = -1
    Const TIME_TX As Byte = 2

    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の初期化を行う
        LabelInit() 'Labelを初期化する
    End Sub

    'RxRingの初期化を行う
    Private Sub RxRingInit()
        RxRing.wp = 0
        RxRing.rp = 0
        ReDim RxRing.dat(RXRGSZ - 1)
    End Sub

    'Labelを初期化する
    Private Sub LabelInit()
        Label1.Text = 0
        Label2.Text = 0
        Label3.Text = 0
    End Sub

    'Comboboxを初期化する
    Private Sub ComboInit()
        ComPortChk()

        ComboBox2.Items.Add("9600")
        ComboBox2.Items.Add("19200")
        ComboBox2.Items.Add("115200")
        ComboBox2.Text = "115200"
    End Sub

    '存在するポートを検索する
    Private Sub ComPortChk()
        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
        ComPortChk() '存在するポートを検索する
    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() 'ポートを閉じる
                .PortName = ComInfo(selectComNo).comno
                .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 Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick

        If timTrack > TIME_UP Then
            timTrack -= 1
        End If

        If timTrack = TIME_UP Then
            timTrack = TIME_OFF
            SerialWrite()
        End If

    End Sub
    '電文を送信
    Private Sub SerialWrite()
        Dim buf(5) As Byte

        buf(0) = Asc("V")
        buf(1) = 3
        buf(2) = Label1.Text
        buf(3) = Label2.Text
        buf(4) = Label3.Text
        buf(5) = GetSum(buf)

        If SerialPort1.IsOpen Then
            SerialPort1.Write(buf, 0, buf.Length)
        End If

    End Sub
    'SUM値を計算
    Function GetSum(dat() As Byte) As Byte
        Dim sum As UInt16 = 0
        Dim i As Byte

        For i = 0 To dat.Length - 1
            sum += dat(i)

            If (sum >= &H100) Then
                sum -= &H100
            End If
        Next

        Return sum
    End Function

    Private Sub TrackBar1_ValueChanged(sender As Object, e As EventArgs) Handles TrackBar1.ValueChanged
        Label1.Text = TrackBar1.Value
        timTrack = TIME_TX
    End Sub

    Private Sub TrackBar2_ValueChanged(sender As Object, e As EventArgs) Handles TrackBar2.ValueChanged
        Label2.Text = TrackBar2.Value
        timTrack = TIME_TX
    End Sub

    Private Sub TrackBar3_ValueChanged(sender As Object, e As EventArgs) Handles TrackBar3.ValueChanged
        Label3.Text = TrackBar3.Value
        timTrack = TIME_TX
    End Sub

    Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
        selectComNo = ComboBox1.SelectedIndex
    End Sub
End Class

コントロールの番号やイベントハンドラーなどのプロパティ名などを変更している場合はソースコードのイベントハンドラーをお使いのイベントハンドラーに置き換えてください。

関連リンク

VBでインストール先を指定できるインストーラを作成する方法を下記記事にまとめています。

VBでインストール先を指定するインストーラを作成する方法

マイクロソフトはVisual Studio以外にもVSCodeという便利なエディターを提供しています。下記リンクではVSCodeのインストールの仕方からC言語開発環境の作り方までをまとめています。

VSCodeをインストールしてC/C++の開発環境を作る

PR: 未経験OK、20代の理系に特化した就職、転職サービス UZUZ(ウズウズ)

最後まで、読んでいただきありがとうございました。

タイトルとURLをコピーしました