Pages: [1]   Go Down
Author Topic: Uno, Joystick, XBee and Motor Shield  (Read 687 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Everyone

This is my first post and I've started looking at Arduino for a few small projects whilst in rehab from a major accident. So I do have a bit of time on my hands, however that being said I have run into a bit of a problem that has resulted in this post (must be a little impatient I guess) hope someone can point me in the right direction.

I have looked at a number of tutorials relating to the Xbee and the Motor Shield I purchased. I am at a stage where I have my Xbees talking, I can control the required 2 Motors by passing a variable to the second Arduino with the motor shield. But I now have two more steps (questions)

Thanks in advance. Renwaar.

1, How can I make two variables pass to the second Arduino so that it will move my project in two directions at once i.e. horizontal and vertically resulting in a diagonal movement?

2, I wish to control the speed based on the Joystick position. I have this working fine in my head of course but just need a little help with the code if someone has the time?

Here is the code I have managed so far:

Joystick Arduino:
Code:
//Code from Sparkfun with a few tweeks

const byte PIN_ANALOG_X = 0;
const byte PIN_ANALOG_Y = 1;

const int X_THRESHOLD_LOW = 450;   //I have the contrains real big so there's less chance for
const int X_THRESHOLD_HIGH = 550;  //analog misinterpretation.

const int Y_THRESHOLD_LOW = 450;
const int Y_THRESHOLD_HIGH = 550;

int x_position;
int y_position;

int x_direction;
int y_direction;

void setup() {
Serial.begin(9600);
}

void loop () {
x_direction = 0;
y_direction = 0;

x_position = analogRead(PIN_ANALOG_X);
y_position = analogRead(PIN_ANALOG_Y);


if (x_position > X_THRESHOLD_HIGH) {
x_direction = 1;
} else if (x_position < X_THRESHOLD_LOW) {
x_direction = -1;
}

if (y_position > Y_THRESHOLD_HIGH) {
y_direction = 1;
} else if (y_position < Y_THRESHOLD_LOW) {
y_direction = -1;
}


if (x_direction == -1) {
if (y_direction == -1) {
Serial.println("left-down");
} else if (y_direction == 0) {
Serial.println("a");                // "a" is horiz pan right
} else {
// y_direction == 1
Serial.println("left-up");
}
} else if (x_direction == 0) {
if (y_direction == -1) {
Serial.println("s");                // "s" is verti pan up
} else if (y_direction == 0) {
Serial.println("f");                // "f" is for Stop until something else is sent
} else {
// y_direction == 1
Serial.println("w");                // "w" is verti pan down
}
} else {
// x_direction == 1
if (y_direction == -1) {
Serial.println("right-down");
} else if (y_direction == 0) {
Serial.println("d");                // "d" is horiz pan left
} else {
// y_direction == 1
Serial.println("right-up");
}
}}

Motor Shield Arduino:
Code:
#include <AFMotor.h>

AF_DCMotor horiz(1, MOTOR12_1KHZ);
AF_DCMotor verti(2, MOTOR12_1KHZ);
AF_DCMotor motors[2] = {horiz, verti};

void setup(void)
{
 Serial.begin(9600);
}
void loop(void)
{
 while (Serial.available() < 0) {} // Wait until a character is received
 char val = Serial.read();
 int Xspeed = 255; //255 is maximum speed
 int Yspeed = 255;
 //horiz.setSpeed(155);
 //verti.setSpeed(255);
 
 switch(val) // Perform an action depending on the command
 {
  case 'w'://Verti Pan Down
  verti.setSpeed(Yspeed);
  verti.run(FORWARD);
  Serial.print("Pan Down");
  break;
  case 's'://Verti Pan Up
  verti.setSpeed(Yspeed);
  verti.run(BACKWARD);
  Serial.print("Pan Up");
  break;
  case 'a'://Horiz Pan Right
  horiz.setSpeed(Xspeed);
  horiz.run(FORWARD);
  Serial.print("Pan Right");
  break;
  case 'd'://Horiz Pan Left
  horiz.setSpeed(Xspeed);
  horiz.run(BACKWARD);
  Serial.print("Pan Left");
  break;

  case 'f'://Stop
  horiz.run(RELEASE);
  verti.run(RELEASE);
  break;

  default:
  break;
 }
}
« Last Edit: June 19, 2012, 02:42:12 am by Renwaar » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi there,
I think the best way to do this would be to send two values between 10-99 over serial that control motor speed, which the second arduino would re-map back to 1-255 to output using PWM to the motor drivers.

THE 10-99 IS VERY IMPORTANT. If you sent a straight PWM(1-255) value, then if one variable was 23, and the other 223, and your variables on the receiving end were reading three characters, then the first variable will read 232 and the second 32. That is probably not what you want. the 10-99 keeps the variable two digits no matter what, and

Here is what you should do: 
-read joystick and map the values for x and y to 10-99. ex: map(motorOutputvariable, 1,255,10,99); map(variable, variable range min, variable range max, new range min, new range max)
-use itoa to make the two(or more variables) into a string.
-send string using the Serial.println(variable); command.
-then loop

Serial Sending Code:
Code:
//Written by njs552 06/18/2012
//Last Modified: 06/18/2012 1806hrs PST
//Released to the public domain

//=============================================================
//MARK: USER INTERFACE
//Debug
int debug = 0; //0 = off, 1 = on
//=============================================================
//MARK: Pin Declarations
//Headtbeat
int ledPin = 9;
//=============================================================
//MARK: VARIABLES:
int variable_1 = 20;
int variable_2 = 43;
int variable_3 = 51;
int variable_4 = 74;
//=============================================================
//MARK: Serial
char replySerial[25];
char sendSerial[100];

byte startByte = '#';
byte endByte = '*';
//=============================================================
//MARK: TIMING VARIABLE DECLARATION SECTION
//Heartbeat Blink
unsigned long lastHeartbeatTime = 0; 
unsigned long heartBeatInterval = 1000; //1sec
bool heartbeatState = false;

//send serial
unsigned long lastSend = 0;
unsigned long currentTime;
unsigned long sendInterval = 100;

//===================================================================================================================================
//===================================================================================================================================
//===================================================================================================================================
//===================================================================================================================================
//===================================================================================================================================

void setup()
{
Serial.begin(9600);

if(debug == 1)   //1 = ON, 0 = OFF
{
Serial.println("Started");
}

pinMode(ledPin, OUTPUT);
}
//=============================================================
void loop()
{
unsigned long currentHeartbeatTime = millis();
currentTime = millis();

if(currentTime - lastSend > sendInterval)
{
lastSend = currentTime;
sendOverSerial(); //send serial packet
}

  //heartbeat or "dead" ROV
if(currentHeartbeatTime - lastHeartbeatTime > heartBeatInterval) //if more tine than interval has passed
{
lastHeartbeatTime = currentHeartbeatTime; //set last time to current time

if(heartbeatState == false) //if led is off
{
heartbeatState = true; //set its state to on
}
else
{
heartbeatState = false; //if on, set state to off
}           
}
digitalWrite(ledPin, heartbeatState); //write the led on or off, depending on state
}


//=============================================================
inline void sendOverSerial()
{
memset(sendSerial, 0, sizeof(sendSerial));

    itoa(variable_1, replySerial, 10);
    strcat(sendSerial, replySerial);
    itoa(variable_2, replySerial, 10);
    strcat(sendSerial, replySerial);
    itoa(variable_3, replySerial, 10);
    strcat(sendSerial, replySerial);
    itoa(variable_4, replySerial, 10);
    strcat(sendSerial, replySerial);

if(debug == 0)
{
Serial.write(startByte);
Serial.write(sendSerial);
Serial.println(endByte);
}
}

Serial Receive Code:
Code:
//written by Njs552 (06/18/2012)
//last modified 06/18/2012 1825hrs PST
//released into the public domain
//=======================================================
//MARK: Serial
char incomingData[100]; //to store incoming serial data
char variable[4];
//=======================================================
//MARK: Timing Variables
//Serial receive
unsigned long last1 = 0;
unsigned long interval1 = 50;
unsigned long current1;
//======================================
void setup()
{
Serial.begin(9600);
}
//============================
void loop()
{
current1 = millis();
receiveSerial();
}
//==========================================================================
inline void receiveSerial()
{
byte ch;
static int cpt=0;
static byte flag=false;

if (Serial.available()>0)
{
ch = Serial.read();

switch( ch )
{
case '#' :
{
cpt =0;
flag=false;
break;
}
case '*' :
{
flag=true;
break;

default: //else of a switch statement
{
incomingData[cpt++]=ch;
}
}
}

if (flag==true)
{
variable[0] = incomingData[0];
variable[1] = incomingData[1];
variable[2] = incomingData[2];
variable[3] = incomingData[3];

memset(incomingData, 0, sizeof(incomingData));
}
        Serial.flush
Serial.println(variable);
}
 
You will have to add your code to this code to test this, but this code has worked for me in the past.

 
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi njs552,

Many thanks for the reply, I have been looking at this code and I am having a little difficulty still in getting where I need to be. You have answered how I get more than one variable across and I get that, the string and the itoa. But my issue is getting it to function with my code.

My Joystick provides only two values (Anaolog 0 and 1) Xpos and Ypos both 0-1024, so as I understand it I map that to Xpos 10-19, then Ypos to 20-29 etc. This will give me what you suggest, but then I have the speed to address which is 0-255, so do I re-map it again? Would I need to make something like: (not actual code just how I would imagine it obviously) :

Code:
variable1 = map(Xpos, 10,19,0,255);          // remap to 0-255
if Xpos < 120 horizMotor.run(BACKWARD) setspeed(Xpos)    // run the motor in desired direction and speed
if Xpos > 130 horizMotor.run(FORWARD) setspeed(Xpos)     // run the other motor in desired direction and speed

This is just how I would see it, but I'm not sure how to get this into the code (and make this syntax correct)

Could you maybe just add that line for me to see it in action, I see that you have explained it but I just can't quite nail it.

Thanks Again,

Renwaar
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
You could also map Xpos, Ypos, and Xspeed, and Yspeed  from 10-99 each, then send.

Serial send Code(Read Joystick):
Code:
variable1 = map(Xpos, 1, 1024, 10, 99);       // map controller input to 10-99 from original 1-1024
variable2 = map(Ypos, 1, 1024, 10, 99);       //same as above, but different axis
variable3 = map(Xspeed, 1, 255, 10, 99);      //x axis speed speed
variable4 = map(Yspeed, 1, 255, 10, 99);      //y axis speed
//send variable in string

Serial Receive Code(Motor Ourput):
Code:
variable[0] =  incomingData[0];
variable[1] =  incomingData[1];
variable[2] =  incomingData[2];
variable[3] =  incomingData[3];

variable1 = map(variable[0], 10, 99, 1, 1024);
variable2 = map(variable[1], 10, 99, 1, 1024);
variable3 = map(variable[2], 10, 99, 1, 255);
variable4 = map(variable[3], 10, 99, 1, 255);

This code then re-maps the values so they are very close to the original numbers.

Next:
if Xpos < 120 horizMotor.run(BACKWARD) setspeed(Xspeed);    // run the motor in desired direction and speed
if Xpos > 130 horizMotor.run(FORWARD) setspeed(Xspeed);     // run the other motor in desired direction and speed
if Ypos < 120 verticalMotor.run(BACKWARD) setspeed(Yspeed); //vertical motor and speed
if Ypos > 130 verticalMotor.run(FORWARD) setspeed(Yspeed);  //vertical motor other direction and speed

Please let me know if this helps, and feel free to ask any questions,
njs552
Logged

Pages: [1]   Go Up
Jump to: