Gamepad connected to computer controls servos connected to Arduino board?

I tried to follow the instructions at Principialabs.com but the person who created the article with video used Linux instead of Windows. Any suggestions?

jeffmorris:
I tried to follow the instructions at principialabs.com but the person who created the article with video used Linux instead of Windows. Any suggestions?

Find a windows programming language you can use and write a control program for use with the joystick. below is for a simple programming language called justbasic.

open "joystick demo" for window as #joy
'open "joystick demo" for graphics as #joy
OPEN "com1:9600,N,8,1,CD0,CS0,DS0,OP0" FOR OUTPUT AS #2
'#joy "down" 'put the pen down
#joy "trapclose [quit]"
timer 10, [readStick] 'every ten ms read the stick
wait

[readStick]
    scan
    readjoystick 1 'either 1 or 2
    '#joy "place 50 50"
    '#joy "\Reading X = "; Joy1x
    '#joy "\Reading Y = "; Joy1y
    '#joy "\Reading Z = "; Joy1z 'throttle slide
    '#joy "\Reading X = "; (Joy1x - 1200)/195
    '#joy "\Reading Y = "; (Joy1y - 1200)/195
    x = (Joy1x - 1200)/195
    y = (Joy1y - 1200)/195
    x1 = int(x)
    y1 = int(y)
    if x1 > 255 then x1 = 255
    if y1 > 255 then y1 = 255
    '#joy "\Reading X1 = "; x1;"  "
    '#joy "\Reading Y1 = "; y1;"  "
    '#joy "\Reading jb1 = "; Joy1button1;"  "
    '#joy "\Reading jb2 = "; Joy1button2;"  "

    if Joy1button1 = 1 then
        PRINT #2, CHR$(00); CHR$(128); CHR$(x1);
        PRINT #2, CHR$(01); CHR$(128); CHR$(y1);
    end if

     if Joy1button2 = 2 then
        PRINT #2, CHR$(00); CHR$(128); CHR$(x1);
        PRINT #2, CHR$(01); CHR$(128); CHR$(y1);
    end if

    wait

[quit]
    CLOSE #2
    close #joy
    end

map(lMotorSpeed, 0, 127, 0, 127);
map(rMotorSpeed, 0, 127, 0, 127);

Yes these should be,
MotorL= map(lMotorSpeed, 0, 127, 0, 255);
MotorR= map(rMotorSpeed, -127, 0, 255, 0);

Try that.
You should make new variables MotorL and MotorR, you should not use the same variables names inside the map as the ones outside.

Plus, it is easier to debug the code.

I want to try again with a Parallax 2-Axis Joystick connected to another Arduino Uno board. Their values are from 0 to about 1000 with the middle at 514. The values on servos are from 0 to 180 with the middle at 90. Should the map command look like this:

value = map(value, 0, 1024, 0, 180);

How do I convert a value from char to int?

This is what I made to do just that, this gets in X,Y,Z and a state.

 void loop() {
   if( Serial.available())       // if data is available to read
   { 
    digitalWrite(ledpin, HIGH); //my way of knowing the robot is getting the data
    char val = Serial.read();
    if (val == ','){
      currentCommand++; 
    }
    else { 
      //Serial.println(val);
      switch (currentCommand) {
      case 0:
        X += val;
        val = "";
        break; 
      case 1:
        Y += val;
        val = "";
        break;
       case 2:
        Z += val;
        val = "";
        break;
      case 3:
      //Serial.println("X: "+X);    //see what is being stored on serial monitor
      //Serial.println("Y: "+Y);    //see what is being stored on serial monitor
      //Serial.println("Z: "+Z);    //see what is being stored on serial monitor
        state = val;                   // this last one ONLY gets 1 char, you need to modify this or take it out.
        currentCommand = 0;    // reset case statements back to zero
        val = "";                         // clears string
        //Serial.println("state: "+state);  //see what is being stored on serial monitor
        //Serial.println();
        x=X.toInt();               //this right here converts the string of character into an INT, .toINT()
        y=Y.toInt();               //this right here converts the string of character into an INT, .toINT()
        z=Z.toInt();               //this right here converts the string of character into an INT, .toINT()
        s=state.toInt();         //this right here converts the string of character into an INT, .toINT()
        X=""; Y=""; Z=""; state="";   // clears strings for new data
        //move( z, y, s);                  sends the int data to my wheels
        break;
      }
    } 
  }
}

