Introduction: Car No.02 Steering Wheel Drive R/C Car With Arduino, Webcam and Net.USB Etc.

IP Control Car was launched in 2001.
I make the similar function car utilizing commercialized products.

The concept of Car No.02 is to utilize commercialized products, and I am an amateur in electrical. So, do not blame me that the system is not sophisticated, i.e. servo & speed controller control system and webcam system are not integrated, or 4 different types of batteries are used for R/C Car(7.2V), Arduino(5V), USB Device Server(12V) and Wireless Broadband Router(5V).

Step 1: Procurement

R/C Car
- Chassis Tamiya M-05Ra Chassis
- Body Tamiya 8085258 Mini Cooper Monte Carlo 94 Finished Body
- Geared Motor AO-8014 Tamiya Geared Motor 380K10 (gear ratio 10:1)
- Servo Futaba S3003
- Speed Controller Tamiya TEU-104BK
- Ni-Cd Battery 1500mAh 7.2V

Mounted devices on R/C Car
- Arduino Duemilanove
- Arduino ProtoShield Kit DEV-07914
- Bluetooth Modem BlueSMiRF
- 5V 500mA Battery eneloop mobile booster KBC-L3AS
- Webcam Microsoft LifeCam Show RLA-00007
- USB Device Server IO Data ETG-DS/US (net.USB)
- Wireless Broadband Router PLANEX MZK-MF300N
- 12V 1A Low Dropout Regulator LM2940CT-12 kit
- 5V 1A Low Dropout Regulator LM2940CT-5.0 kit
- AA battery x 20
- Battery Case (AAx10pcs) x 2
- Lubic, etc

Desktop PC side (OS is Windows XP.)
- Steering Wheel Logicool Driving Force GT LPRC-14000
- Bluetooth USB Adaptor Parani-UD100
- Wireless LAN USB Adapter GW-US300MiniS
- Wireless LAN Extender PLANEX MZK-EX300N-EZ

Software (to be downloaded and installed)
- Arduino
- Processing
- Jmyron (http://webcamxtra.sourceforge.net/)
- proCONTROLL (http://creativecomputing.cc/p5libs/procontroll/)

Step 2: Assembling 1

Assemble Tamiya M-05Ra Chassis in accordance with Assembly Manual. (http://www.tamiya.com/japan/download/rcmanual/m05ra.pdf)

The followings are different from the manual.

- Geared motor installation
  (if you do not want a low speed car, geared motor is not necessary. Assemble with 540 motor in accordance with the manual.)

  Modify A2 and B2 parts, and attach the geared motor with following parts;

Different diameter in-line collar 6mm x 4mm
Dia 4mm hollow shaft 10mm long
Dia 3mm shaft 19mm long
16T pinion gear
Adjuster 20mm long
Countersunk screw

  Skip Part 11 and 12 of Assembly Manual.


- Get the center value of servo and set up speed controller
  Instead of Part 19 of Assembly Manual (Checking R/C equipment), get the center value of servo and set up speed controller with connecting them to Arduino. Receiver is not required for this system.

  Upload the following Arduino code to Arduino.
Arduino code

/*
* Servo & Speed Controller
* Processing ---- SVSC_P
* Arduino Duemilanove ---- SVSC_A
*/

#include <Servo.h>
Servo servo;
Servo speedcontroller;
int val1;
int val2;
int val3;

int servoneutral = 63;
int speedcontrollerneutral = 63;

int steval = servoneutral;
int velval = speedcontrollerneutral;
int reversea = 'F';
boolean reverseb = false;

void setup() {
  Serial.begin(115200);
  servo.attach(9);
  speedcontroller.attach(10);
}

void loop() {
  if(Serial.available()>2){
    val1 = Serial.read();
    val2 = Serial.read();
    val3 = Serial.read();
    Serial.print(65,BYTE);
  }

  if(val1>=128 && val2<128 && (val3=='F'||val3=='R') ){
    steval = val1 - 128;
    velval = val2;
    reversea = val3;
  }else if(val1<128 && (val2=='F'||val2=='R') && val3>=128){
    steval = val3 - 128;
    velval = val1;
    reversea = val2;
  }else if((val1=='F'||val1=='R') && val2>=128 && val3<128){
    steval = val2 - 128;
    velval = val3;
    reversea = val1;
  }

  servo.write(steval);

  if(reversea=='R' && reverseb==false){
    for (int i=1; i <= 5; i++){
      speedcontroller.write(speedcontrollerneutral);
      delay(15);
    }
    reverseb = true;
    speedcontroller.write(velval);
  }else if(reversea=='F'){
    reverseb = false;
    speedcontroller.write(velval);
  }else {
    speedcontroller.write(velval);
  }
}

  Connect servo and speed controller to Arduino.
  (Servo --> D9, 5V, GND Speed Controller --> D10, 5V, GND)

  Run the following Processing code.
Processing code

/*
* Servo & Speed Controller
* Processing ---- SVSC_P
* Arduino Duemilanove ---- SVSC_A
*/

import processing.serial.*;

Serial port01;
int x;
int y;
int steval = 63;
int velval = 63;
int reversea = 'F';

void setup(){
  size(127,127);
  stroke(128);
  port01 = new Serial(this,"COM18",115200); //COM No. varies by each PC.
  port01.clear();
}

void draw(){
  background(51);
  line(x, 0, x, height);
  line(0, height-y, width, height-y);
}

void serialEvent(Serial p){
  steval = 127 - x;
  velval = y;

  if(velval>=63){reversea='F';} else{reversea='R';}
  if(p.available()>0){
    port01.write(steval+128);
    port01.write(velval);
    port01.write(reversea);
    print(steval);print(",");print(velval);print(",");println(char(reversea));
  }
}

void keyPressed(){
  if(key=='s'){
    x = 63;
    y = 63;
    steval = 127 - x;
    velval = y;
    port01.write(steval+128);
    port01.write(velval);
    port01.write(reversea);
  }
  else if(keyCode == RIGHT){
    x += 1;
    if(x > 127){x = 127;}
  }
  else if(keyCode == LEFT){
    x -= 1;
    if(x < 0){x = 0;}
  }
  else if(keyCode == UP){
    y += 1;
    if(y > 127){y = 127;}
  }
  else if(keyCode == DOWN){
    y -= 1;
    if(y < 0){y = 0;}
  }
}

  Once the display window appears, press ‘s’ key to start serial communication.

  ‘Right’ and ‘left’ arrow keys relate to servo (steering) and ‘up’ and ‘down’ ones relate to speed controller (forward, backward and speed).

  Make the first figure 64 in the Processing lower black screen by pressing ‘s’ key.

  Attach a servo arm as much as central. After attaching the servo arm, get the center value of servo. (Press ‘right ‘and/or ‘left’ arrow keys, make the servo arm center, then read the first figure.)

  Set up speed controller in accordance with the speed controller setup manual.
  (Press ‘s’ key, then the second value becomes 63 as neutral. Press ‘up’ arrow key continuously, then the second value becomes 127 as forward max. Press ‘down’ arrow key continuously, then the second value becomes 0 as backward max.)

  Disconnect the servo and the speed controller from Arduino.


- Longer Servo Shaft (Part 20 of Assembly Manual)
  Battery boxes and regulators for USB device server and wireless broadband rooter will be mounted above the servo. Ball connector (BA23) is attached to the opposite side of servo arm and the servo shaft becomes longer. The original shaft length is 89mm and I made 93mm one.

- Receiver is not required for this system. (Part 21 of Assembly Manual)

- Skip Part 23, 24 and 25 of assembling manual.

- Tire size (Part 26 of Assembly Manual)
  Instead of 60mm diameter tires, I use 55mm diameter tires.

- Antenna pipe is not needed. (Part 30 of Assembly Manual)

- Body
  Make holes and attach Lubic mount.

Step 3: Assembling 2

- Solder, assemble and mount 12V 1A and 5V 1A power supplies for USB device server and wireless broadband router respectively.
  Solder the following parts, assemble, and mount on R/C car chassis with double-faced adhesive tape and hook & loop fastener.
Parts

Board
Low dropout regulator kits (12V 1A and 5V 1A)
Resistance
LED
Switch
Terminal
Heat Sink

- Set up wireless broadband router. (Refer to the set up manual. Changeover switch shall be ‘AP’.)

- Attach wireless broadband router, USB device server and eneloop battery on acrylic plate with double-faced adhesive tape, attach   duino+ProtoShield+Bluetooth Modem on USB device server also with double-faced adhesive tape, and fix the acrylic plate on Lubic mount.

- Attach webcam in front window of R/C car.
  (Webcamera is attached upside down. In Processing code, upside down is adjusted.)

- Wiring/Connect
  Connect servo and speed controller to Arduino.
  (Servo --> D9, 5V, GND Speed Controller --> D10, 5V, GND)
  Connect eneloop battery to Arduino.
  Connect webcam usb connector to USB device server.
  Connect USB device server and wireless broadband router with LAN cable.
  Set battery cases with batteries and connect to 12V 1A and 5V 1A power supplies.
  Connect 12V 1A power supply to USB device server with DC plug (outer diameter 5.5mm, inner diameter 2.5mm)
  Connect 5V 1A power supply to wireless broadband router with DC plug (outer diameter 3.4mm, inner diameter 1.3mm)

Step 4: PC Side Setup

- Install driver and connect Steering Wheel.

- Install driver and connect Bluetooth USB Adaptor.

- Install driver and connect Wireless LAN USB Adapter.

Step 5: Code

- Arduino code is same as Step 2.

- Download Jmyron and proCONTROLL, and install them.

- The following is the processing code.
  Adjust servoneutral value and COM No.
  Adjust xa calculating formula in void serialEvent() and void keyPressed(). (Adjust 33 and 99. 33 is max steering to right and 99 is that to left.)

xa = (33-99)/(camWidth_*k_)*x+99; // 0-->99, camWidth_/2*k-->66, camWidth_*k-->33
(camWidth_/2*k = 352/2*2 = 352, camWidth_*k = 352*2 = 704, These 0, 353, 704 are x coordinate in the display window.)

Processing code

/*
* Car No.02
* Servo, Speed Controller, Driving Force GT & Webcam
* Processing ---- CARNO02
* Arduino Duemilanove ---- SVSC_A
*/

import processing.serial.*;
import procontroll.*;
import net.java.games.input.*;
import JMyron.*;

Serial port01;

ControllIO controll;
ControllDevice device;
ControllSlider slider0;
ControllSlider slider2;
ControllSlider slider3;
ControllButton button1;
ControllButton button13;
ControllButton button14;

JMyron cam;

//Microsoft LifeCam Show RLA-00007
float camWidth_ = 352;
float camHeight_ = 288;
int camWidth = int(camWidth_);
int camHeight = int(camHeight_);

float k_ = 2;
int k = int(k_);
float k1 = camWidth_/127 * k;
float k2 = camHeight_/127 * k;
float x;
float y;
float xa;
float ya;
int forward = 0;
int servoneutral = 66; //Servoneutral value varies by each servo.
int speedcontrollerneutral = 63;
int steval = servoneutral;
int velval = speedcontrollerneutral;
int reversea = 'F';
boolean reverseb = false;

void setup(){
  size(camWidth*k,camHeight*k);
  stroke(128);
  port01 = new Serial(this,"COM43",115200); //COM No. varies by each PC.
  port01.clear();

  controll = ControllIO.getInstance(this);
  device = controll.getDevice("Logitech Driving Force GT USB"); //Refer to Device Manager. Logitech might be Logicool.
  // device.printSliders();
  // device.printButtons();
  device.setTolerance(0.05f);

  slider0 = device.getSlider(0); //Steering Wheel
  slider2 = device.getSlider(2); //Break Pedal
  slider3 = device.getSlider(3); //Accelerator Pedal
  button1 = device.getButton(1); //Cross button
  button13 = device.getButton(13); //Gear Shift Lever Pull
  button14 = device.getButton(14); //Gear Shift Lever Push

  fill(0);
  rectMode(CENTER);

  cam = new JMyron();
  cam.start(camWidth,camHeight);
  cam.findGlobs(0);
}

void draw(){
  cam.update();
  int[] camPixels = cam.image();
  loadPixels();
  for(int i2 = 0 ; i2 < height ; i2++) {
    for(int i1 = 0 ; i1 < width ; i1++) {
      pixels[i2 * width + i1] = camPixels[floor((height-1-i2)/k)*camWidth + floor((width-1-i1)/k)];
    }
  }
  updatePixels();

  x = (constrain((1+slider0.getValue())*width/2,0,width));

  if(button1.pressed()){forward = 0; y = height/2; reversea = 'F'; reverseb = true;}
  if(button13.pressed()){forward = 1; y = height/2; reversea = 'F'; reverseb = true;}
  if(button14.pressed()){forward = -1; y = height/2; reversea = 'R'; reverseb = false;}

  if(forward ==1){
    if(slider2.getValue()<0){y = constrain(y + slider2.getValue()*8*k,height/2,height);}
    if(slider3.getValue()<0){y = constrain(y - slider3.getValue()*4*k,height/2,height);}
    if(slider2.getValue()>0&&slider3.getValue()>0&&y<height*2/3){
      y = (constrain(y + slider2.getValue()*0.6*k,height/2,height*2/3));
    }else if(slider2.getValue()>0&&slider3.getValue()>0&&y>height*2/3){
      y = (constrain(y - slider3.getValue()*0.3*k,height*2/3,height));
    }
  }

  if(forward == -1){
    if(slider2.getValue()<0){y = constrain(y - slider2.getValue()*8*k,0,height/2);}
    if(slider3.getValue()<0){y = constrain(y + slider3.getValue()*4*k,0,height/2);}

    if(y<=height*5/12 && reverseb==false){y = height/2; reverseb = true;}

    if(slider2.getValue()>0&&slider3.getValue()>0&&y>height*1/3){
      y = (constrain(y - slider2.getValue()*0.6*k,height*1/3,height/2));
    }else if(slider2.getValue()>0&&slider3.getValue()>0&&y<height*1/3){
      y = (constrain(y + slider3.getValue()*0.3*k,0,height*1/3));
    }
  }

  line(x, 0, x, height);
  line(0, height-y, width, height-y);
}

void serialEvent(Serial p){
  xa = (33-99)/(camWidth_*k_)*x+99; // 0-->99, 352/2*k-->66, 352*k-->33
  steval = int(xa);
  velval = int(y/k2);

  if(p.available()>0){
    port01.write(steval+128);
    port01.write(velval);
    port01.write(reversea);
    print(steval);print(",");print(velval);print(",");println(char(reversea));
  }
}

void keyPressed(){
  if(key=='s'){
    forward = 0;
    x = width/2;
    y = height/2;
    xa = (33-99)/(camWidth_*k_)*x+99;
    steval = int(xa);
    velval = int(y/k2);
    port01.write(steval+128);
    port01.write(velval);
    port01.write(reversea);
  }
}

Step 6: Let's Drive!

R/C Car side
- Switch on 12V and 5V power supplies, attach Car Body to body mounts and fix it by snap pins, and switch on R/C Car(7.2V) and eneloop(5V).

PC side
- Establish Bluetooth connection.

- Establish Wireless LAN connction.

- And await for net USB connection. (It sometimes takes more than 10 minutes!)

- After these connections are established, run the Processing code.

  Once video capture appears, press ‘s’ key to start serial communication.
  Vertical and horizontal lines are indicated on the video captured screen.

  Pull the gear shift lever for forward and push it for backward.
  Break pedal for break and accelerator pedal for accelerator.

  The break is set weak. If you want sharp break, adjust the figure in the processing code.

if(slider2.getValue()<0){y = constrain(y + slider2.getValue()*8*k,height/2,height);}

if(slider2.getValue()<0){y = constrain(y - slider2.getValue()*8*k,0,height/2);}

  Press X button on the wheel steering for emergency stop.


Step 7: Reference, Notes and Trailer

Reference:

http://kousaku-kousaku.blogspot.com/2008/06/processing-arduino.html
http://kousaku-kousaku.blogspot.com/2008/06/arduino.html
http://kousaku-kousaku.blogspot.com/2008/10/arduino-processingbluetooth.html




Notes:

Since the speed controller Tamiya TEU-104BK does not function well for the change from forward to backward, I elaborated the Processing code for that change, but it takes several seconds to start backwarding after setting the shift lever backward.

Logicool Webcam series are not recognized in net.USB.




Problems yet solved:(Yo Dareka Oshietekure!)

Net USB connection for Webcam takes so much time. Dose anyone know how to establish net.USB connection for Webcam quickly.




Trailer for Car No.03

Car No.03 is Crawler type!