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:
- Make a new version with custom RJ12 female sockets from Mindsensors (http://mindsensors.com/index.php?module=pagemaster&PAGE_user_op=view_page&PAGE_id=139&MMN_position=50:50)
- Make the Ultrasonic Sensor work as well. My plan is to add two sensor input to the shield. Right now I am struggling to get the Ultrasonic sensor work. If anyone have some ideas or experience with it please visit my post here on the Arduino forum: Mindstorms Ultrasonic Sensor Help - Solved!! - Sensors - Arduino Forum
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)