Phidgets Servo Motor and JavaScript
Thanks to some snappy USB-enabled hardware, and Adobe AIR, your web applications now have access to environmental data such as temperature, barometric pressure, humidity and light levels, as well as sensing any RFID tags that might come near. And that is really just the tip of the iceberg of the types of physical data to which your applications can react. But what if you want your web application to go the other way? What if you want to reach out to the physical world and make something happen? Ladies and gentlemen, I give you the Phidget Servo Motor.
What’s a servo motor? Well, motors in general, come in a variety of form factors. There is everything from the motor in your car or lawn mower, down to the motors that drive radio controlled (RC) cars and even small toys. Since we have only a limited amount of power coming from our USB port, I’m sorry to report that you won’t be cranking over your car any time soon. That voltage is however, capable of driving the RC type motors, and that is what the Phidget Servo Motor is designed to provide.
Without further delay, here is the list of steps necessary to get from hardware to computer (again). While we are interested in going the other direction, the steps are the same.
1. Hardware
2. Serial to Socket Server
3. Socket Library
4. Your Code and Innovation
Hardware
The Phidget Servo Motor Kit comes with a HiTec HS-322HD servo. So what’s a servo?

Well, it is a class of motor that uses internal feedback in some fashion to know where the position of the motor sits. Take for example the motor in your car. It does not know where it sits (how far it has rotated), nor does it matter. You push the gas, the motor turns over, and you control the rate and direction yourself. The motor in your car is not a servomechanism.
What if however you wanted to precisely control the position of that motor? That is to say that if you told it to spin to a given angle, that it would always hit the same spot – and hold that position. Your motor would need to know, via internal feedback, how far it had turned. Let’s say you put your airplane on autopilot and wanted a motor to drive the direction of the plane – that motor better be really sure of its position. That is a servo motor.
Taking it back to your car, the motor that you activate when you turn on your cruise control is a servomechanism. It uses environmental feedback to hold your speed at a constant rate.
The servo motor itself doesn’t know about USB, but Phidgets provides a connector board that sits between the servo motor and the USB port. Phidgets even provides a board that can control up to eight (8) servo motors. If perhaps you are not interested in a servo motor, and just want the thing to spin when you tell it, and for some duration of time in a given direction, then Phidgets also provides a DC motor kit. Bottom line for us in this case is that we’ll be using the Phidgets Servo Motor Kit.
Serial to Socket Server
I’ve already covered this in depth in a previous post on the topic of Phidgets. Essentially, Phidgets provides what they call a “driver” that sits on the computer and listens for incoming data from the USB port. It then broadcasts that data to any devices connected to a TCP/IP port via socket (not HTTP). All of the various Phidgets you can get can be controlled by the one driver software, you don’t need a new/additional one for each component. So, if you’ve been following along, then you are all set.
Socket Library
Here again, as it relates to Phidgets, I have covered this in a previous article. Fundamentally, we leverage the ability of Adobe AIR to expose Flash libraries to JavaScript directly. We write the JavaScript to listen for events, and then have our program react to those events. In this case however, we will use the Phidgets API to tell the servo what to do. And again, if you have been following along, and already have the library and the SCRIPT snippet to make it work, then you are good to go. The same library works for all available Phidgets.
Your Code
As before, the first step is to instantiate a reference to the Phidget class you are interested in using. In this case, that is the PhidgetServo class. Since we will be telling the servo what to do, and not it telling our program to do something, there are not really any events you absolutely need. That being said, you might want to know when the connection to the servo has been made, just so you are sure it is there.
// Variables to be used var phidget = null; $( document ).ready( function() { phidget = new runtime.com.phidgets.PhidgetServo(); // Listen for when attached phidget.addEventListener( runtime.com.phidgets.events.PhidgetEvent.ATTACH, function( evt ) { // Set the servo all the way to one side // The "minimum" side phidget.setPosition( 0, phidget.getPositionMin( 1 ) ); // Create a slider within the range of the servo // Listen for slide changes to move servo position $( '#slider' ).slider( { min: phidget.getPositionMin( 1 ), max: phidget.getPositionMax( 1 ), slide: function( evt, ui ) { phidget.setPosition( 0, ui.value ); } } ); } ); // Open a connection to the servo (Phidget socket server) phidget.open( 'localhost', 5001 ); } );
In the above code snippet you can pretty clearly see what it takes to drive a servo motor – one line that tells the servo to set it’s position. In this case, I tell the servo to zero out, or spin as far one way as it can just so I know where it is at for the duration of the application. You might be wondering what “position” means – is it an angle? Is that degrees or radians? Actually, none of the above.
Through the aforementioned internal feedback, the servo knows where it is at in terms of rotation, but different servos have different ranges. In the case of Phidgets, that rotation is expressed as a minimum point of rotation, and a maximum point of rotation. You can look at the numbers that relate to those points, and calculate a total range. You can then divide that up to tell the servo to go to a specific position. The number you give it won’t be an angle expressed in degrees or radians, but rather a number that means a specific point, to that specific servo motor.
It is also worth noting that servos may have zones at the minimum and maximum side that the gears cannot physically reach. So if “0” was the minimum reported by the servo, and you told it to go to “10” you might not get any visible activity from the servo until it past “5”. You will want to experiment with your particular servo to find actionable ranges.
Oh, and if you don’t like those dead zones, then you can pay more money for a higher quality servo. Pay enough money, and you may just end up with the same servo a plane might use for autopilot. How you use it is up to you – plane not required.
The only other thing I like to listen for isn’t a Phidget event, but rather an Adobe AIR event – I like to know when the application is closing. This is one of those things that’s really hard to do across browsers, but that is reliably surfaced for you in AIR. Why do I care when the application quits?
Well, in the case of a servo, I like to turn off the power so the motor doesn’t overheat. Keep in mind that to hold a specific position, the servo will be constantly pulling electrical current to power the internal feedback. Over time, that little motor will get downright hot to the touch. And because we have to go through the serial-to-socket bridge, if we don’t tell the servo that the application has exited, and that we no longer need its services, then it will keep trying to hold that position so long as the motor is connected to the USB port.
// Stop powering the servo when the application exits air.NativeApplication.nativeApplication.addEventListener( air.Event.EXITING, function( evt ) { phidget.setEngaged( 0, false ); } );
And Innovation
Here are two little samples for you to check out. The first is a barebones servo example. It uses jQuery UI to present a slider. When you move the slider, the servo will move to the respective position of its actionable rotation range. It has all the parts and pieces already in place from the AIR application descriptor file, to the Phidgets library SWF, to the jQuery UI elements. Done.

