Pages

Sunday, June 5, 2011

Robot schematic and Arduino sketch

Last week I posted some pictures of a robot I've started building, at the moment it's really just a remote controlled car. I've put together a schematic showing the various pin connections. I use an Arduino Uno, an XBee radio, and an L293D motor driver chip, as well as two motors (mine are 9v).

Blue and red obviously represent power and ground lines, green connections represent digital or PWM signals from and to the Arduino, and the magenta lines are PWMs from the L293D, I chose a different color because they will run at a higher voltage than the Arduino PWMs, and they power the motors.

On the Arduino, I'm running the following sketch:


char index;
char serialbuff[7];
char ch;
int x=0;
int lSpeed;
int rSpeed;

int LMOTOR_DIR = 12; // Non PWM pin for direction control
int LMOTOR_PWM = 11; // PWM controlled pin.
int RMOTOR_DIR = 7;
int RMOTOR_PWM = 6;


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

// Set the pins to output.
pinMode(LMOTOR_DIR, OUTPUT);
pinMode(LMOTOR_PWM, OUTPUT);
pinMode(RMOTOR_DIR, OUTPUT);
pinMode(RMOTOR_PWM, OUTPUT);
// And set these to a initial value to make sure.
digitalWrite(LMOTOR_DIR, LOW);
digitalWrite(LMOTOR_PWM, LOW);
digitalWrite(RMOTOR_DIR, LOW);
digitalWrite(RMOTOR_PWM, LOW);
}

void loop() {
switch(x){
case 0:{
ch=(char)Serial.read();
if(ch=='s'){
x=1;
serialbuff[0]=ch;
index=1;
}
}
break;

case 1:{
ch=(char)Serial.read();
if(ch!=-1){
serialbuff[index]=ch;
index++;
if(index==7){
x=2;
}
}
}
break;

case 2:{
if(serialbuff[6]=='e'){
x=3;
}
else{
x=4;
}
}
break;

case 3:{
if(serialbuff[1]=='+'){
digitalWrite(LMOTOR_DIR, HIGH);
lSpeed = 255-serialbuff[2];
}
else{
digitalWrite(LMOTOR_DIR, LOW);
lSpeed = serialbuff[2];
}

if(serialbuff[3]=='+'){
digitalWrite(RMOTOR_DIR, HIGH);
rSpeed = 255-serialbuff[4];
}
else{
digitalWrite(RMOTOR_DIR, LOW);
rSpeed = serialbuff[4];
}

analogWrite(LMOTOR_PWM, lSpeed);
analogWrite(RMOTOR_PWM, rSpeed);

x=4;
}
break;

case 4:{
index=0;
x=0;
}
break;
}
}


As you can see, the Arduino will read its serial port (the XBee) for the character "s", which will indicate the start of a control packet. once it's found this, it reads the next characters, these will make up the rest of the packet:
  • serialbuff[1] is either "+" or "-", indicating the direction of the left motor.
  • serialbuff[2] is the speed of the left motor and can be between 0 and 255
  • serialbuff[3] and [4] are the same as [1] and [2], but for the right motor
  • serialbuff[5] will eventually act as a checksum, though I haven't implemented this properly yet
  • serialbuff[6] must be "e" to indicate the end of a packet, otherwise the packet is discarded and loop restarts
You can see from this that the direction and speed of both motors can be completely controlled remotely, which gives us more opportunities as to how to steer the robot. For instance, instead of just using arrow buttons of the computer keyboard, one could write a script that converts accelerometer data (e.g. from a phone) into the appropriate motor speeds, allowing the robot to effectively be controlled through a phone.

Next up: the PC side script that sends packets to the robot.

No comments: