Friday 6 July 2012

Gadgeteer Robotic Arm Controller

In this post i'm going to explain how to control a small 2dof robotic arm using .Net Gadgeteer.


The parts i am using for this project are
  • Fez Spider Mainboard
  • Dagu 2dof Robotic Arm
  • Gadgeteer Extender Module
  • Gadgeteer Button Module to control the gripper
  • Gadgeteer Potentiometer Module to control the arm.
The robotic arm consists of a gripper and two servos, the first servo controls the movement of the gripper, and the other moves the arm up or down (or left/right depending on how you mount it)

You could very easily adapt the code in this post to deal with a larger robotic arm with more servos.

Here is a quick video of the robotic arm in action. It's currently attached to the front of my gadgeteer robot.

Setting up the robotic arm


In order to wire up the Robotic arm i'm using an extender module with a header soldered onto it so that i can plug it into a breadboard easily.




First up the extender module needs to be connected to a pwm capable socket on the mainboard.
I used socket 8 on the Spider. Pins 7 and 8 on the extender module will be connected to the pwm connectors on the servos. The pwm connectors are orange. Positive is red and Ground is the brown connector.

We need to use a separate power source for the servos. Don't try and power them from the extender module. A battery pack of 4AA batteries or similar will work fine.

Our breadboard should be wired up as shown to the left.









Once everything is connected it's pretty simple to write some code to move the servos.

The only tricky part was figuring out the correct pwm values to send to the gripper servo in order to fully open and close it. This just required a bit of trial and error. The gripper servo can only move around 60 degrees because it is constrained by the gripper mechanism. If you try to move it too far beyond its limits, the servo will heat up extremely fast. The arm servo can move through 180 degrees.

I made a small class which simplifies use of the arm with gadgeteer, and can be re-used in other projects.

In the constructor of the RoboticArmController class we pass in a reference to the extender module, and specify which pins will be used for the gripper and the arm.

There are public methods which can be used to move the position of the gripper and arm. The position value passed to these methods should be in the range of 0 - 100. At position 0 the gripper is fully open, and at 100 it is fully closed.

 using System;  
 using Microsoft.SPOT;  
 using Gadgeteer.Modules.GHIElectronics;  
 using GT = Gadgeteer;  
 namespace GadgeteerRoboticArm  
 {  
   public class RoboticArmController  
   {  
     private const int ClawPwmMin = 1500;  
     private const int ClawPwmMax = 2200;  
     private const int ArmPwmMin = 600;  
     private const int ArmPwmMax = 2400;
  
     private const int ClawPositionMax = 100;  
     private const int ClawPositionMin = 0;  
     private const int ArmPositionMax = 100;  
     private const int ArmPositionMin = 40; 
 
     private uint _pwmPulsePeriod;  
     private GT.Interfaces.PWMOutput _clawPwm;  
     private GT.Interfaces.PWMOutput _armPwm; 
 
     public int ClawCurrentPosition { get; private set; }  
     public int ArmCurrentPosition { get; private set; } 
 
     public RoboticArmController(Extender extender, GT.Socket.Pin clawPin, GT.Socket.Pin armPin, uint pwmPulsePeriod)  
     {  
       if (extender == null)  
       {  
         throw new ApplicationException("robotic arm pwm extender not set up correctly");  
       }  
       _pwmPulsePeriod = pwmPulsePeriod;  
       _clawPwm = extender.SetupPWMOutput(clawPin);  
       _armPwm = extender.SetupPWMOutput(armPin);  
       Reset();  
     }
  
     public void Reset()  
     {  
       MoveClaw(ClawPositionMin);  
       MoveArm(ArmPositionMin);  
     } 
 
     public void MoveClaw(int position)  
     {  
       ClawCurrentPosition = Move(_clawPwm, position, ClawPositionMin, ClawPositionMax, ClawPwmMin, ClawPwmMax);  
     }
  
     public void MoveArm(int position)  
     {  
       ArmCurrentPosition = Move(_armPwm, position, ArmPositionMin, ArmPositionMax, ArmPwmMin, ArmPwmMax);  
     } 
 
     private int Move(GT.Interfaces.PWMOutput pwm, int position, int minPosition, int maxPosition, int pwmMin, int pwmMax)  
     {  
       position = position > maxPosition ? maxPosition : position;  
       position = position < minPosition ? minPosition : position;
  
       Servo(pwm, GetPwmPulseValue(pwmMax, pwmMin, position));
  
       return position;  
     } 
 
     private int GetPwmPulseValue(int max, int min, int position)  
     {  
       return (min + (((max - min) / 100) * position)) * 1000;  
     }
  
     private void Servo(GT.Interfaces.PWMOutput pwm, int pwmPulseHighTime)  
     {  
       pwm.SetPulse(_pwmPulsePeriod, (uint)pwmPulseHighTime);  
     }  
   }  
 }  

Using this class it is then easy to set up a demo application that closes and opens the gripper as a button is pressed and released, and moves the arm position dependant on the position of a potentiometer module.

Create a new Gadgeteer project in visual studio, add the the button, potentiometer and extender modules using the visual designer and then add the following code to Program.cs

 using System;  
 using System.Threading;  
 using Microsoft.SPOT;  
 using GT = Gadgeteer;  
 using Gadgeteer.Modules.GHIElectronics;  
 using GadgeteerRoboticArm;  
 namespace RoboticArmDemo  
 {  
   public partial class Program  
   {  
     private RoboticArmController _roboticArmController;  
     private GT.Timer _timer; 
 
     void ProgramStarted()  
     {  
       Debug.Print("Program Started");  
       _roboticArmController = new RoboticArmController(extender, GT.Socket.Pin.Seven, GT.Socket.Pin.Eight, 20000000);
  
       button.ButtonPressed += new Button.ButtonEventHandler(button_ButtonPressed);  
       button.ButtonReleased +=new Button.ButtonEventHandler(button_ButtonReleased);
  
       _timer = new GT.Timer(500);  
       _timer.Tick += new GT.Timer.TickEventHandler(_timer_Tick);      
     }
  
     void _timer_Tick(GT.Timer timer)  
     {  
       _roboticArmController.MoveArm((int)potentiometer.ReadPotentiometerPercentage());  
     }
  
     void button_ButtonPressed(Button sender, Button.ButtonState state)  
     {  
       _roboticArmController.MoveClaw(100);  
     }
  
     void button_ButtonReleased(Button sender, Button.ButtonState state)  
     {  
       _roboticArmController.MoveClaw(0);  
     }  
   }  
 }  

And thats pretty much all there is to it.

When the program is started, pressing and holding the button will close the gripper. Releasing the button will open the gripper again.


The position of the arm can be set using the potentiometer.


You can grab sample code to accompany this post from github

1 comment:

  1. hey rik,
    i am a final year student of engineering and my final year project is on robotic arm, please give me information on how to build a robotic arm inn simple manner please its urgent reply me fast

    ReplyDelete