XBee Control of .NET Gadgeteer Robot

The code in this brief example is part of an investigation into bandwidth and latency of XBee radios used for remote control.  I’d be interested in any other experiments with XBees.  If you have something, we can discuss a guest post.  There are several versions of this robot now.  The original by Eduardo Velloso uses light sensors and can be controlled with a flashlight.  Others by Marco Minerva and MJ Sharma use Bluetooth remote control.

This experiment uses the same robot chassis as the version designed by Eduardo Velloso, which is described on the .NET Gadgeteer team blog and Eduardo’s blogAssembly of the robot and XBee configuration details have been discussed elsewhere.  The remote control device and the the robot receiver, in this case, are modified to use XBee radios.  The XBeeClient libraries from the codeplex project by Paul Mineau are the core of the application. 

This version of the robot and the controller use Spider mainboards from GHI Electronics instead of the Hydra mainboard, also from GHI Electronics that Eduardo used in the earlier version.  Instead of light sensors, this version uses a GHI Electronics potentiometer to control the speed and direction of the robot.

Controller Device Code

The following code block shows the remote control device. The control mechanism is simply to send the voltage reading from the potentiometer via the XBee radio on the controller to the XBee radio on the robot.  If the user turns the potentiometer all the way to zero, the controller sends a “stop” message instead of the voltage.  A timer initiates the control signals at two second intervals.  This is an ad hoc limit that I found using a baud rate of 9600.

using Microsoft.SPOT;

using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;

namespace SpiderController
{
    public partial class Program
    {
        GT.Timer timer;

        void ProgramStarted()
        {
            xBeeClient.DataReceived +=
                new GTM.Community.XBee.DataReceivedEventHandler(xBeeClient_DataReceived);
            button.ButtonPressed += new Button.ButtonEventHandler(button_ButtonPressed);

            timer = new GT.Timer(2000);
            timer.Tick += new GT.Timer.TickEventHandler(timer_Tick);
            Debug.Print("Program Started");
        }

        void timer_Tick(GT.Timer timer)
        {
            double potVoltage = potentiometer.ReadPotentiometerVoltage();
            if (potVoltage > 0)
                xBeeClient.UploadStringAsync(potVoltage.ToString());
            else
                xBeeClient.UploadStringAsync("stop");
        }

        void xBeeClient_DataReceived(object sender, GTM.Community.XBee.DataReceivedEventArgs e)
        {
            Debug.Print("my data received: " + e.Data.ToString());
        }

        void button_ButtonPressed(Button sender, Button.ButtonState state)
        {
            if (!button.IsLedOn)
            {
                timer.Start();
                button.TurnLEDOn();
            }
            else
            {
                timer.Stop();
                xBeeClient.UploadStringAsync("stop");
                button.TurnLEDOff();
            }

        }
    }
}

Receiver Device Code

The receiver is not much more complex than the controller.  The voltage readings from the potentiometer range from 0 – 3.3 volts.  If each voltage reading received from the controller is not a “stop” signal, it is truncated to four digits and parsed as type double.  The if statements divide the potentiometer readings into four segments that control the speed of the tracks running on the robot.

using Microsoft.SPOT;

using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;

namespace SpiderReceiver
{
    public partial class Program
    {
        const int maxSpeed = 60;

        void ProgramStarted()
        {
            xBeeClient.StringReceived +=
                new GTM.Community.XBee.StringReceivedEventHandler(xBeeClient_StringReceived);
            button.ButtonPressed += new Button.ButtonEventHandler(button_ButtonPressed);
            Debug.Print("Program Started");
        }

        void button_ButtonPressed(Button sender, Button.ButtonState state)
        {
            xBeeClient.UploadStringAsync("test from receiver");
        }

        void xBeeClient_StringReceived(object sender, GTM.Community.XBee.StringReceivedEventArgs e)
        {
            if (e.Message.IndexOf("stop") != -1)
            {
                motorControllerL298.MoveMotor(MotorControllerL298.Motor.Motor1, 0);
                motorControllerL298.MoveMotor(MotorControllerL298.Motor.Motor2, 0);
                return;
            }

            double direction = double.Parse(e.Message.Substring(0, 4));

            if (direction > 1.55 && direction <= 2.2)
            {
                motorControllerL298.MoveMotor(MotorControllerL298.Motor.Motor1, maxSpeed);
                motorControllerL298.MoveMotor(MotorControllerL298.Motor.Motor2, maxSpeed);
                return;
            }
            if (direction > 0.45 && direction <= 1.55)
            {
                motorControllerL298.MoveMotor(MotorControllerL298.Motor.Motor1, maxSpeed / 2);
                motorControllerL298.MoveMotor(MotorControllerL298.Motor.Motor2, maxSpeed);
                return;
            }
            else if (direction > 0 && direction <= 0.45)
            {
                motorControllerL298.MoveMotor(MotorControllerL298.Motor.Motor1, 0);
                motorControllerL298.MoveMotor(MotorControllerL298.Motor.Motor2,  maxSpeed / 2);
                return;
            }
            else if (direction > 2.2 && direction <= 3.0)
            {
                motorControllerL298.MoveMotor(MotorControllerL298.Motor.Motor1, maxSpeed);
                motorControllerL298.MoveMotor(MotorControllerL298.Motor.Motor2, maxSpeed / 2);
                return;
            }
            else if (direction > 3.0)
            {
                motorControllerL298.MoveMotor(MotorControllerL298.Motor.Motor1, maxSpeed / 2);
                motorControllerL298.MoveMotor(MotorControllerL298.Motor.Motor2, 0);
                return;
            }
        }
    }
}

, , ,

  1. #1 by bhugun belal on June 11, 2012 - 8:30 AM

    hye, do you have the schematic diagrams please?

Leave a comment