Controlling an RC car via XBOX controller

Good morning everyone,

I am new to Arduino and have a question about the serial communication with the Arduino. I have looked at quite a few examples and forums, but I am having some trouble understanding. I am still testing, using the Arduino and Motor Shield to control two DC motors via Serial Monitor to send commands. My question is, is there any way in which I can send commands to the Arduino without having to open the Serial Monitor and press "Enter" when I want to send data? I want to be able to just press the "f" key and have my car move forward, rather than having to send one command at a time, pressing "Enter" for each command.

I hope I have been as clear as possible. I'll post my code along with this question.

Parts I currently am using for this project:
-New Bright RC Car (Ford Mustang GT)
-Arduino Uno BT
-Arduino Motor Shield R3
-Laptop (OS Windows 7)
-XBOX 360 Controller

Serial_Motor_Control_Test_1.txt (1.29 KB)

My question is, is there any way in which I can send commands to the Arduino without having to open the Serial Monitor and press "Enter" when I want to send data? I want to be able to just press the "f" key and have my car move forward, rather than having to send one command at a time, pressing "Enter" for each command.

Using the serial monitor, no. Writing your own application that sends data to the serial port is easy, though. Make it send data when a key is pressed, and again when the key is released. That way, your car can go forward while the f key is pressed, and stop when it is released. Or, just send when the key is pressed, and have another key (or any subsequent key) for "stop doing that".

So would I have to find a source outside of the Arduino IDE? (Create my own application) If so, any recommendations?
Also, is there any example code on the tutorials page?

By the way, thank you for the quick response, much appreciated.

My suggestion would be to use a Processing sketch to program the computer side of things. The Arduino IDE is actually based on Processing if I'm not mistaken. Take a look at the book "Making Things Talk" as it has several good examples of setting up serial communications with the Arduino.

Your question seems a bit confusing, but there are a few ways you can input data to the Arduino without using the Serial Monitor:

  1. Set up your own External buttons to use as controls: http://arduino.cc/it/Tutorial/Button

  2. As previously suggested, use Processing to capture keyboard events and send them or other data over a serial connection like so:

import processing.serial.*;       //use the Serial library
Serial myPort;                    // Create object from Serial class   

void setup() { 
  size(200, 200);                                  //set window size to 200 by 200 pixels
  String portName = Serial.list()[0];              //list serial ports, save the first one as portName
  myPort = new Serial(this, portName, 9600);       //initialize the serial port object
}

void draw() {                    //this is like the 'loop' section of code on Arduino
  background(255);           // set background color
  if(keyPressed) {                                                                                            //if a key is pressed, do the following
    if (  key == 'f' || key == 'F'  ){  myPort.write(key);  println(key);  delay(200);   }   // if the key is f or F, write it to the serial port, then wait 200 miliseconds
  }
}
  1. Embed an Arduino Nano or comparablly small device in the Xbox controller to monitor joystick/button actions and send the data to the device directly, or via an RF (Radio) module. example: TMRh20s Project Blog: March 2012

Update: Added comments to code per request by OP

Just wanted to say thanks for all the advice. I'll post some updates as soon as possible. Maybe along with some photos.

Also, TMRh20 could you please explain your code?

It is code for processing. Download Processing / Processing.org

I added some comments to the processing code above too.

HAHA! Wow guys thanks soo much! Much appreciated. Works perfectly with my code, so now I asm going to use the keyboard to control two (2) DC motors (both direction and speed). Then I will move onto the XBOX code.

I am a little intimidated to use the XBOX controller but I have found some individuals who have done a similar project before. But thanks once again for all the help! XD

I will keep updating everyone on my progress. Pics should be coming soon once my internship is up. :slight_smile:

Hey everyone,

Just an update, so far so good! The RC Car is moving Forward/Backward/Left/Right! However, I do have one question, is there an easier way for me to have the Processing and/or Arduino receive multiple I/O's? respectively. Right now, I plan on creating "if" statements for those cases.

ex: Processing Code: Arduino Code:

char upRight = 'E' if(input == 'E'){
if(keyCode == UP && keyCode == RIGHT){ analogWrite(pwmA, 255); analogWrite(pwmB, 255);
myPort.write(upRight) digitalWrite(dirA, LOW); digitalWrite(dirB, HIGH);
} }

Open to any suggestions, just want my code to be "better", so to speak. I feel this is a crude way of doing this control. Also, I want to be able to make sure that while I am driving forward, I can press on the right arrow key and it will read the two inputs (both up and right arrow key) as soon as I press it. Let me know if this is not concise.

However, I do have one question, is there an easier way for me to have the Processing and/or Arduino receive multiple I/O's?

Easier than what?

Also, I want to be able to make sure that while I am driving forward, I can press on the right arrow key and it will read the two inputs (both up and right arrow key) as soon as I press it.

You won't be able to use delay() anywhere. Not that you should want to, or should be doing so...

Why would you need to have two inputs? The Processing application can see that forward and right are pressed, and send some different value. It might send 0 for forward, 1 for forward, right, 2 for right, 3 for reverse, right, 4 for reverse, etc.

Easier than the code I had posted with my question. But I will be removing the delay() from my code (not necessary). And thanks for the quick response Paul, that's just what I needed answered!

Ok, so I was able to get it to work with the arrow keys, however, I changed my code in order to process 'Letter Keys' rather than the "Arrow Keys", my Arduino Code looks fine, but I will send both the Arduino Code and the Processing Code for any input. Please do let me know of dumb mistakes.

Arduino_Motor_Control_Final.txt (3.16 KB)

Processing_Controller_Final_Rev1.txt (2.17 KB)

