PEEK/POKE equivalents in Visual Basic .NET

Hi,
I have a 24 ch Mini Maestro that is now up and running after a very steep learning curve for someone who is new to most of this. Its an amazing little thing and the posibillities are endless :smiley: :smiley: :smiley: :smiley: :smiley: :smiley: :smiley: :smiley: :smiley: :smiley:

Now, the next phase of my project is to write a little VB.NET application that will display information from the running script.

I am starting out with the MaestroEasyExampleVb ( the only one for vb? ). I can use the TrySetTarget command to enable/disable outputs. This works well. But what I am most of all looking for is the command to read from the stack, equivalent of PEEK.
Also the equivalents of POKE and get_position would be great.

I have been looking through the material, searched around, and tried whatever I can think of but achieving nothing but frustration. :confused: :angry: :cry: :frowning: :imp: :smiling_imp:

HELP PLEASE!!!

EDIT: Ok I got a little bit more idea now. I found the sub where TrySetTarget is defined:

    ''' <summary>
    ''' Attempts to set the target of 
    ''' </summary>
    ''' <param name="channel">Channel number from 0 to 23.</param>
    ''' <param name="target">
    '''   Target, in units of quarter microseconds.  For typical servos,
    '''   6000 is neutral and the acceptable range is 4000-8000.
    ''' </param>
    Sub TrySetTarget(ByVal channel As Byte, ByVal target As UInt16)
        Try
            Using device As Usc = connectToDevice() ' Find a device and temporarily connect.
                device.setTarget(channel, target)
                ' 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
    End Sub

So then, more precisely, my question is how to define something like ReadStackValue
Sorry I need this with spoon :confused:

EDIT II: I found this in the Usc.cs:

        /// <summary>
        /// Gets an array of shorts[] representing the current stack.
        /// The maximum size of the array is stackSize.
        /// </summary>
        /// <remarks>If you are using the Micro Maestro and calling
        /// getVariables more than once in quick succession,
        /// then you can save some CPU time by just using the
        /// overload that has 4 arguments.
        /// </remarks>
        public void getVariables(out short[] stack)
        {
            if (microMaestro)
            {
                MaestroVariables variables;
                ServoStatus[] servos;
                ushort[] callStack;
                getVariablesMicroMaestro(out variables, out stack, out callStack, out servos);
            }
            else
            {
                getVariablesMiniMaestro(out stack);
            }
        }

I get this is the correct one?
Now how can I apply this in the code with correct parameters?
Example would be great. Thanks

You are almost all the way there. :sunglasses:

You found the function you need to call in the Usc class to get the stack. Now you just need to figure out how to pass an “out short[]” parameter in Visual Basic.

