NXT Motor Shield

Part 2:
Demonstration
The first demonstration shows the robot controlled by my Apple Remote using Ken Shirriff's excellent IR library (A Multi-Protocol Infrared Remote Library for the Arduino):

The code look like this:

#include <IRremote.h>

const long iup = 0x77E1D0BE;
const long idown = 0x77E1B0BE;
const long iright = 0x77E1E0BE;
const long ileft = 0x77E110BE;
const long icenter = 0x77E1BABE;
const long imenu = 0x77E140BE;
const long iplay = 0x77E17ABE;
const long irepeat = 0xFFFFFFFF;

int RECV_PIN = 9;
IRrecv irrecv(RECV_PIN);
decode_results results;

//Right motor
#define logicright1 8
#define logicright2 10
#define pwm1 11
//Left motor
#define logicleft1 7
#define logicleft2 12
#define pwm2 6

int left = 0;
int right = 1;
int backward = 0;
int forward = 1;

int pwm;
int logic1;
int logic2;

int count = 0;

void setup(){
  irrecv.enableIRIn(); // Start the receiver

  pinMode(pwm1, OUTPUT);
  pinMode(logicleft1, OUTPUT);
  pinMode(logicleft2, OUTPUT);

  pinMode(pwm2, OUTPUT);
  pinMode(logicright1, OUTPUT);
  pinMode(logicright2, OUTPUT);
}

void loop(){
  if(irrecv.decode(&results)){
    count = 0;
    //Serial.println(results.value, HEX);
    switch(results.value){
    case iup:
      move(left,forward,100); 
      move(right,forward,100);
      break;
    case idown:
      move(left,backward,100); 
      move(right,backward,100);
      break;
    case iright:
      move(left,forward,100); 
      stop(0);
      break;
    case ileft:
      move(right,forward,100); 
      stop(1);
      break;
    case icenter:
      break;
    case imenu:
      break;
    case iplay:
      break;
    case irepeat:
      break;
    }
    delay(10);
    irrecv.resume(); // Receive the next value
  }
  else{
    count++;
    delay(1);
    if(count == 100){
      stop(0); 
      stop(1);
    }
  }
}
void move(int motor, int way, int power){
  if(motor == 1){//right
    pwm = pwm1;
    logic1 = logicleft1;
    logic2 = logicleft2;
  }
  if(motor == 0){//left
    pwm = pwm2;
    logic1 = logicright1;
    logic2 = logicright2;
  }
  power = map(power,0,100,0,255);
  analogWrite(pwm, power);
  if(way == 0){//backward
    digitalWrite(logic1, LOW);
    digitalWrite(logic2, HIGH);
  }
  if(way == 1){//forward
    digitalWrite(logic1, HIGH);
    digitalWrite(logic2, LOW);
  }
}
void stop(int motor){
  if(motor == 0){//left
    digitalWrite(pwm1, HIGH);
    digitalWrite(logicleft1, HIGH);
    digitalWrite(logicleft2, HIGH);
  }
  if(motor == 1){//right
    digitalWrite(pwm2, HIGH);
    digitalWrite(logicright1, HIGH);
    digitalWrite(logicright2, HIGH);
  }
}

The next example is a bit mote complicated. It is controlled by a PS3 controller connected to Processing http://processing.org/ via Bluetooth. It then sends serial data through a XBee (http://search.digikey.com/scripts/DkSearch/dksus.dll?Detail&name=XB24-ACI-001-ND) to the Arduino:

The arduino code:

//Right motor
#define logicright1 8
#define logicright2 10
#define pwm1 11
//Left motor
#define logicleft1 7
#define logicleft2 12
#define pwm2 6

int pwm;
int logic1;
int logic2;

int buffer[2];

void setup(){
  pinMode(pwm1, OUTPUT);
  pinMode(logicleft1, OUTPUT);
  pinMode(logicleft2, OUTPUT);

  pinMode(pwm2, OUTPUT);
  pinMode(logicright1, OUTPUT);
  pinMode(logicright2, OUTPUT);
  
  Serial.begin(9600);
}

void loop(){
  if(Serial.available()>1){
    for(int i=0;i<2;i++){
      buffer[i] = Serial.read()-48;
    }
    if(buffer[1] == 0){
      stop(buffer[0]);
    }
    else{
      move(buffer[0], buffer[1], 100);
    }
  }  
}

void move(int motor, int way, int power){
  if(motor == 0){//right
    pwm = pwm1;
    logic1 = logicleft1;
    logic2 = logicleft2;
  }
  if(motor == 1){//left
    pwm = pwm2;
    logic1 = logicright1;
    logic2 = logicright2;
  }
  power = map(power,0,100,0,255);
  analogWrite(pwm, power);
  if(way == 1){//backward
    digitalWrite(logic1, LOW);
    digitalWrite(logic2, HIGH);
  }
  if(way == 2){//forward
    digitalWrite(logic1, HIGH);
    digitalWrite(logic2, LOW);
  }
}
void stop(int motor){
  if(motor == 0){//right
    digitalWrite(pwm1, HIGH);
    digitalWrite(logicleft1, HIGH);
    digitalWrite(logicleft2, HIGH);
  }
  if(motor == 1){//left
    digitalWrite(pwm2, HIGH);
    digitalWrite(logicright1, HIGH);
    digitalWrite(logicright2, HIGH);
  }
}

I have uploaded the processing code as a .zip file - see the bottom of this post.

Sources:
All information can be found in: "LEGO MINDSTORMS NXT Hardware Developer Kit" (http://mindstorms.lego.com/en-us/support/files/default.aspx)

To do:

Update
I have made a second version of the shield. Which supports the Ultrasonic sensor and have custom RJ12 female sockets. See my blog for more information: TKJ Electronics » NXT Shield Version 2

Motorshield_processing.zip (820 KB)