Thursday, April 16, 2009

TinyOS: Control servo motor using telosb







For the class project, we made a robot that can be controlled by a Telosb mote. We used two Parallax modified (we did not modify it. The one can continuously rotate is called modified servo) servo motor. The servo motor is shown in figure. This servo motor can be controlled by PWM. The servo motor PWM timing diagram is shown in Figure. The wiring diagram for Parallax servo motor is shown in Figure. So the servo motor can be controlled by providing PWM to the I/O pin. You can try this by using a simple ciruit. PWM can also control the speed of the servo motor.

Now, lets see how we connect the servo motor to the Telosb. Telosb has two expansion connectors. We use the 10-pin connector. Pin 9 is ground. We used two servo motors, so that the robot can turn in Tank style. Therefore, we used Pin-3 and Pin-5 to control two servo motors. To forward straight, two servo motor must rotate in opposite direction. You will see it when you construct your robot. Now, we Telosb ADC converer to send PWM signal to Pin-3 and Pin-5. From the msp430 manual, you know that pins 60 and 61 are the ones you want to use. There is the NesC code for that.

In your configuration file:

components HplMsp430GeneralIOC;

App.Pin0 ->HplMsp430GeneralIOC.Port60;
App.Pin1 ->HplMsp430GeneralIOC.Port61;

In Module use the interfaces:

interface HplMsp430GeneralIO as Pin0;
interface HplMsp430GeneralIO as Pin1;

That is it. Now only thing you have to is is call
call Pin0.clr() or call Pin1.set();
in your timer. You can try this on your Oscilloscope if you are not sure. The only thing left is timing. We used three timers. One with period 18. Other two timers are fires once in 1 or 2 ms after the first timer starts. Here is the code for that. This code randomly sets the movement of the robot.

event void Boot.booted()
{
call Timer0.startPeriodic(18);
}


void forward()
{
call Timer1.startOneShot(1);
call Timer2.startOneShot(2);
}

void reverse()
{
call Timer1.startOneShot(2);
call Timer2.startOneShot(1);

}

void turnright()
{
call Timer1.startOneShot(2);
call Timer2.startOneShot(2);
}
void turnleft()
{
call Timer1.startOneShot(1);
call Timer2.startOneShot(1);
}

event void Timer0.fired()
{
count++;
call Pin1.set();
call Pin0.set();

switch(action){
case 1:
forward(); break;
case 2:
reverse(); break;
case 3:
turnright();break;
case 4:
turnleft();break;
default:
forward();

}

if(count % 100 == 0)
{

action = call Random.rand16() % 4 + 1;
if(action == 1 || action == 2)
count = 0;
else
count = 80;
}
}


event void Timer1.fired()
{
call Pin1.clr();

}
event void Timer2.fired()
{
call Pin0.clr();
}

That is pretty much everything. The source code is here: servo-telosb.zip

7 comments:

Anonymous said...
This comment has been removed by a blog administrator.
Rajendran Thirupugalsamy said...

Very nice indeed.

I want to try this out.

Could you tell the spec of your servo motor ?
I am concerned whether the 3V pulse from telosb can drive a 4-6V servo.

Naveed said...

How can we get Pulse Width in micro-second?

Unknown said...

Hi,
Thank for your instruction. However, I cannot download the servo-telosb.zip. Would you please upload it again!

Thank you

Unknown said...

please upload servo-telosb.zip again!

Anwar Mamat said...

I uploaded the zervo-telosb.zip again.

Unknown said...

Hi I am new to using tinyOS and the diffrent types of motes. I was wondering if this could be applied to Iris motes as well as Telosb? Any help in this matter would be greatly appreciated thank you.