getVariables and Visual Basic (2010)

Hello,
Newb here, both to Pololu and programming.
I’ve been trying to access position data on a Maestro 24 via device.getVariables(ByRef Stack() as Short) in Visual Basic 2010 and have run into problems with getting any data returned.
I’m wondering if the issues are with VB 2010 vs VB 2008 (used for the SDK), old/new versions of the SDK, or just plain ol’ ignorance on my part.

First off, the Maestro with one servo on channel 0 works just fine, both with the control center and the VB easyexample. The example code converted to VB 2010 without any issues, both in XP and Vista (different machines).
Using the SDK to get other information (device.stacksize, etc) works fine.

So I started following along same path as Marius. He (with David’s guidance) basically used the easyexample script but replaced device.settarget with device.getVariables(st), then added textboxes to display three values from the stack.

That code won’t run for me: I received “NullReference exception unhandled” errors for the dynamic array st() as soon as any line of code tried to use the array. Once that was fixed ( grain of salt there) I received " IndexOutOfRangeException" errors if I attempted to read any values for st() if I had already called getVariables(st). st.GetUpperBound would return a value of negative 1 (i.e., null) for st after calling getVariables(st). Before calling getVariables(st) st.GetUpperBound would return whatever value I initialized st() to.

VB2010 changed the way dynamic arrays are initialized; at least I think that might be at the root of the first problem. So I added to Marius’s code:
ReDim st(126)

Which got it running - until I tried to read the data.

Imports Pololu.UsbWrapper
Imports Pololu.Usc

Imports System
Imports System.Text
Imports System.ComponentModel


Public Class MainWindow

    Public Property Stack As Object
    Dim st As Short()
    Dim ss As Int32
    Dim cs As Int32

    ''' <summary>
    ''' Attepts to get variables from the stack
    ''' </summary>
    Public Sub TryGetVariables()

        ReDim st(126)
        st(0) = 0

        TextBox1.Text = st.GetLowerBound(0)
        TextBox2.Text = st.GetUpperBound(0)
        Try
            Using device As Usc = connectToDevice() ' Find a device and temporarily connect.
                device.getVariables(st)
                ss = device.stackSize
                
                ' device.Dispose() is called automatically when the "Using" block ends,
                ' allowing other functions and processes to use the device.
            End Using

        Catch exception As Exception  ' Handle exceptions by displaying them to the user.
            displayException(exception)
        End Try
        TextBox3.Text = st.GetLowerBound(0)
        TextBox4.Text = st.GetUpperBound(0)

        ' TextBox5.Text = st(0)

    End Sub


    ''' <summary>
    ''' Connects to a Maestro using native USB and returns the Usc object
    ''' representing that connection.  When you are done with the
    ''' connection, you should close it using the Dispose() method so that
    ''' other processes or functions can connect to the device later.  The
    ''' "Using" statement can do this automatically for you.
    ''' </summary>
    Function connectToDevice() As Usc
        ' Get a list of all connected devices of this type.
        Dim connectedDevices As List(Of DeviceListItem) = Usc.getConnectedDevices()

        For Each dli As DeviceListItem In connectedDevices
            ' If you have multiple devices connected and want to select a particular
            ' device by serial number, you could simply add some code like this:
            '    If dli.serialNumber <> "00012345" Then
            '        Continue For
            '    End If

            Dim device As Usc = New Usc(dli)  ' Connect to the device.
            Return device                     ' Return the device.
        Next

        Throw New Exception("Could not find device.  Make sure it is plugged in to " & _
            "USB and check your Device Manager.")
    End Function

    ''' <summary>
    ''' Displays an exception (error) to the user by popping up a message box.
    ''' </summary>
    ''' 
    Sub displayException(ByVal exception As Exception)
        Dim stringBuilder As StringBuilder = New StringBuilder()
        Do
            stringBuilder.Append(exception.Message & "  ")
            If TypeOf exception Is Win32Exception Then
                Dim win32Exception As Win32Exception = DirectCast(exception, Win32Exception)
                stringBuilder.Append("Error code 0x" + win32Exception.NativeErrorCode.ToString("x") + ".  ")
            End If
            exception = exception.InnerException
        Loop Until (exception Is Nothing)
        MessageBox.Show(stringBuilder.ToString(), Text, MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Sub


    Public Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        TryGetVariables()

    End Sub

    Private Sub MainWindow_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    End Sub
End Class

note- TextBox5.Text = st(0), which in the best of all possible worlds would display the data I want, is commented out to allow the program to run.

I guess I have several questions.

  1. If someone could explain or point me towards an answer, I’d be most grateful.
  2. Is using VB 2008 (vs 2010) likely to be a path of less resistance for using Pololu and perhaps other controllers?
  3. My previous programming experience is old and atrophied, so I’m really just getting started -both with learning an OOP language and learning about machine interfaces in general. Would switching to C# instead of VB be likely to increase or decrease the slope of the learning curve? Down here at the bottom of the hill, that is.

Thank you!

hardware: maestro-24, RC servo on channel 0, Core2Duo PC
software: latest version of USB SDK(2010-11-19), Visual Basic 2010 Express, XP SP3 32-bit

What exactly are you trying to read from the Maestro? If you just want to read the position of a particular servo channel, there is another overload of device.getVariables that you should use. It fetches an array of ServoStatus structs, one for each channel. If you want to read some data from the Maestro’s stack (used by the internal scripting language), you should tell us what your current script is, and what data you see on the stack when you run the Maestro Control Center (your script should be the simplest possible script that demonstrates the problem, a super simple script like “1 2” would suffice).

If you don’t have any familiarity with VB, I think switching to C# would be good. That way, you would be able to read/copy the C# source code of UscCmd in order to figure out how to do whatever it is you want to do. Also I think you should use the 2010 version of Visual Studio because it’s newer and it should work fine with our code.

–David

I am having the same issue with the indexoutofrange exception. Has anyone managed to shed any light on this yet?

Thanks!

Hello.

I noticed you create a new thread asking a very similar question. Please see my response there.

- Amanda