Share via


Making the Robot Arm Move Again – on .NET Gadgeteer

Technorati Tags: .NET Micro Framework,.NET Gadgeteer,Robotics

6 weeks ago, I posted a blog about controlling a robot arm with the new Netduino board (https://blogs.msdn.com/b/netmfteam/archive/2010/08/30/making-the-robot-arm-move-again.aspx).  I used an available Arduino joystick shield and three of the 4 PWNs available on the Netduino.  The arm actually has 6 servos (or servo pairs) so I thought I’d add .NET Gadgeteer to control three servos making this a hybrid. 

 IMG_0224 (2) 

I mounted both solutions side by side on some acrylic.  You can see the Netduino solution on the right and the Gadgeteer solution on the left.  The Gadgeteer solution is made up of the main board, a Dpad module, three motor controller modules, and the 4.3 inch touch enabled display.  You can see the power connection – in the center front.  The motor controllers are switchable between using power from the main board or external power.  In this case, I set them up to use  power from a 5V wall wart. 

IMG_0220

On the Netduino side, I added an LED to show which servo is selected.  The rest of the logic did not change.  As you may recall, the joystick sends analog input through the horizontal or vertical axis and also works as a standard button (GPIO) when pressed.  The logic is a continuous loop checking for analog input from the Joystick and an event handler to change the targeted servo.  (see the previous blog for the code).  Pretty straightforward.

IMG_0221

On the Gadgeteer side, I use the Dpad module in place of the Joystick.  It has the same basic logic – up, down, left, right however, instead of continual polling of the analog input, I get two events, one when the Dpad is pressed in a certain direction and the other when it is released which set state variables.   A single event handler is needed as the direction is an argument to the handler.  I still have a loop called ProcessDPAD():

void ProcessDPAD()
{
while (true)
{
_DPADalert.WaitOne();

              while (_moveServo)
{
_servoPosition[_targetServo] += _increment;
if (_servoPosition[_targetServo] > 1.0)
{
_servoPosition[_targetServo] = 1.0;
_moveServo = false;
}
else if (_servoPosition[_targetServo] < 0.0)
{
_servoPosition[_targetServo] = 0.0;
_moveServo = false;
}
_servo[_targetServo].DriveServo(_servoPosition[_targetServo], _time);
Thread.Sleep(100);
}
}
}

but I run this in a dedicated processor  thread and an event handler to alter the processor to change the targeted servo.  Still pretty straightforward and still asynchronous

_processor = new Thread(new ThreadStart(this.ProcessDPAD));
_processor.Start();

so that it doesn’t interfere with the responding to the events that come in from the DPad.

To set the target servo to be controlled by the Dpad module, I use a touch interface on the 4.3 in display.  OK – I clearly am not a UI guy so no wise cracks.  :-) All the touch setup is taken care of in the constructor for the Display_480x272  object.  The buttons are a simple UIButton class that I used in the Bicycle Computer and other projects.  It handles user feedback on the button press and dispatching a Click event. 

IMG_0222

_display = new GTM.Display_480x272(GTM.Display_480x272.CompatibleSocket.P, GTM.Display_480x272.TouchPanelCompatibleSocket.D);

In the Netduino project, I created a Servo class to wrap the PWM and to set each servo so that I could position it as a percentage of its total range.  In the Gadgeteer, the Motor class already has that same functionality so I just used that .  

GTM.Motor[] _servo = new GTM.Motor[3];

_servo[0] = new GTM.Motor(GTM.DaisyLinkModule.CompatibleSocket.M);
_servo[1] = new GTM.Motor(GTM.DaisyLinkModule.CompatibleSocket.M);
_servo[2] = new GTM.Motor(GTM.DaisyLinkModule.CompatibleSocket.M);

The motor controller modules all daisy chain to the same socket on the main board.  The daisy chain logic is pretty cool in that it is self-enumerating.  You can use an array like this or more meaningful names as you wish.  The association is that the first module instantiated is the first one on the daisy chain and so on down the rest. 

While there are some differences in capabilities (like support for a large display) the big difference in the two programming environments is that with Gadgeteer, you don’t need to understand PWM or analog input or anything ‘electronic’.  You just plug it in and then program to some very high level, event driven interfaces.  The trade-off is of course, flexibility.  The .NET Gadgeteer supports the modules that it supports so if you can build what you want with those, you are golden.  If not, you still have the option of using the breakout boards and the analog input and digital IO modules but those are pretty much the same as the existing programming model. 

IMG_0219