Controlling Servos Using Netdunio and Phidgets
August 12, 2014 1 Comment
As part of the Terminator program I am creating, I need a way of controlling servos to point the laser (and then gun) and different targets. I decided to create a POC project and evaluate two different ways of controlling the servos. As step one, I purchased a pan and tilt chassis from here.
After playing with the servos from the kit, I decided to use my old stand-by servos that had a much higher quality and whose PWM signals I already know how to use. With the chassis done, I needed a laser pointer so I figured why not get a shark with fricken laser?
I found one here.
So with the servos and laser ready to go, it was time to code. I started with Netduninos:
public class Program { private const uint TILT_SERVO_STRAIGHT = 1500; private const uint TILT_SERVO_MAX_UP = 2000; private const uint TILT_SERVO_MAX_DOWN = 1000; private const uint PAN_SERVO_STRAIGHT = 1500; private const uint PAN_SERVO_MAX_LEFT = 1000; private const uint PAN_SERVO_MAX_RIGHT = 2000; private static PWM _tiltServo = null; private static PWM _panServo = null; private static uint _tiltServoCurrentPosition = 0; private static uint _panServoCurrentPosition = 0; public static void Main() { SetUpServos(); InputPort button = new InputPort(Pins.ONBOARD_BTN, false, Port.ResistorMode.Disabled); while (true) { if (button.Read()) { MoveServo(); } } } private static void SetUpServos() { uint period = 20000; _tiltServoCurrentPosition = TILT_SERVO_STRAIGHT; _panServoCurrentPosition = PAN_SERVO_STRAIGHT; _tiltServo = new PWM(PWMChannels.PWM_PIN_D3, period, _tiltServoCurrentPosition, PWM.ScaleFactor.Microseconds, false); _tiltServo.Start(); _panServo = new PWM(PWMChannels.PWM_PIN_D5, period, _panServoCurrentPosition, PWM.ScaleFactor.Microseconds, false); _panServo.Start(); } private static void MoveServo() { _panServo.Duration = PAN_SERVO_MAX_LEFT; Thread.Sleep(2000); _panServo.Duration = PAN_SERVO_MAX_RIGHT; Thread.Sleep(2000); _panServo.Duration = PAN_SERVO_STRAIGHT; Thread.Sleep(2000); _tiltServo.Duration = TILT_SERVO_MAX_UP; Thread.Sleep(2000); _tiltServo.Duration = TILT_SERVO_MAX_DOWN; Thread.Sleep(2000); _tiltServo.Duration = TILT_SERVO_STRAIGHT; } }
And sure enough the servos are behaving as expected
I then implemented a similar app using Phidgets. Because the code is being executed on the PC, I could use F# to code (It does not look like the Netdunino/Microframework supports F#?)
open System open Phidgets let _servoController = new AdvancedServo() let mutable _isServoControllerReady = false let servoController_Attached(args:Events.AttachEventArgs) = let servoController = args.Device :?> AdvancedServo servoController.servos.[0].Engaged <- true servoController.servos.[7].Engaged <- true _isServoControllerReady <- true [<EntryPoint>] let main argv = _servoController.Attach.Add(servoController_Attached) _servoController.``open``() while true do if _isServoControllerReady = true then _servoController.servos.[0].Position<- 100. _servoController.servos.[7].Position<- 100. Console.ReadKey() |> ignore printfn "%A" argv 0
The choice then becomes using the Netduino or the Phidgets with my Kinect program. I decided to defer the decision and use an interface for now.
type IWeaponsSystem = abstract member Activate: unit -> unit abstract member AquireTarget : float*float -> bool abstract member Fire: int -> bool
My decision about using Phidgets or Netduino is a series of trade-offs. I can code Phidgets in C# or F# but I have to code Netduino in C#. I would prefer to do this in F# so that makes me learn towards Phidgets. I can put the Netduino anywhere and have it communicate via an Ethernet signal but I have to have the Phidgets wired to the PC. Since the targeting system needs to be near the Kinect and the Kinect has to be tethered to the PC also, there is no real advantage of using the mobile Netduino. Finally, the Phidgets API handles all communication to the servo control board for me, with the Netduino I would have to hook up a router to the Netduino and write the Ethernet communication code. So I am leaning towards Phidgets, but since I am not sure, the interface allows me to swap in the Netduino at a later point without changing any code. Love me some O in SOLID…
Up next, integrating the targeting system into the Terminator program.
Pingback: F# Weekly #33, 2014 | Sergey Tihon's Blog