Friday, January 7, 2011

Arduino Takes Control (of RC Truck)

Recap: I'm entering the Sparkfun Autonomous Vehicle Competition (AVC) for 2011 (if they have it again), I bought an RC truck for the robot platform.  After playing with the truck a little, it was time to hand the controls over to an Arduino (aka ATmega328P on a breadboard)

This ElectrixRC stadium truck will soon become a robot...

How do you control an RC car with a microcontroller?  It's easy. The steering servo is controlled with servo pulses (surprising, no?) and so is the Electronic Speed Controller (ESC) aka throttle. The Arduino servo library makes coding a breeze.

Image from coastalplanes.com

Wiring is easy too.  The ESC and Servo both use standard 3-wire RC servo connectors.  The ESC has a 5V regulator (Battery Elimination Circuit or BEC). Wire the BEC's 5V and GND to power the Arduino, and wire the signal line to one of the digital pins. Then wire the steering servo's signal wire to another digital pin and connect the power and ground wires so the servo gets power.

After converting my Pololu SPI programmer to serial mode (Pokey and my FTDI programmer were on loan for the Thompson Robotics Expo) I modded some code and... voila:



Here's the code to control the car. Easy peasy. I used digital pins 9 and 10. Getting the range and center set correctly on the servo and throttle took quite a bit of trial and error.  You don't want to force the steering servo to full lock as that is hard on the servo.

// Steering/Throttle test - Michael Shimniok
// Based on Sweep by BARRAGAN  

#include <servo.h> 
 
// create servo object to control a servo 
// a maximum of eight servo objects can be created 
Servo steering;  
Servo throttle;

int ledPin = 13;
int pos = 0;    // variable to store the servo position 

#define CENTER 95
#define LEFT 55
#define RIGHT 130
 
void setup() 
{ 
  steering.attach(9);
  throttle.attach(10);  // attaches the servo on Arduino pin 10 
  
  steering.write(CENTER);
  throttle.write(90); // set mid throttle
} 
 
 
void loop() 
{
  throttle.write(85);
  digitalWrite(ledPin, HIGH);
  delay(250);
  throttle.write(90);
  digitalWrite(ledPin, LOW);
  delay(500);
  digitalWrite(ledPin, HIGH);
  delay(100);
  digitalWrite(ledPin, LOW);
  delay(100);
  sweep(CENTER, RIGHT, 1);
  sweep(RIGHT, CENTER, -1);
  sweep(CENTER, LEFT, -1);
  sweep(LEFT, CENTER, 1);
  digitalWrite(ledPin, HIGH);
  delay(100);
  digitalWrite(ledPin, LOW);
  delay(100);
}  

void sweep(unsigned char start, unsigned char stop, char inc)
{
  unsigned char pos;
  char i;

  for(pos = start; pos+inc != stop; pos += inc)
  { 
    steering.write(pos);             // tell servo to go to position in variable 'pos' 
    delay(15);                       // waits 15ms for the servo to reach the position 
  }
} 

That's one small step of progress with a massive, overwhelming list of things left to do. But hey, every journey, however long and arduous, starts with a single step, right?

No comments:

Post a Comment