NXT xBee Remote Control

Hi everyone,

Since I was a kid, I’ve always wanted to rip apart a few of my old electronics toys and give them Remote control capabilities. After a bit of reading and coding in Arduino from a college course, I’ve finally been able to come very close to success!

Heres the project:
To control a robot built from NXT components (motors and lego parts) that can be wirelessly controlled via a PS3 controller communicating to the robot through the computer via xbee shield communication.

Here’s the status:
The basics are complete!
Thanks to Clinton Blackmore’s work on the NXT motor library, sending messages to run the motors has been pretty simple.
I used the ProControll library in Processing to write a Processing sketch that listens to the Bluetooth Ps3 controller and outputs a mapped value of the analog inputs of each controller to xbee connected via a Serial Port.

Here’s the problem:

So far the Arduino is INDEED listening to the commands sent over through the xbees, but it doesn’t always perform the right actions based on what is being sent from the controller. To resolve this, I’ll simply press the reset button a few times on the the Arduino until it starts mimicking the correct commands sent from the controller.

I’ve cracked down the problem to lie somewhere within the actual serial communication. I believe that I’m not sending over data efficiently. Does anyone have any suggestions regarding how to best send over data? Right now I’m storing the received data in an array, interpretting it, and sending the corresponding commands to the motors.

Thanks for the help everyone! I appreciate any feedback!

Lastly,
Here’s my Arduino code:

// Joshua Vasquez
// Wireless NXT Tread Control
// via Xbee Shield
// December 19, 2010

/* The following Program…

  1. sets up the NXT Motors
  2. Listens to the Serial commands
  3. responds to the PS3 controller (which is sending commands
    via bluetooth to the xbee shield connected to the laptop)
  4. interprets the data sent over the xBee shields
  5. Runs accordingly!
    */

#include <NXTI2CDevice.h>
#include <NXTMMX.h>
#include <Wire.h>

NXTMMX Bob; // The name of the NXT

const int loadTime = 1000; // delay time in void setup.

int Command= {4,5,4,5};
/*
An array for storing commands sent to the NXT.
The first two digits correspond to the left motor’s analog speed.
The second two digits correspond to that of the right motor.
*/

int leftSpeed = 45; // the starting speeds of the left
int rightSpeed = 45; // and right motors.
/*
At speed 45, both motors will map this value to a
speed of zero. Neither motor will move before any commands
are sent.
*/

void setup()
{
Serial.begin(9600); // open communication between xBees
Bob.reset(); // resets the NXT (which I named “Bob” )
/*
Next, we delay for loadTime to ensure that both
the Serial communication is ready and that
the NXT has had enough time to reset.
*/
Serial.print("Delaying for… "); Serial.print(loadTime);
delay(loadTime);
Serial.println(“I’m now ready for action!”);

}

void loop()
{
if (Serial.available() > 3) // if a valid command is being sent,
// (commands come in the form of 4 integers)
{
for (int i = 0; i<4; i+=1)
{
// store each command to an array
Command = Serial.read() - 48;

  • }*

  • }*

// Now convert this array to two integers that correspond to speed
// values.
_ leftSpeed = 10Command[0] + Command[1];_
_ rightSpeed = 10
Command[2] + Command[3];_

  • // uncomment this component for tests.*
    _ /*_
  • Serial.print(leftSpeed);*
  • Serial.print(" ");*
  • Serial.print(rightSpeed);*
  • Serial.println(" ");*
    _ */_

/* Now, we need to decide:

  • the speed and*
  • the direction that each motor should move.*
  • This task is handled by an if/else statement for each motor.*
    */

// For the Left Motor:

  • if (leftSpeed >= 45)*
    /* Move forward if the command is a value from 45 to 80,

  • but first Map the value to a value understood by the*
    _ Nxt I2c motor library */_

  • {*

  • leftSpeed = map(leftSpeed,45,80,0,80);*

  • Bob.runUnlimited(MMX_Motor_2,*

  • MMX_Direction_Forward,*

  • leftSpeed);*

  • }*

  • else*
    _ /* Move backward if the command is a value from 0 to 44,_

  • but first Map the value to a value understood by the*
    _ Nxt I2c motor library */_

  • { leftSpeed = map(leftSpeed,44,10,0,80); *

  • Bob.runUnlimited(MMX_Motor_2,*

  • MMX_Direction_Reverse,*

  • leftSpeed);*

  • }*

*// For the Right Motor *

  • if (rightSpeed >=45)*

  • {*

  • rightSpeed = map(rightSpeed,45,80,0,80);*

  • Bob.runUnlimited(MMX_Motor_1,*

  • MMX_Direction_Forward,*

  • rightSpeed);*

  • }*

  • else*

  • { *

  • rightSpeed = map(rightSpeed,44,10,0,80); *

  • Bob.runUnlimited(MMX_Motor_1,*

  • MMX_Direction_Reverse,*

  • rightSpeed);*

  • }*

  • // Uncomment this code for tests. *
    _ /*_

  • Serial.print(leftSpeed);*

  • Serial.print(" ");*

  • Serial.print(rightSpeed);*

  • Serial.println(" ");*
    _ */ _

}