Hi. I know this topic is old but since I'm pretty much working on the exact same thing, I didn't to start a whole new post and cover ground this topic has already covered.
Ok, I'm working on being able to control an rc car using an arduino mega 2560 using my computer. I'm using an adafruit motor control shield V1. I have managed to get processing to control the car to move forward, but when I release the 'F' key the motor continues to run forward rather then stop like I would like it to.
Here's my Arduino IDE code:

#include <AFMotor.h>

// Select which 'port' M1, M2, M3 or M4. In this case, M4
AF_DCMotor ThrottleMotor(4);
// You can also make another motor on port M1
AF_DCMotor SteeringMotor(1);

const int ledPin = 13; // the pin that the LED is attached to
int incomingByte;      // a variable to read incoming serial data into

void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("Adafruit Motorshield v1 - DC Motor test!");

  //AFMS.begin();  // create with the default frequency 1.6KHz
  //AFMS.begin(1000);  // OR with a different frequency, say 1KHz

  // Set the speed to start, from 0 (off) to 255 (max speed)
  ThrottleMotor.setSpeed(150);
  ThrottleMotor.run(FORWARD);
  // turn on motor
  ThrottleMotor.run(RELEASE);

  //OTHER MOTOR
  SteeringMotor.setSpeed(150);
  SteeringMotor.run(FORWARD);
  // turn on motor
  SteeringMotor.run(RELEASE);

}

void loop() {
  uint8_t i;

  // see if there's incoming serial data:
  if (Serial.available() > 0) {
    // read the oldest byte in the serial buffer:
    incomingByte = Serial.read();
    // if it's a capital H (ASCII 72), turn on the LED:
    if (incomingByte == 'F' || incomingByte == 'f') {
      ThrottleMotor.run(FORWARD);
      ThrottleMotor.setSpeed(100); 
    }
    if (incomingByte == 'L' || incomingByte == 'l') {
      SteeringMotor.run(FORWARD);
      SteeringMotor.setSpeed(100);
      delay(1000);
      SteeringMotor.setSpeed(130);
      delay(1000);
      SteeringMotor.setSpeed(140);
      delay(2000);
      SteeringMotor.setSpeed(160);
      delay(2000);   
    }
    if (incomingByte == 'R' || incomingByte == 'r') {
      SteeringMotor.run(BACKWARD);
      SteeringMotor.setSpeed(225);
    }
    if (incomingByte == 'C' || incomingByte == 'c') {
      SteeringMotor.run(RELEASE);
    }
    // if it's an L (ASCII 76) turn off the LED:
    if (incomingByte == 'B' || incomingByte == 'b') {
      ThrottleMotor.run(BACKWARD);
      for (i=0; i<255; i++) {
        ThrottleMotor.setSpeed(i);  
        delay(10);
      }
    }
    // 
    if (incomingByte == 'S' || incomingByte == 's') {
      ThrottleMotor.run(RELEASE);
      SteeringMotor.run(RELEASE);
    }
  }    
}

Processing Code:

import processing.serial.*;   
      
//use the Serial library

Serial myPort;                      
//Create object from Serial class  



int  standBy = 0; 




void setup() { 
  
size(200, 200);                                  //set window size
  
String portName = Serial.list()[0];              //list serial ports
  
myPort = new Serial(this, portName, 9600);       //initialize the serial port object

}




void draw() {                   //this is like the 'loop' section of code on Arduino
  
background(255);                   

}



void keyPressed() { 

                                
//if the key is "F"
    
if (  key == 'F' ){      
//Forward Movement
  
myPort.write(key);  
  
println("Forward");     
    
}

                
//if the key is "X"
    
if (  key == 'X' ){      
//Reverse Movement
  
myPort.write(key);  
  
println("Reverse");     
    
}

                
//if the key is "Q"
    
if (  key == 'Q' ){      
//Forward Left Turn
  
myPort.write(key);  
  
println("Forward Left turn");     
 
} 

                
//if the key is "E"
    
if (  key == 'E' ){      
//Forward Right Turn
  
myPort.write(key); 
  
println("Forward Right Turn");     
    
}
 
                               
//if the key is "Z"
    
if (  key == 'Z' ){      
//Backward Left Turn
  
myPort.write(key); 
  
println("Backward Left Turn");     
    
}

                                
//if the key is "C"
    
if (  key == 'C' ){      
//Backward Right Turn
  
myPort.write(key); 
  
println("Backward Right Turn");     
    
}
  
}
  


void keyReleased() {


    
if (  key == 'F' ){
    
myPort.write(standBy);
  
println("RC Car is on stand-by.");
    
}

 
   
if (  key == 'X' ){
    
myPort.write(standBy);
  
println("RC Car is on stand-by.");
    
}
    
if (  key == 'Q' ){
    
myPort.write(standBy);
  
println("RC Car is on stand-by.");
    
}

 
   
if (  key == 'E' ){
    
myPort.write(standBy);
  
println("RC Car is on stand-by.");
    
}
    
    
if (  key == 'Z' ){
    
myPort.write(standBy);
  
println("RC Car is on stand-by.");
    
}
 
   
    
if (  key == 'C' ){
    
myPort.write(standBy);
  
println("RC Car is on stand-by.");
    
}
 
 
}

NOTE: I was only working on getting the forward function to work first, then I'll rework all the other movements. I basically want to be able to press the 'f' key to go forward and when I release it, I want the forward motion to stop.

Also, my future plan is to attach a camera to the car and be able to control the car from my computer using a wired usb xbox 360 controller. So if anyone has any info or suggestions for me on this, that would be great. I also intend to connect the arduino to a raspberry pi that I have already set up to be wireless and controlled using my laptop. The arduino would be controlling the motors of the vehicle, while the pi will eventually control sensors. But, first thing is first, can someone please help me control car how I described above. If you need any clarification, please ask. Thanks.