Auto-complete can help you. If you go in to Visual Basic and type “device.getVariables(” inside the Using block then you can see the 5 different overloads of the getVariables function. Browsing to the correct overload (by clicking the little gray arrows), you can see that the Visual Basic signature of that function is:

getVariables(ByRef stack() As Short)

If you are familiar with Visual Basic, then you probably know exactly what to do when you see a function like this. I’m not too familiar with Visual Basic, so it took me a few tries, but I figured it out. Here’s the code:

Dim st As Short()
device.getVariables(st)
MessageBox.Show(st(0).ToString())

Try putting that in the Using block and it should display the value at the bottom of the stack in a dialog box. I tested it here with a Micro Maestro 6 and it worked.

Unfortunately, there is no USB command that lets you poke the stack. You can get the positions of all the servo channels using another overload of GetVariables.

–David

YES!!! I got it working now.
Thank you very much.
:smiley: :smiley: :smiley: :smiley: :smiley:

This is the working script that, at the click of a button, will retrieve all stack values: (and display 3 of them)

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()

    ''' <summary>
    ''' Attepts to get variables from the stack
    ''' </summary>
    Public Sub TryGetVariables()
        Try
            Using device As Usc = connectToDevice() ' Find a device and temporarily connect.
                device.getVariables(st)
                ' 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
    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()
        TextBox1.Text = st(0)
        TextBox2.Text = st(1)
        TextBox3.Text = st(2)
    End Sub

End Class

But with this script I need to click the button every time I want to update the values.

What I am trying to achieve, is to stay connected to keep streaming the data for constant update.
I have been trying hard the last 12 hours without any success. :confused: :confused: :confused:
If anybody has any idea of how to do this please help!

The simplest thing to do is make a timer that runs every 100ms or so, and calls TryGetVariables. There are 3 timer classes in .NET, and I recommend using System.Windows.Forms.Timer because then you don’t have to worry about cross-thread issues.

In VB, I think you can just drag a timer object on to the Window and configure it by clicking on it, (it’s similar to configuring other controls like buttons).

–David

WOW!!! :smiley: :smiley: :smiley: :smiley: :smiley: :smiley:
I dont know what to say.
What I have been trying to do for 12 hours took about 12 seconds with your help!!
THANK YOU!!!

Hola!!

Alguien me podría ayudar el comando equivalente a “get_position”, o si alguien sabe como controlar las entradas análogas de mini-maestro 12 desde visual basic. deseo activar o desactivar desde una interfaz gráfica creada en visual un boton que me permita el control manual de un servomotor con un potencioemtro.

lo he hecho, programando desde el Script de “pololu maestro control center” y funciona bien, pero realmente necesito controlarlo desde Visual Basic. dejo el programa en script, gracias al que me pueda ayudar

begin

##################MOVIMIENTO HACIA ADELANTE###############
8 get_position # get the value of the pot, 0-1023
dup 300 less_than
if
10000 # go to 4000 for values 0-299
else
dup 600 less_than
if
6000 # go to 6000 for values 300-599
else
6000 # go to 8000 for values 600-1023
endif
endif
150 0 speed
0 servo
drop # remove the original copy of the pot value

8 get_position # get the value of the pot, 0-1023
dup 300 less_than
if
1000 # go to 4000 for values 0-299
else
dup 600 less_than
if
6000 # go to 6000 for values 300-599
else
6000 # go to 8000 for values 600-1023
endif
endif
150 3 speed
3 servo
drop # remove the original copy of the pot value
##################FIN MOVIMIENTO HACIA ADELANTE###############

repeat

Hello, edicxon.

I noticed you emailed us what seems like a similar question that also included this English translation:

To read the voltage on a Maestro channel configured as an input using our Software Development Kit, you can use getVariables(). Alternatively, if you are using serial communication, you can use the Maestro’s “Get Position” serial command. You can find more information about the Maestro’s serial commands in the “Serial Servo Commands” section of its user’s guide.

-Brandon

hi, BrandoM
excuse me for the insistence, But that does not answer my question.
i want to know if somehow, I can or not , control the analog inputs from Visual Basic, same way as in the examples, I can control the position of the servo with TrySetTarget (0, 1000 * 4) function. I want to know which command can I use to control it.

thanks for your help

I am not sure I understand what you are asking. Could you try rephrasing your question and explaining what you are trying to do?

-Brandon

hi Brandon M
my question goes directly focused on the control of the Mini Maestro 12 from visual basic, I am creating a graph interface with this program in order to control the mini maestro 12 to do a sequence with 6 servo.

the control position of each servo motor from visual basic, it’s possible by the function TrySetTarget (0, (2800) * 4), where “0” is the servo 0 and 2800 servo motor position. correct!!
I also need to control the servos with a joystick (from the interface I created in visual basic).

my question is: ¿how i can control the analogous inputs, from visual basic?
well as the command TrySetTarget, what command can I use in visual basic to control the inputs Mini Maestro 12?
or if on the contrary there is no way how to control it.

leave programming in visual basic to be in context

thank you

Imports Pololu.UsbWrapper
Imports Pololu.Usc

Imports System
Imports System.Text
Imports System.ComponentModel

Public Class SimuladorSismos

    Public Property Stack As Object
    Dim st As Short()

    Public Sub TryGetVariables()
        Try
            Using device As Usc = connectToDevice() ' Find a device and temporarily connect.
                device.getVariables(st)
                ' 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
    End Sub




    Sub Ejecutar_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Ejecutar.Click
        TextBox1.Text = TrackBar1.Value * 1
        If ((OndasP.Checked = True) And (TrackBar1.Value = 1)) Then
            TryGetVariables()
            Timer1.Start()
        End If

    End Sub


    ''' <summary>
    ''' Los intentos de establecer el objetivo de
    ''' </summary>
    ''' <param name="channel">Número de canal entre 0 y 23.</param>
    ''' <param name="target">
    '''   Target, en unidades de microsegundos trimestre. Para servos típica,
    '''   6000 es neutra y el rango aceptable es 4000-8000.
    ''' </param>
    Sub TrySetTarget(ByVal channel As Byte, ByVal target As UInt16)
        Try
            Using device As Usc = connectToDevice() ' Encontrar un dispositivo y conectar de forma temporal.
                device.setTarget(channel, target)
                ' device.Dispose () es llamado automáticamente cuando termina el bloque de "Uso",
                ' permitir que otras funciones y procesos utilicen el dispositivo.
            End Using
        Catch exception As Exception  ' Manejar excepciones mostrándolos al usuario.
            displayException(exception)
        End Try
    End Sub

    ''' <summary>
    ''' Se conecta a un Maestro usando USB nativo y devuelve el objeto Usc
    ''' que representa esa conexión. Cuando haya terminado con la
    ''' conexión, debe cerrarla utilizando el método Dispose () de modo que
    ''' otros procesos o funciones pueden conectarse al dispositivo más tarde. El
    ''' "Usando" la declaración puede hacer esto automáticamente para usted.
    ''' </summary>
    Function connectToDevice() As Usc
        ' Obtenga una lista de todos los dispositivos conectados de este tipo.
        Dim connectedDevices As List(Of DeviceListItem) = Usc.getConnectedDevices()

        For Each dli As DeviceListItem In connectedDevices
            ' Si tiene varios dispositivos conectados y desea seleccionar un determinado
            ' dispositivo por número de serie, que podría simplemente añadir un poco de código como este:
            '    Si dli.serialNumber <> "00012345" Entonces
            '        continuar por
            '    End If

            Dim device As Usc = New Usc(dli)  ' Conecte el dispositivo.
            Return device                     ' Devuelva el dispositivo.
        Next

        Throw New Exception("No se pudo encontrar el dispositivo.  Asegúrese de que está conectado a " & _
            "USB y compruebe su Administrador de dispositivos.")
    End Function

    ''' <summary>
    ''' Muestra una excepción (error) al usuario por aparecer un cuadro de mensaje.
    ''' </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("Código de error 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





    ''''//////////INICIO DE ONDAS P////////////////////////////////////////////////////////////////////////'''
    '''******************** INICIO ONDAS P NIVEL 1*********************************************************                                                                     
    Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
        TrySetTarget(0, (560) * 4)
        TrySetTarget(1, (2800) * 4)
        TrySetTarget(2, (560) * 4)
        TrySetTarget(3, (2800) * 4)
        TrySetTarget(4, (560) * 4)
        TrySetTarget(5, (2800) * 4)
        Timer2.Start()
        Timer1.Enabled = False
    End Sub
    Private Sub Timer2_Tick(sender As System.Object, e As System.EventArgs) Handles Timer2.Tick
        TrySetTarget(0, (2800) * 4)
        TrySetTarget(1, (560) * 4)
        TrySetTarget(2, (2800) * 4)
        TrySetTarget(3, (560) * 4)
        TrySetTarget(4, (2800) * 4)
        TrySetTarget(5, (560) * 4)
        Timer3.Start()
        Timer2.Enabled = False
    End Sub
    Private Sub Timer3_Tick(sender As System.Object, e As System.EventArgs) Handles Timer3.Tick
        TrySetTarget(0, (1675) * 4)
        TrySetTarget(1, (1675) * 4)
        TrySetTarget(2, (1675) * 4)
        TrySetTarget(3, (1675) * 4)
        TrySetTarget(4, (1675) * 4)
        TrySetTarget(5, (1675) * 4)
        Timer1.Start()
        Timer3.Enabled = False
    End Sub
    ''' ****************************************FIN ONDAS P NIVEL 1****************************************


    Private Sub Cancelar_Click(sender As System.Object, e As System.EventArgs) Handles Cancelar.Click
        Timer1.Stop()
        Timer2.Stop()
        Timer3.Stop()
        

    End Sub



  
   
End Class

It sounds like you are asking for a way to read the input from your joystick, which is connected to your Maestro. If this is the case, my previous post still applies. As I mentioned in that post, to read the voltage on a Maestro channel configured as an input using our Software Development Kit, you can use getVariables(). I am not sure what you mean when you say you want to control inputs from Visual Basic. The inputs from your joystick are not being controlled by the software; they are being controlled from your joystick and read from the software.

-Brandon

but, how I can use get_vatiables () to read the voltage on a master channel configured as an input?
I am using communication via USB.
if you say that you can read the voltage on a channel configured as a Master with get_vatiables input () function … how do I?
¿that library I can use for this?.

is using this command?
getVariables (ByRef stack () As Short)
you have an example where you can read the voltage on a master channel configured as an input

It looks like you are using the wrong overload of getVariables; you should use the one whose C# definition is public void getVariables(out ServoStatus[] servos). We do not have sample code for Visual Basic, but you might find the C# code in this post helpful. You will need to convert it to the equivalent Visual Basic code.

-Brandon