Phidgets Inc.Servo Tutorial 1A Single Servo Controller in Visual BasicOverviewIn this, tutorial we will cover:InstallingVisual Basic ExpressCreate a Graphical User interfaceWriting code to operate the Graphical User Interface and control a Phidget servo.This tutorial provides an excellent starting point for learning how to use the PhidgetServo controller and helps develop a feel forthe way all Phidgets work. It is specifically geared towards those users new toVisual Basic and creating Graphical User Interfaces.To attempt this tutorial, you should understand basic programming concepts. Knowledge of object oriented programming wouldalso be an asset. There are extensive resources available online that deal with this subject.The source code for this application is provided with the tutorial. It is suggested though that you follow the steps outlined here togain a firm grasp of howVisual Basic works and the steps used to create the application.Visual Basic Express and Initial SetupVisual Basic (VB) Express is a free Windows development package from Microsoft that uses the .NET framework. It provides allthe functionality that the vast majority of people will require. Additionally, it contains documentation and help files specificallytargeted at assisting beginner and intermediate programmers. VB Express can be downloaded from the Microsoft web site.Important: OnceVB Express has been installed, or if you are using a pre-installed .NET programming package, it is necessary todownload and install the API from the Phidgets website, Phidget21.msi. Without this file, it is not possible to use Phidgets.Creating the Graphical User Interface (GUI)The GUI is what you actually see when running your program. It allows you to interact with the code and make changes that canaffect your Phidget.Open VB ExpressTo begin, open VB Express and createa new project. Select “WindowsApplication,” name the project‘ServoControler’ and click “Ok.”•••
Phidgets Inc.Load Phidget APIUnder the “Project” menu (1), select “AddReference.” In the new window, click on theBrowse tab (2) and navigate to the directory inwhich you installed Phidgets21.msi. The defaultdirectory is: C:Program FilesPhidgets. For VBExpress, select the Phidget21.NET.dll (3) andclick “Ok” (4). This is a compulsory process asit loads the Phidget API or “ApplicationProgramming Interface.” The API contains thePhidget library which is a collection of thecontrols we will need to interact with Phidgets.You must load the library regardless of whichPhidgets you are using.GUI LayoutA program with a GUI is composed of one or more “forms.”The forms contain all of the elements necessary to interactwith the computer in a graphical environment. The form forthis program is the grey box on the screen. Most programsthat you will be writing for Phidgets, at least to begin with, willonly use one form. Applications that make use of more thanone are often substantially more complicated to program. Thescreen you see now is called the “Form Designer”It is useful to first set up your workspace. If the “Toolbox”panel is not already visible, open the “View” menu (1) andselect “Toolbox.” To ensure the Toolbox panel does not coverthe form you are going to be working on, toggle the “pin”button (2).The various elements of the GUI, known as controls, can beplaced in whatever order you wish and in any location you wish. For this example, let us first start by placing the “TrackBar” (3).This control will be used to change the position of the servo. Under the “All Windows Forms” rollout, select TrackBar. Clickand drag somewhere in the upper portion of the form. The exact positioning is irrelevant, however, for aesthetic purposes, thetrackbar may be repositioned, and re-sized. Edge “snaps” are often useful to create a uniform look (you should discover thesewhen dragging the track bar around the edges of the form).The next step is to place the “Labels” (5) which will be used to display information.‘Label1’ will present an absolute numericalvalue for servo rotation,‘Label2’, the connection status and finally,‘Label3’, the serial number of a connected Phidget. Under the“Common Controls” rollout in the toolbox, select the label and click and drag in the form. Repeat this action to create 3 labels.Note the names of your labels and the order they appear on the form, they should follow the order shown here.When working with the labels and controls in general, it is often useful to open the layout toolbar by selecting View (1) Toolbars Layout. The layout toolbar provides many helpful tools for aligning elements on the form. Select the three labels youcreated and perform a“LeftAlign” (6). If your labels are spread out vertically you can also try clicking“MakeVertical Spacing Equal”(7). You can move the labels as a group into whatever position you wish.
Phidgets Inc.Finally, select the button tool (4) and as in the same manner as the trackbar and labels, create a button at the bottom of the form.It should be sized in such a way so its title,“Button1” can be seen clearly. While the button is selected,click“Center Horizontally”(8) on the layout toolbar.In this stage, experimentation is encouraged to create a satisfactory look.Modify PropertiesTo ensure the proper operation of the program,a few properties of the controls you just placedmust be modified. By first clicking on the trackbar to select it, look to the bottom right handside of the screen. The properties panel should be visible with the name of the selected controlat the top of the panel. Here the name is “TrackBar1.” Change the following propertiesMaximum – Set this to 180. In combination with the minimum value two lines below,thesenumbers determines the range of values that can be selected on the trackbar. Withinthe application code (which will be discussed latter), the API for the servo accepts valuescorresponding roughly to degrees of rotation. Consequently, the range of 0 to 180 on thetrack bar is used to set the position of the servo within half of one complete rotation. Itshould be noted that the PhidgetServo accept position ranges from -23 to 231.TickFrequency – Once you change the maximum property and view the trackbar, it isquite obvious that it does not look right. Where there should be ticks beneath the slider,it probably looks like some sort of solid bar. Changing the TickFrequency property from1 to 10 should fix this.Value – The value should be set to 90 to ensure that the slider is resting in the middle ofthe slide range.After modifying the track bar, click to select the button that you placed near the bottom of theform. In the properties panel,findText and set its value to“Close.”You should now observe thatthe button is now labeled “Close.”As is obvious, there are many different properties that can be set. A fairly good explanation canbe found by clicking on each and looking to the very bottom of the screen or by searching thehelp file which comes withVB Express.1.2.3.
Phidgets Inc.Writing the CodeVisual Basic and all visual programming languages are“event driven,” as such,any action you want the program to respond to calls asubroutine. As a general rule,every event requires its own block of code. There are three categories of action that this applicationmust be designed to handle.Program Activities –These are events such as opening or closing the program.User Activities –Including sliding the trackbar and clicking the Close button.Phidget Events – Phidget events include attaching or detaching the Phidget and handling any errors that might occur.Objects and EventsWhile still in the Form Designer, under the“View” menu, select “Code” (1). A more orless blank page should appear. At the top ofthis section, two drop down menus can befound. The left menu (2) is used for selectingthe control or object while the right menu(3) is used to select an event related to thatobject. The first subroutine that should bewritten is the Load event that is triggeredwhen the application is opened. First, select“(Form1 Events)” (2) from the left menu,then “Load” (3) from the right menu. A newblock of text should appear.If at any time you would like to test code youhave written, simply click the green arrowbutton (4) on the “Standard” toolbar.Loading the formBoth subroutines seen here should be created by using the drop down menus or other automatic means withinVB (such as doubleclicking on the control in the form designer). You should never have to type out the basic frame work for subroutines that dealwith events. Private Sub, End Sub, and any text on the same line as Private Sub should be created byVB. Making yourown subroutines will be covered in the next tutorial.1.2.3.Public Class Form1Dim WithEvents Servo1 As New Phidgets.ServoPrivate Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)Handles MyBase.Load1Label1.Text = Position: -Label2.Text = Status: Not ConnectedLabel3.Text = Serial Number: -End SubPrivate Sub TrackBar1_Scroll(ByVal sender As Object, ByVal e As System.EventArgs)Handles TrackBar1.ScrollLabel1.Text = Position: TrackBar1.ValueEnd SubEnd Class4234567Public Class Form1Dim WithEvents Servo1 As New Phidgets.ServoPrivate Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)Handles MyBase.Load1Label1.Text = Position: -Label2.Text = Status: Not ConnectedLabel3.Text = Serial Number: -End SubPrivate Sub TrackBar1_Scroll(ByVal sender As Object, ByVal e As System.EventArgs)Handles TrackBar1.ScrollLabel1.Text = Position: TrackBar1.ValueEnd SubEnd Class4234567
Phidgets Inc.In attempting this tutorial,you should already have a concept ofhow object oriented programming works. As a quick refresherthough; object oriented programming is centered aroundcreating virtual “objects” that can both store information andtake action using subroutines. Objects are defined by writinga “class” that defines their behavior. Each of the controls thatyou placed in the form designer (the trackbar, button andlabels) are objects. If you will notice the very first lines of thiscode are “Class Form1.” In writing this program we areactually creating an object. It can perform actions through itssubroutines and store data. Generally, in this program, we areusing other object,like the labels (6),to store information,suchas text (called “strings”).After writing the segment of code shown here it would beprudent to test it by clicking the green arrow button as describedpreviously. All the application allows you to do with this code isdrag the slider and have a numerical value displayed.Here, the “Servo1” object is created. Note thatthe position of this line is outside of any subroutine(as explained in (7)) and therefore it remains globallyaccessible (every subroutine can access it) within thescope of this application, or more specifically, this form.It may be obvious that this line is not strictly necessaryas Servo1 is not used. Later, it will allow us to interactwith the Phidget.Notice the structure of this declaration. The keywordDim is responsible for declaring the object, creatinga reference for the object and reserving appropriatememory. It does not create the object. Objects orvariables created in memory always have a reference,alsoknown as a pointer. If you are unfamiliar with references,you can simply think of them as the objects name. Whenusing an object in code, such as Servo1, you are actuallynot using the object but the reference to that object. Forexample, it is possible to have two objects (A and B) andto swap their references. In such a case, calling object Awould actually access object B.WithEvents allows the object to use its own handles. Ifthis term is neglected, you would have to manually definesubroutine names for the events the object can trigger. Intutorial 3, this will be discussed in deeper detail. For now,it is important for simplicity.As New Phidgets.Servo creates this objectas a Servo object. The term New is important as itis responsible for actually creating the object in thememory defined by Dim. Finally, If you were to createa program using Phidget encoders, you would useAs New Phidgets.Encoder to create an encoderspecific object.The entire line shown here was automatically createdand is used to define the subroutine. This portion is thename of the subroutine and can be changed to whatever1.2.is wished. It can not start with a number or contain anyspaces or special characters such as *, !, , etc. It mustalso be unique. These naming rules are applicable forany variable or object withinVisual Basic and most otherprogramming languages.As with (3), this portion of the line was automaticallycreated and for most new users is unimportant. In thesimplest sense,it generates two objects,the first of which,sender, can be used to identify the object or eventresponsible for triggering the subroutine. The secondobject, e, contains other information that the subroutineis given. This structure containing sender,and e objectsis very common in .NET programming.Handles are very important and are by default,responsiblefor determining when a subroutine is called. In thefirst instance, the handle is Me.Load. “Me” is used toreference the active form and .Load is the condition foraction. Hence the statement is equivalent to “Call thissubroutine when loading.” Similarly with the second block,the handle TrackBar.Scroll calls that subroutinewhen the trackbar is scrolled or moved. Without thesehandles, neither event of loading the form or moving thetrackbar would call a subroutine. While creating an eventto respond to trackbar changes it is important to use the.Scroll event and not the .ValueChanged eventthough both seem similar.This three line block of code is responsible for changing thelabels. The text shown on the Close button was modifiedin the properties panel when laying out the GUI. Herehowever, the contents of the labels are modified directlywithin the code. Most properties found in the propertiespanel can be modified by the code in this same manner. Thestructure,object.propertyorobject.variableis a universal way of accessing or modifying informationwithin objects. If the call contains brackets, it is asubroutine, such as object.subroutine().It is also possible to have layered structures, as inobject.property.property.subroutine().In this case,the property actually refers to another objectcontained within the main object.It should be obvious that the precursor to this statementis very similar to the statements contained within (6).The highlighted section however demonstrates a way todisplay variables. The“” symbol is necessary to separatedistinct elements.These two statements were created automatically whenselecting the two drop down menus. Together,they definethe start and end of the subroutine.188.8.131.52.7.
Phidgets Inc.Handling the PhidgetIt is now time to interface with the Phidget.As you can see in the code to the left, thereare three important events common toall Phidgets, these are, attach and detach,occurring when a Phidgets USB cord isconnected or removed from the computer.Additionally,there is the error event which iscalled when the Phidget malfunctions.As with the previous section of code,these are the handles to the subroutines.If you modify the name of the subroutineand later can not remember what itdoes, simply look to the handle. All threehandles, and therefore subroutines, arecalled when something happens regardingthe Phidget, and since we are usingthe Servo1 object to interact with it,the Servo1 object is responsible fortriggering these events.This is the first instance where we areactually telling the Phidget to take action.Here,we are giving it a command to centerits position (90 degrees out of 180). Noticethe structure of this command. Servo1 isthe object responsible for controlling thisPhidget. Next, servos(0), is accessingthe subroutine for servo motor withindex 0. On the 4-Motor PhidgetServo,the 0 shown here could be 0, 1, 2 or 3 corresponding to each individual motor channel. Finally, .Position= 90 isresponsible for setting the position of the servo.This line ensures that when the servo becomes active, the trackbar is enabled so that the user can modify its position.These two blocks of code are very similar to those shown in (6) from the previous explanation and are responsible forchanging the labels information.TheValue property of the trackbar can be changed by both the program and the user. You have already seen how this valuecan be read by the application and while being modified by the user to simply display a value. Here, the value is set by theapplication and then the control is disabled to prevent its value from being changed when there is no Phidget attached to thecomputer. Since this is necessary only when there is no Phidget, it is located within the Servo.Detach subroutine.This expression creates the object, e, of type Phidgets.Events.ErrorEventArgs. The type of object should be ofno concern as it is already defined by the nature of the event. The call to this subroutine occurs when there is an error andthe e object gets passed the details of that error.Following from (6), here, a message box is created and the desc variable of the e object is displayed. The e object onlycontains two variables, the error code and its corresponding description (or desc). It is always a good practice to showwhat error has occurred when writing code.Me refers to the active form and the .Close() subroutine initiates the processes of closing the formIf you like, you can once again test the code you have written. At this stage, the trackbar still will not have any effect on the servomotor however you should see changes to the lables on the form when you plug in and unplug the Phidget.184.108.40.206.220.127.116.11.Private Sub Servo1_Attach(ByVal sender As Object, ByVale As Phidgets.Events.AttachEventArgs) Handles Servo1.AttachServo1.servos(0).Position = 90TrackBar1.Enabled = TrueLabel1.Text = Position: 90Label2.Text = Status: ConnectedLabel3.Text = Serial Number: Servo1.SerialNumberEnd SubPrivate Sub Servo1_Detach(ByVal sender As Object, ByVal eAs Phidgets.Events.DetachEventArgs) Handles Servo1.DetachLabel1.Text = Position: -Label2.Text = Status: Not ConnectedLabel3.Text = Serial Number: -TrackBar1.Value = 90TrackBar1.Enabled = FalseEnd SubPrivate Sub Servo1_Error(ByVal sender As Object, ByVal eAs Phidgets.Events.ErrorEventArgs) Handles Servo1.ErrorMessageBox.Show(e.desc)Me.Close()End Sub235811164476
Phidgets Inc.Linking the Phidget to TrackBarReturn once more to the first two blocks ofcode you wrote.Adding this line will disable the trackbarimmediately when the program starts.At this point, it is unknown whetheror not a Phidget is connected to thecomputer. If no servo Phidget is availableto the Servo1 object and you try andchange its position value through thecode at (3), an error will occur. Sincethere is an enable command for thetrackbar in the Attach subroutine,thisline provides a measure of protection.Calling the .open() subroutinespecifically tells Servo1 to searchthe computers USB ports and try anddetect any Phidgets already connected.If it finds any, it then proceeds to callthe Attach subroutine that youhave already written. The .open()subroutine called here is in fact anelement common to any Phidget object that you create. Just as Phidgets.Servo was used to create the Servo1 objectused here to interact with the servo motor,a Phidgets.Accelerometer object would interact with an accelerometer.Both objects would contain a number of common properties and subroutines, including .open(). A complete list can befound in the .NET API manual.This is the line that links the rotation of the servo to the position of the track bar. It updates the Position property for theservo to reflect the position of the trackbar when it is moved.At this point the application is nearly complete. If you choose to test it at this stage, dragging the slider bar when a PhidgetServois connected should result in it rotating.Closing SubroutinesThe final thing that must be accounted for is exiting theprogram and clicking the close button.As has been mentioned, these handles tell you what thesubroutines are responding to. They should be starting tolook familiar by now. The lower subroutine is called onlywhen the program is closing.This is exactly the same as the line shown above and tellsthe application to shut down. It causes the program tocall the subroutine below it.Though not essential, it is recommended to use the.close() subroutine when a given Phidget object is nolonger required. It does not delete the object,rather it disconnects the current Phidget from the program. If you wanted touse the Phidget after this command (which is not applicable in this case as the program is closing), you would need to onceagain call the .open() subroutine.18.104.22.168.2.3.Public Class Form1Dim WithEvents Servo1 As Phidgets.ServoPrivate Sub Form1_Load(ByVal sender As System.Object,ByVal e As System.EventArgs) Handles MyBase.LoadServo1 = New Phidgets.ServoLabel1.Text = Position: -Label2.Text = Status: Not ConnectedLabel3.Text = Serial Number: -TrackBar1.Enabled = FalseServo1.open()End SubPrivate Sub TrackBar1_Scroll(ByVal sender As Object,ByVal e As System.EventArgs) Handles TrackBar1.ScrollLabel1.Text = Position: TrackBar1.ValueServo1.servos(0).Position = TrackBar1.ValueEnd Sub123Public Class Form1Dim WithEvents Servo1 As Phidgets.ServoPrivate Sub Form1_Load(ByVal sender As System.Object,ByVal e As System.EventArgs) Handles MyBase.LoadServo1 = New Phidgets.ServoLabel1.Text = Position: -Label2.Text = Status: Not ConnectedLabel3.Text = Serial Number: -TrackBar1.Enabled = FalseServo1.open()End SubPrivate Sub TrackBar1_Scroll(ByVal sender As Object,ByVal e As System.EventArgs) Handles TrackBar1.ScrollLabel1.Text = Position: TrackBar1.ValueServo1.servos(0).Position = TrackBar1.ValueEnd Sub123Private Sub CloseButton_Click(ByVal senderAs Object, ByVal e As System.EventArgs)Handles Button1.ClickMe.Close()End SubPrivate Sub Form1_FormClosing(ByVal senderAs Object, ByVal e As System.Windows.FormsFormClosingEventArgs) Handles Me.FormClosingServo1.close()End SubEnd Class2311Private Sub CloseButton_Click(ByVal senderAs Object, ByVal e As System.EventArgs)Handles Button1.ClickMe.Close()End SubPrivate Sub Form1_FormClosing(ByVal senderAs Object, ByVal e As System.Windows.FormsFormClosingEventArgs) Handles Me.FormClosingServo1.close()End SubEnd Class2311
Phidgets Inc.ConclusionYou are now done creating this application. You should now beable to run it (the green arrow). Connect a Phidget and dragthe trackbar around. The servo motor should move in relationto the position of the bar.Hopefully you now have a better understanding of Phidgets andhow to begin programming with them. Every Phidget works inthe same fundamental way so if you understand the creationof the Servo1 object, how it is used and how to modify itsproperties,you are well on your way to being able to use almostany Phidget.It is very important to note what you have learned in thistutorial is suitable for dealing with only one Phidget connectedto the computer. If you have two or more of the same type,youwill get unreliable results and not know which one the programwill control. A simple method for dealing with this issue isdiscussed in the next tutorial.If you do have two Phidgets of different types and wish to trycreating your own program now,you must remember that eachPhidget requires its own object to control it. That object mustalso be of the same type as the Phidget.
Phidgets Inc.This application demonstrates the use of the Phidgetservo controller. Please note that if you are using the4-Motor version, this application is suitable forcontrolling only motor 0. For reliable results, esurethat only one PhidgetServo is attached to the computerPublic Class Form1Dim WithEvents Servo1 As New Phidgets.ServoCreates the Servo1 Object used to control the PhidgetPrivate Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)Handles MyBase.LoadSubroutine called when the form is created. Sets the initial conditions.Label1.Text = Position: -Label2.Text = Status: Not ConnectedLabel3.Text = Serial Number: -Sets the inital text to displayTrackBar1.Enabled = FalseDisables the TrackBar to prevent errors with the Servo1 objectServo1.open()Will attempt to detect Phidgets already attached to the computer.If detected will call the attach subroutine (below).End SubPrivate Sub TrackBar1_Scroll(ByVal sender As Object, ByVal e As System.EventArgs) HandlesTrackBar1.ScrollA subroutine to deal with changes made to the scroll barLabel1.Text = Position: TrackBar1.ValueUpdates the position displayServo1.servos(0).Position = TrackBar1.ValueUpdates the servo motor to reflect the position of the track barEnd SubPrivate Sub Servo1_Attach(ByVal sender As Object, ByVal e As Phidgets.Events.AttachEventArgs) Handles Servo1.AttachA subroutine activated when a Phidget is detected attached to the computerServo1.servos(0).Position = 90Sets the initial position of the Phidget servo to 90 degreesTrackBar1.Enabled = TrueEnables the TrackBar to allow for changing the servo positionLabel1.Text = Position: 90Label2.Text = Status: ConnectedLabel3.Text = Serial Number: Servo1.SerialNumberUpdates the text and shows the serial number of the connected PhidgetEnd SubPrivate Sub Servo1_Detach(ByVal sender As Object, ByVal e As Phidgets.Events.DetachEventArgs) Handles Servo1.DetachSubroutine called when the Phidget is detached from the computerCode
Phidgets Inc.10Label1.Text = Position: -Label2.Text = Status: Not ConnectedLabel3.Text = Serial Number: -Text ChangesTrackBar1.Value = 90TrackBar1.Enabled = FalseResets the track barEnd SubPrivate Sub Servo1_Error(ByVal sender As Object, ByVal e As Phidgets.Events.ErrorEventArgs) Handles Servo1.ErrorA subroutine that deals with error conditionsMessageBox.Show(e.desc)Show the error that has occurredMe.Close()Close the programEnd SubPrivate Sub CloseButton_Click(ByVal sender As Object, ByVal e As System.EventArgs)Handles Button1.ClickA subroutine to close the programMe.Close()End SubPrivate Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosingThe subroutine that is run as the program closesServo1.close()This block of code ensures that the Phidget is disabled. It isnot strictly necessary but recommendedEnd SubEnd Class Signals the end of this program