Programming a Simple Servo Motor in C# / WPF

Download Source code for this example

Before you begin

  • Make sure the Phidgets software is correctly installed
  • Start the Phidgets server via the control panel. If a phidget is plugged in, can you see it?
  • Have a Phidget Servo ready (i.e., the phidget servo board with connected servo motor, and a USB cable)

Common steps to all Phidget programming.

  1. Start visual studio in the usual way and create a C# / WPF project.
  2. Add a reference to the Phidgets dll library by:
    • choose Add References from the context menu on the References icon in your solution explorer
    • select the Browse tab from the Add Reference dialog box
    • browse to C:\\Program Files\Phidgets and select Phidgets21.Net.dll
  3. Add Using statements to the top of your code
    • using Phidgets;
    • using Phidgets.Events;

Create your GUI

- a slider used to control the position of the servo motor - a small texblock next to it (the textblock will contain the position of the servo)

Common order of activities, illustrated with an example of a servo.

Declare your phidget (:source lang=csharp tabwidth=2 :) public partial class MainWindow : Window { Phidgets.Servo servo = new Phidgets.Servo(); // The basic servo object that controls the actual hardware

Initialize your phidget byhaving it look for the Attach event and then opening it (:source lang=csharp tabwidth=2 :) public MainWindow() { InitializeComponent(); this.slider1.IsEnabled = false; // We don't want the slider operable until the servo is plugged in servo.Attach += new AttachEventHandler(servo_Attach); // Invoked when the servo is actually plugged in (Attached); }

In the Attach event, add the various event handlers, set parameters and activate UI controls as needed (:source lang=csharp tabwidth=2 :) // The servo is attached. Add callbacks, enable the slider, and set it all to position 0 void servo_Attach(object sender, AttachEventArgs e) { this.Dispatcher.Invoke(new Action(delegate() { // If you want to look for a particular servo, do something like this. Note the 283 is a device-specific serial number // if (servo.SerialNumber != 283) return; printMessage("servo " + servo.SerialNumber + " is attached"); servo.Detach += new DetachEventHandler(servo_Detach); // generic phdiget callbacks servo.Error += new ErrorEventHandler(servo_Error); servo.PositionChange += new PositionChangeEventHandler(servo_PositionChange); // servo-specific callbacks servo.servos[0].Position = 0; slider1.Value = 0; this.slider1.IsEnabled = true; })); }

In the Detach event, remove the various event handlers and deactivate UI controls as needed (:source lang=csharp tabwidth=2 :) // The servo is detached. Disable the slider and remove callbacks void servo_Detach(object sender, DetachEventArgs e) { this.Dispatcher.Invoke(new Action(delegate() { printMessage("servo Detached"); this.slider1.IsEnabled = false; servo.Detach -= new DetachEventHandler(servo_Detach); servo.Error -= new ErrorEventHandler(servo_Error); servo.PositionChange -= new PositionChangeEventHandler(servo_PositionChange); })); }

Handle errors, although usually there is no need to do anything (:source lang=csharp tabwidth=2 :) // Some random error was generated. void servo_Error(object sender, ErrorEventArgs e) { this.Dispatcher.Invoke(new Action(delegate() { printMessage("servo Error: " + e.Description); })); }

'Handle Phidget-specific callbacks (:source lang=csharp tabwidth=2 :) // The servo motor position has been changed. Show its new position void servo_PositionChange(object sender, PositionChangeEventArgs e) { this.Dispatcher.Invoke(new Action(delegate() { this.textBlock1.Text = e.Position.ToString(); ; })); }

Handle callbacks for UI elements that control phidgets (:source lang=csharp tabwidth=2 :) // Change the servo position so it corresponds to the slider value private void slider1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) { this.Dispatcher.Invoke(new Action(delegate() { servo.servos[0].Position = slider1.Value; })); }

Utility function for showing feedback, in this case just printing in the title bar

(:source lang=csharp tabwidth=2 :) // Put some feedback in the title bar private void printMessage(string msg) { this.Title = msg; }