For the second example, I wanted to display something moderately useful. Since I intend to demonstrate this project, I also needed it to be portable, and to deliver activity on demand.

I hit inspiration when I came across a web site called “emotionstream” that allows you to check the emotional status of a specific Twitter account. In playing around with the web site, it was clear that the developer was leveraging Ajax techniques to request data in the background, and build the respective user interface. As SOA goes, so goes a good AIR application, and after reviewing the code, I found the following URL signature would return to me JSON data with all the relevant emotional data.
http://www.emotionstream.com/ws/useremotions.php?user=parkerkrhoyt
You might be saying “Wait, that’s a different domain. You can’t do that!” Actually with AIR there are no cross-domain limitations, and I can use good old Ajax techniques to request data from any endpoint I so choose. Sure it’d be great if the developer wrapped his API up in some JavaScript for me to include, but we’re just talking HTTP GET requests here, with some query strings on the end. Done.
With the data at hand, the next step was for me to display search results. In this case, the Emotionstream data may not have emotions for every day. Say for example that you didn’t tweet regularly. If you’ve been using Twitter for any amount of time however, it does generally return with at least seven previous, but not necessarily consecutive, days. My application shows those days in the AIR user interface.

Also in the user interface is a slider that allows you to scroll to a specific date. I custom built the slider for this application after having a hard time getting the specific results I wanted from jQuery UI. It responds to being dragged by the mouse, but also moves to whatever date is clicked on, or even handles keyboard arrows to move around. I even designed it to snap to the closest date in case you stopped part way through. When a date is selected, the program tells the Phidgets servo attached to the system to turn to a specific point.
I experimented for a little while with this servo to find the actionable range. Once I had that, I divided the range by the eight (8) different emotions that can be returned by Emotionstream. A little cardboard and a few “for sale” stickers later, I was able to reliably turn the servo to a specific emotion. Yes, that’s thread (as in sewing) that holds the cardboard to the servo. It’s what I had around at the time – don’t ask why.
In a perfect world, this AIR application would run as a background process – yes, AIR applications can do that too. It would periodically ping the Emotionstream service and rotate the servo to show me the emotional states of my friends. The only other missing piece would be an LED display to show which Twitter friend was showing. Oh, but you know what? Phidgets makes that too, and now that you’re getting the hang of this hardware stuff, you could probably add that on yourself. Enjoy!
September 11th, 2009 at 8:12 pm
Simply amazing. I wish I had something more intelligent to say – but I believe this is the first tech post I’ve seen in my entire life that involved cardboard.
September 12th, 2009 at 6:53 pm
First of all I would just like to say what a wonderful series of posts. I look forward to more, I do have a question though:
Would it be possible to send data to drive a USB device like a Dream Cheeky LED message board http://www.dreamcheeky.com/index.php?pagename=product&pid=52 ?
Device technical information can be found here http://www.last-outpost.com/~malakai/dcled/USB%20LED%20Message%20Board%20-%20Developer%20Manual%20v1.0.pdf
Thanks
September 13th, 2009 at 5:17 am
Awesome post. I look forward to seeing more on the subject!
-JD
September 21st, 2009 at 12:16 am
It’s nice that they’ve made the documentation available, and based on that, I’d say that it looks feasible. It worries me that they say they only support Windows, but that may be simply because they don’t have Mac developer skills on hand. On the other hand, it may be that their USB stack on the device doesn’t show up on Mac. Don’t know if it matters to you.
I didn’t see a price listed, and couldn’t find a vendor with the message board. 27×7 is 189 LEDs. Driving that many lights is a project I’ve been wanting to get into for a while, but just haven’t found the time. Maybe as this series progresses…
Thanks for the comment!
October 22nd, 2009 at 5:59 am
Hi Kevin,
Just a curious question.
Why you put AS3 code in JS environment?
What’s its benefit? (I mean you can create the same thing with a standard Flash/Flex project)
Also, how to develop/debug within a JS project? It have many different code standards (AS, JS, etc.).
Joseph
October 26th, 2009 at 3:59 pm
Joseph,
To be clear, I’m not coding any AS3 here, this is still all JavaScript. In the case of AIR however, JavaScript can leverage AS3 libraries directly through JavaScript. The reason for doing this is to not reinvent the wheel.
Flash has been able to do things that JavaScript cannot for some time, so it’s natural that libraries exist for things in AS3, that do no exist in JavaScript. Again, when it comes to AIR, that doesn’t mean you should be cut out of using them just because you’re using JavaScript. So, include the AS3 library via SCRIPT tag, and you have access to whatever that AS3 library provided, but from JavaScript.
Kevin
January 1st, 2010 at 4:28 am
one Christmas, i was about 10 or 12 at the time…