Example Source Code:
Visual Basic Test Program
For the WheelCommander WC-132


This example uses NdiCmdC.dll, a Windows 2000/XP/Vista dynamic link library designed to provide a simple "flat" interface to NdiCmd.dll, a C++ DLL used by WC Wizard. NdiCmdC.dll provides access to all of the useful commands within a WheelCommander, in a way that is compatible with C and Visual Basic programs on a Windows machine.

Wc132.vb is a module used to declare all of the entry points into NdiCmdC.dll, and provides an initialization function which will either locate the WheelCommander (by scanning all enabled serial ports), or, if not found, will pop up the WC Wizard so that you can make changes to the communication settings and attempt to connect manually.

MainModule.vb contains Sub main(), the main entry point to the program. This calls Init_WheelCommander, and if successful, queries the firmware version and passes it to frmMain.vb, the main form.

FrmMain.vb contains 5 controls: a text box that displays the WheelCommander version and connection status; a text box for entering a velocity value; a scroll bar for changing the velocity value; a button for issuing a Go! command; and a button for issuing a Coast command. The code for frmMain.vb contains the NdiCmdC.dll calls to affect this behavior.


wc132.vb - Visual Basic source
MainModule.vb - Visual Basic source
frmMain.vb - Visual Basic source
VBCommander.NET.zip - All project files


Source Code


Option Strict Off
Option Explicit On
Module wc132
    ' declare entry points to WheelCommander DLL
    Declare Sub NdiCmd_Init Lib "NdiCmdC.dll" Alias "_NdiCmd_Init@0" ()
    Declare Sub NdiCmd_SetLogFile Lib "NdiCmdC.dll" Alias "_NdiCmd_SetLogFile@8" (ByVal path As String, ByVal append As Boolean)
    Declare Function NdiCmd_Search Lib "NdiCmdC.dll" Alias "_NdiCmd_Search@0" () As Integer
    Declare Function NdiCmd_CheckPort Lib "NdiCmdC.dll" Alias "_NdiCmd_CheckPort@4" (ByVal port As Integer) As Integer
    Declare Function NdiCmd_GetFirstPort Lib "NdiCmdC.dll" Alias "_NdiCmd_GetFirstPort@0" () As Integer
    Declare Function NdiCmd_GetNextPort Lib "NdiCmdC.dll" Alias "_NdiCmd_GetNextPort@4" (ByVal prev As Integer) As Integer
    Declare Sub NdiCmd_RunWizard Lib "NdiCmdC.dll" Alias "_NdiCmd_RunWizard@4" (ByVal wizMode As Integer)
    Declare Function NdiCmd_GetWheelCommander Lib "NdiCmdC.dll" Alias "_NdiCmd_GetWheelCommander@0" () As Integer

    Declare Function NdiCmd_Sync Lib "NdiCmdC.dll" Alias "_NdiCmd_Sync@4" (ByVal handle As Integer) As Integer
    Declare Function NdiCmd_GetName Lib "NdiCmdC.dll" Alias "_NdiCmd_GetName@12" (ByVal handle As Integer, ByVal name As String, ByRef version As Integer) As Integer
    Declare Function NdiCmd_Coast Lib "NdiCmdC.dll" Alias "_NdiCmd_Coast@4" (ByVal handle As Integer) As Integer
    Declare Function NdiCmd_Brake Lib "NdiCmdC.dll" Alias "_NdiCmd_Brake@4" (ByVal handle As Integer) As Integer
    Declare Function NdiCmd_Reset Lib "NdiCmdC.dll" Alias "_NdiCmd_Reset@4" (ByVal handle As Integer) As Integer
    Declare Function NdiCmd_Go Lib "NdiCmdC.dll" Alias "_NdiCmd_Go@4" (ByVal handle As Integer) As Integer
    Declare Function NdiCmd_SetVelocity Lib "NdiCmdC.dll" Alias "_NdiCmd_SetVelocity@8" (ByVal handle As Integer, ByVal vel As Integer) As Integer
    Declare Function NdiCmd_GetVelocity Lib "NdiCmdC.dll" Alias "_NdiCmd_GetVelocity@8" (ByVal handle As Integer, ByRef vel As Integer) As Integer

    Declare Function NdiCmd_SetAccel Lib "NdiCmdC.dll" Alias "_NdiCmd_SetAcceleration@8" (ByVal handle As Integer, ByVal vel As Integer) As Integer
    Declare Function NdiCmd_GetAccel Lib "NdiCmdC.dll" Alias "_NdiCmd_GetAcceleration@8" (ByVal handle As Integer, ByRef vel As Integer) As Integer
    Declare Function NdiCmd_SetRotation Lib "NdiCmdC.dll" Alias "_NdiCmd_SetRotation@8" (ByVal handle As Integer, ByVal vel As Integer) As Integer
    Declare Function NdiCmd_GetRotation Lib "NdiCmdC.dll" Alias "_NdiCmd_GetRotation@8" (ByVal handle As Integer, ByRef vel As Integer) As Integer
    Declare Function NdiCmd_SetAngle Lib "NdiCmdC.dll" Alias "_NdiCmd_SetAngle@8" (ByVal handle As Integer, ByVal vel As Integer) As Integer
    Declare Function NdiCmd_GetAngle Lib "NdiCmdC.dll" Alias "_NdiCmd_GetAngle@8" (ByVal handle As Integer, ByRef vel As Integer) As Integer
    Declare Function NdiCmd_SetXAngle Lib "NdiCmdC.dll" Alias "_NdiCmd_SetXAngle@8" (ByVal handle As Integer, ByVal vel As Integer) As Integer
    Declare Function NdiCmd_GetXAngle Lib "NdiCmdC.dll" Alias "_NdiCmd_GetXAngle@8" (ByVal handle As Integer, ByRef vel As Integer) As Integer
    Declare Function NdiCmd_SetDist Lib "NdiCmdC.dll" Alias "_NdiCmd_SetDistance@8" (ByVal handle As Integer, ByVal vel As Integer) As Integer
    Declare Function NdiCmd_GetDist Lib "NdiCmdC.dll" Alias "_NdiCmd_GetDistance@8" (ByVal handle As Integer, ByRef vel As Integer) As Integer
    Declare Function NdiCmd_SetXDist Lib "NdiCmdC.dll" Alias "_NdiCmd_SetXDistance@8" (ByVal handle As Integer, ByVal vel As Integer) As Integer
    Declare Function NdiCmd_GetXDist Lib "NdiCmdC.dll" Alias "_NdiCmd_GetXDistance@8" (ByVal handle As Integer, ByRef vel As Integer) As Integer

    Declare Function NdiCmd_ReadAIO Lib "NdiCmdC.dll" Alias "_NdiCmd_ReadAIO@12" (ByVal handle As Integer, ByVal pin As Integer, ByRef value As Double) As Integer

    Declare Sub NdiCmd_CloseAllPorts Lib "NdiCmdC.dll" Alias "_NdiCmd_CloseAllPorts@0" ()

    Public handle As Integer ' handle to current WheelCommander

    Public Function Init_WheelCommander() As Integer
        handle = -1
        NdiCmd_Init() ' init library
        NdiCmd_SetLogFile("vbcommander.log", False)
        If NdiCmd_Search <> 1 Then ' try finding WheelCommander
            NdiCmd_RunWizard(1) ' if it failed, run the wizard
            If NdiCmd_Search = 1 Then ' try finding it again
                handle = NdiCmd_GetWheelCommander ' if found, get a handle to the WheelCommander
            End If
            handle = NdiCmd_GetWheelCommander ' we found it straight away, so get a handle to it
        End If
        Init_WheelCommander = handle
    End Function