I found code on http://bildr.org/2011/04/arduino-xbee-wireless/ that lets me adjust the brightness on a LED wirelessly. I tried to modify the code to let me control a servo wirelessly but the servo doesn't work properly. Continuous servo doesn't run continuously. Regular servo doesn't run the way that a regular servo should run. Any suggestions?

#include <SoftwareSerial.h>
#include <Servo.h>
#define potPin 3
#define ledPin 11
Servo servoLeft;
Servo servoRight;
char val1;
char val2;
int value1;
int value2;
int inByte = -1;
char inString[6];
int stringPos = 0;
int lastValue = 0;
const int xb_rx = 2;
const int xb_tx = 3;
SoftwareSerial Xbee(xb_rx,xb_tx);
void setup()  
{
  servoLeft.attach(10);       // Left servo to pin 10
  servoRight.attach(9);       // Right servo to pin 9
  servoLeft.write(90);
  servoRight.write(90);
  Serial.begin(9600);
  Xbee.begin(9600);
  pinMode(ledPin, OUTPUT);
} 
void loop() 
{
  inByte = Xbee.read();
  int potVal = analogRead(potPin);
  if( abs(potVal - lastValue) > 5)
  {
     Xbee.println(potVal);
     lastValue = potVal;
  }
  if((inByte >= '0') && (inByte <= '9'))
  {
    inString[stringPos] = inByte;
    stringPos ++;
  }
  if(inByte == '\r')
  {
    int value1 = atoi(inString);
    Serial.println(value1);
    value1 = map(value1, 0, 1023, 0, 180);
    analogWrite(ledPin, value1);
    servoLeft.write(value1);
    for (int c = 0; c < stringPos; c++)
    {
      inString[c] = 0;
    }
    stringPos = 0;
  }
}

What is it doing, what are you getting out on the serial monitor?

try something like this to make the servo rotate continuously.
Example:

myservo1.writeMicroseconds(N);

N<1500: usually backwards
N>1500: usually forwards
N=1500: usually stop

your values may need to be adjusted to suit your servo.

I still can't get the servos to work properly. When using continuous servos, they behave like regular servos and they run clockwise only. The regular servos run slightly back and forth jerkily. I think that the last few lines of code were affecting the servos.

Try this code in another sketch.

Simple servo test code you can try to see if the servos are ok.

// zoomkat 10-22-11 serial servo test
// type servo position 0 to 180 in serial monitor
// or for writeMicroseconds, use a value like 1500
// for IDE 0022 and later
// Powering a servo from the arduino usually *DOES NOT WORK*.

String readString;
#include <Servo.h> 
Servo myservo;  // create servo object to control a servo 

void setup() {
  Serial.begin(9600);
  myservo.writeMicroseconds(1500); //set initial servo position if desired
  myservo.attach(7);  //the pin for the servo control 
  Serial.println("servo-test-22-dual-input"); // so I can keep track of what is loaded
}

void loop() {
  while (Serial.available()) {
    char c = Serial.read();  //gets one byte from serial buffer
    readString += c; //makes the string readString
    delay(2);  //slow looping to allow buffer to fill with next character
  }

  if (readString.length() >0) {
    Serial.println(readString);  //so you can see the captured string 
    int n = readString.toInt();  //convert readString into a number

    // auto select appropriate value, copied from someone elses code.
    if(n >= 500)
    {
      Serial.print("writing Microseconds: ");
      Serial.println(n);
      myservo.writeMicroseconds(n);
    }
    else
    {   
      Serial.print("writing Angle: ");
      Serial.println(n);
      myservo.write(n);
    }

    readString=""; //empty for next input
  } 
}

I tried zoomkat's code and it worked. I tried to modify his code for wireless communication and it didn't work. I found out that the Println command adds carriage return and line feed characters to end of string being printed. Do I have to modify the code to look for these characters?