End Module


Option Strict Off
Option Explicit On
Module MainModule
    Public fMainForm As frmMain

    Public Sub main()
        Dim name As String
        Dim version As Integer
        Init_WheelCommander() ' find wc132 if possible; if not, launch wizard
        fMainForm = New frmMain
        If handle <> -1 Then
            name = "- unknown -"
            If NdiCmd_GetName(handle, name, version) = 1 Then
                fMainForm.WCStatus.Text = "Connected: Ver " & Str(version) & " Type " & name
                fMainForm.WCStatus.Text = "Connected"
            End If
            fMainForm.WCStatus.Text = "Not Connected"
        End If
    End Sub
End Module


Option Strict Off
Option Explicit On
Friend Class frmMain
Inherits System.Windows.Forms.Form
    Private velTextBoxChanging As Boolean
    Private Shared myTimer As New System.Windows.Forms.Timer()

    Private Sub Coast_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles Coast.Click
        NdiCmd_Coast(wc132.handle) ' tell WheelCommander to stop moving
    End Sub

   Private Sub Go_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles Go.Click
      Dim vel As Short
      vel = CShort(Velocity.Text)
      If NdiCmd_SetVelocity(wc132.handle, vel) <> 1 Then ' pass velocity value from form to WheelCommander; only needed if user never set the velocity
         MsgBox("Error setting velocity!")
         If NdiCmd_Go(wc132.handle) <> 1 Then ' tell WheelCommander to start using current velocity setting
            MsgBox("Error on Go!")
         End If
      End If
   End Sub

   Private Sub Velocity_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Velocity.ValueChanged
      Dim vel As Short
      vel = CShort(Velocity.Text)
      If NdiCmd_SetVelocity(wc132.handle, vel) <> 1 Then ' pass velocity value from form to WheelCommander    
         MsgBox("Error on SetVelocity!")
      End If
   End Sub

   Private Sub VelScroll_Change(ByVal newScrollValue As Integer)
      If velTextBoxChanging = False Then
         Velocity.Text = CStr(newScrollValue)
      End If
   End Sub

   Public Sub mnuHelpAbout_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles mnuHelpAbout.Click
      VB6.ShowForm(frmAbout, VB6.FormShowConstants.Modal, Me)
   End Sub

   Public Sub mnuViewOptions_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles mnuViewOptions.Click
      VB6.ShowForm(frmOptions, VB6.FormShowConstants.Modal, Me)
   End Sub

   Public Sub mnuViewRefresh_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles mnuViewRefresh.Click
      MsgBox("Add 'mnuViewRefresh_Click' code.")
   End Sub

   Public Sub mnuViewStatusBar_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles mnuViewStatusBar.Click
      mnuViewStatusBar.Checked = Not mnuViewStatusBar.Checked
      sbStatusBar.Visible = mnuViewStatusBar.Checked
   End Sub

   Public Sub mnuFileExit_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles mnuFileExit.Click
      'unload the form
   End Sub

   Private Sub VelScroll_Scroll(ByVal eventSender As System.Object, ByVal eventArgs As System.Windows.Forms.ScrollEventArgs)
      Select Case eventArgs.Type
         Case System.Windows.Forms.ScrollEventType.EndScroll
      End Select
   End Sub

   Private Sub OnTick(ByVal myObject As Object, ByVal myEventArgs As EventArgs)
      Dim voltage As Double
      Dim dist As Integer
      Dim ang As Integer
      Dim vel As Integer
      Dim rot As Integer
      Dim trunc As String

      If NdiCmd_ReadAIO(wc132.handle, 6, voltage) = 1 Then
         trunc = Str(voltage * 40.01 / 10)
         DigitalSupply.Text = trunc.Remove(5, trunc.Length - 5)
      End If
      If NdiCmd_ReadAIO(wc132.handle, 7, voltage) = 1 Then
         trunc = Str(voltage * 100.09 / 10)
         MotorSupply.Text = trunc.Remove(5, trunc.Length - 5)
      End If
      If NdiCmd_GetDist(wc132.handle, dist) = 1 Then
         Distance.Text = Str(dist)
      End If
      If NdiCmd_GetAngle(wc132.handle, ang) = 1 Then
         Angle.Text = Str(ang)
      End If
      If NdiCmd_GetVelocity(wc132.handle, vel) = 1 Then
         CurVelocity.Text = Str(vel)
      End If
      If NdiCmd_GetRotation(wc132.handle, rot) = 1 Then
         RotationRate.Text = Str(rot)
      End If
   End Sub

   Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      Me.Left = VB6.TwipsToPixelsX(CSng(GetSetting(My.Application.Info.Title, "Settings", "MainLeft", CStr(1000))))
      Me.Top = VB6.TwipsToPixelsY(CSng(GetSetting(My.Application.Info.Title, "Settings", "MainTop", CStr(1000))))
      Me.Width = VB6.TwipsToPixelsX(CSng(GetSetting(My.Application.Info.Title, "Settings", "MainWidth", CStr(6500))))
      Me.Height = VB6.TwipsToPixelsY(CSng(GetSetting(My.Application.Info.Title, "Settings", "MainHeight", CStr(6500))))

      AddHandler myTimer.Tick, AddressOf OnTick
      myTimer.Interval = 500
   End Sub

   Private Sub frmMain_FormClosed(ByVal eventSender As System.Object, ByVal eventArgs As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
      If Me.WindowState <> System.Windows.Forms.FormWindowState.Minimized Then
         SaveSetting(My.Application.Info.Title, "Settings", "MainLeft", CStr(VB6.PixelsToTwipsX(Me.Left)))
         SaveSetting(My.Application.Info.Title, "Settings", "MainTop", CStr(VB6.PixelsToTwipsY(Me.Top)))
         SaveSetting(My.Application.Info.Title, "Settings", "MainWidth", CStr(VB6.PixelsToTwipsX(Me.Width)))
         SaveSetting(My.Application.Info.Title, "Settings", "MainHeight", CStr(VB6.PixelsToTwipsY(Me.Height)))
      End If
   End Sub

End Class