#include <SoftwareSerial.h>
#include <Servo.h> 
String readString;
Servo myservo;  // create servo object to control a servo
const int xb_rx = 2;
const int xb_tx = 3;
SoftwareSerial Xbee(xb_rx,xb_tx);
void setup() 
{
  Serial.begin(9600);
  Xbee.begin(9600);
  myservo.writeMicroseconds(1500); //set initial servo position if desired
  myservo.attach(9);  //the pin for the servo control 
  Serial.println("servo-test-22-dual-input"); // so I can keep track of what is loaded
}
void loop() 
{
  while (Xbee.available()) 
  {
    char c = Xbee.read();  //gets one byte from serial buffer
    Serial.println(c);
    readString += c; //makes the string readString
    delay(2);  //slow looping to allow buffer to fill with next character
  }
  if (readString.length() >0) 
  {
    Serial.println(readString);  //so you can see the captured string 
    int n = readString.toInt();  //convert readString into a number
    if(n >= 500)
    {
      Serial.print("writing Microseconds: ");
      Serial.println(n);
      myservo.writeMicroseconds(n);
    }
    else
    {   
      Serial.print("writing Angle: ");
      Serial.println(n);
      myservo.write(n);
    }
    readString=""; //empty for next input
  } 
}

What are you sending and what are you getting back, lets start there.

You have this, n = readString.toInt(); but you need to convert it AFTER you get everything
so right I think it is only getting 1 char then it goes to the IF/ELSE and then gets cleared. You don't give it time to get multiple chars.
you need a stop char for it to look for like ":" or ";" or "."

If the incoming char is anyone of these, then it know that you have everthing and it should then convert the string to an INT.

I have code that reads joystick input and sends it to another Arduino board.

#include <SoftwareSerial.h>
const byte PIN_ANALOG_X = 0;
const byte PIN_ANALOG_Y = 1;
int x_position;
int y_position;
int x_direction;
int y_direction;
const int xb_rx = 2;
const int xb_tx = 3;
SoftwareSerial Xbee(xb_rx,xb_tx);
void setup() 
{
  Serial.begin(9600);
  Xbee.begin(9600);
}
void loop () 
{

  x_direction = 0;
  y_direction = 0;
  x_position = analogRead(PIN_ANALOG_X);
  y_position = analogRead(PIN_ANALOG_Y);
  map(x_position,0,1024,0,180);
  Serial.println(x_position);
  Xbee.println(x_position);
}

Serial Monitor displays values properly. Should I try the code from http://arduino.cc/en/Tutorial/VirtualColorMixer ?

The controller puts out values 0 - 180?
OK, what are you getting on the other end?

Yea about the println, I found that out too, just do:

Serial.print(n);
Serial.println();

I found out that the Println command adds carriage return and line feed characters to end of string being printed. Do I have to modify the code to look for these characters?

I think the readString.toInt() will ignore trailing non neumeric characters. You may be transmitting faster than you are receiving, flooding the receiving buffer. Try a delay like below to slow the transmission to see if the receiving does better. If that works, then you could do some more tweeking.

  map(x_position,0,1024,0,180);
  delay(50);  //slow looping 
  Serial.println(x_position);
  Xbee.println(x_position);

The code for Processing won't work on Arduino. How can I convert the code so that it will work on Arduino?

void serialEvent(Serial myPort) 
{ 
  String inString = myPort.readStringUntil('\n');
  if (inString != null) 
  {
    inString = trim(inString);
    float[] colors = float(split(inString, ","));
    if (colors.length >=3) 
    {
      redValue = map(colors[0], 0, 1023, 0, 255);
      greenValue = map(colors[1], 0, 1023, 0, 255);
      blueValue = map(colors[2], 0, 1023, 0, 255);
    }
  }
}

I can't help you with processing, I don't like it and I try to stay away from it.
Sorry.

I wasn't sure what you wanted to do with Processing, but now I see. Arduino might be made from processing but it does not have the same functions as processing. One function in particular is Split(). Arduino does not have it, and that make things harder to break apart incoming strings. So what you(everyone in general) have to do is MAKE a split function using IF statements and Case statements.

This should do exactly what you want to do, get the incoming data, and convert it to an integer.

String inString;
int Data; 

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

void loop() {
   if( Serial.available() )       
   { 
    char val = Serial.read();

    if (val == '.'){  // looks for the period in the incoming data then prints it.
    Serial.print(inString);
    Serial.print(" :: ");  
    Serial.println(Data);
    inString = ""; 
    }
    else { 
      inString += val;    // stores the characters in a string
      Data=inString.toInt();    // converts the string into an integer          
          }
     }
 }

Not compiled but it should work.
Make sure when you send out the data, you include a period at the end, otherwise it will continue to add to the string and never print.

Also I gave you a simple Split function in a previous post, did you analyze it.