Table of Contents
Wi-Fi Car
The Wi-Fi Car is an open source robotic device controlled by a terminal, such as a smartphone, PC, or tablet. It provides a video stream of what the car sees through its camera.
The project combines what we have learned about OpenWrt routers, Arduino, remote control, MJPG streaming and HTML.
The car was featured in a report by Global Times on May 31, 2012 ("The Robot Cookbook").
Media
If you are interested our Wi-Fi Car and want make your own, watch the videos in this Youku playlist (instructions in Chinese).
-
Part 1: Making the Body
-
Part 2: Installing the DFRduino RoMeo (requires Arduino IDE
-
Part 3: Communicating with the Arduino (requires this code)
-
Part 4: Controlling the Wi-Fi Car via Amarino (required this code)
-
Part 5: About the Android App
-
Part 6: Making the Android App Control the Wi-Fi Car
-
Part 7: About OpenWrt
Hardware
There are a few current versions of the hardware:
Mini Wi-Fi Car
-
Chasis
-
DFRduino
-
Battery
-
TP-Link WR703N
-
A camera (most cheap webcams will do)
-
Wire
Normal Wi-Fi Car
-
Chasis or Rover 5 Tank
-
Romeo (or Motor Shield and DFRduino)
-
TP-Link WR703N
-
Camera
-
Wire
-
USB hub
This version connects the Arduino via USB instead of direct serial. You will need two batteries, or a more powerful battery. Its difficulty is mainly because of this.
Software
We have built our own OpenWrt image to flash on the router, with drivers and some required tools. It's ready to use and easy to install. Just update the firmware on your router from the menu and select our custom build.
WARNING: This will void your warranty! Make sure you want to do that before you proceed. This is a testing build. If something goes wrong, its your own problem.
-
Custom OpenWrt based on r33202 (no configs)
-
Custom OpenWRT config file (`make` file to compile OpenWrt)
-
TODO (a working set of config files)
Wi-Fi Car Howto
(needs review/check)
-
Connect to your router using telnet or the serial port
-
Configure networking
-
Access the video stream through your browser
-
Open minicom to connect to your Arduino's USB port
-
Issue commands to your Arduino while watching the video stream
Sample Code
Arduino
- wifi-car.ino
-
// Wifi-Car Code for Arduino // controls motors, servos and others, // by commands through serial USB // If used with router, you need to install Drivers. // for serial FTDI or ACM for newer Arduinos // // This code is basically copied from examples at DFRobot and Arduino. // So it is well explained and documented online. // // You will need: // - motors + motor driver // - PC speaker or something for sound ( horn ) // - 2 Servo motors to move camera's point of view. // // Open-Drone.org #include <Servo.h> Servo twist; Servo nod; int EN1 = 6; int EN2 = 5; int IN1 = 7; int IN2 = 4; // horn int horn = 3; int hornLevel; //Variable to store servor possition int horizontal; int vertical; void setup() { for(int i=3;i<=7;i++) pinMode(i, OUTPUT); //set pin 3,4,5,6,7 to output mode, including the horn // Servo SetUp horizontal = 90; vertical = 90; twist.attach(8); // initialize servo motors for the neck of the camera nod.attach(9); delay(10); // Start servos Centered when Wifi-Car is turned ON nod.write(horizontal); twist.write(horizontal); // tell servo to go to centered possition delay(15); hornLevel = 100; Serial.begin(115200); } void loop() { char val; while(1) { val = Serial.read(); if(val!=-1) { switch(val) // here are all the commands i will be sending from the usb connection { case 'w'://Move ahead Motor1(250,true); Motor2(250,true); delay(50); Motor1(0,false); Motor2(0,false); break; case 'x'://move back Motor1(250,false); Motor2(250,false); delay(50); Motor1(0,false); Motor2(0,false); break; case 'd'://turn left Motor1(250,false); Motor2(250,true); delay(50); Motor1(0,false); Motor2(0,false); break; case 'a'://turn right Motor1(250,true); Motor2(250,false); delay(50); Motor1(0,false); Motor2(0,false); break; case 's'://stop Motor1(0,false); Motor2(0,false); break; // Move the neck, control servos, horizontal and vertical case 'e': if (horizontal < 1) { horizontal = 0; break; } else { horizontal--; Serial.print("Servo twist (horizontal) possition: "); Serial.println(horizontal); twist.write(horizontal); break; } case 'q':// for the neck of the camera if (horizontal > 179) { horizontal = 179; break; } else { horizontal++; Serial.print("Servo twist (horizontal) possition: "); Serial.println(horizontal); twist.write(horizontal); break; } case 'f':// for the neck of the camera if (vertical > 127) { vertical = 127; break; } else { vertical++; Serial.print("Servo nod (vertical) possition: "); Serial.println(vertical); nod.write(vertical); break; } case 'r':// for the neck of the camera if (vertical < 32) { vertical = 32; break; } else { vertical--; Serial.print("Servo nod (vertical) possition: "); Serial.println(vertical); nod.write(vertical); break; } case 't':// center camera point of view vertical = 90; horizontal = 90; Serial.println("Centering neck .. "); nod.write(vertical); twist.write(horizontal); break; case 'h': //horn, like in the movie. Wifi-Car can also talk! //if you have some sensors, you can use this function to let him complain. //dont forget to attach the pitch library! digitalWrite(horn,HIGH); Serial.println("Beep Beep"); if (hornLevel < 100) { for(int i=1;i<=20;i++) tone(3, random(31, 4978), 200); } hornLevel = 90; Serial.println("Beep Beep"); break; } } } } // Basic motor functions void Motor1(int pwm, boolean reverse) { analogWrite(EN1,pwm); //set pwm control, 0 for stop, and 255 for maximum speed if(reverse) digitalWrite(IN1,HIGH); else digitalWrite(IN1,LOW); } void Motor2(int pwm, boolean reverse) { analogWrite(EN2,pwm); if(reverse) digitalWrite(IN2,HIGH); else digitalWrite(IN2,LOW); }
Flymaple
- flymaple-car.ino
-
// Wifi-Car Code for FlyMaple // test control motors // // This code is basically copied from examples at DFrobot and arduino. So it is well explained and documented online. // You will need: // flymaple + motors + motor driver // LED will light when serial command is entered. // Open-Drone.org // Motors int M1 = 5; int E1 = 4; int M2 = 6; int E2 = 7; void setup() { SerialUSB.begin(); SerialUSB.println("Wifi-Car booting up"); pinMode(BOARD_LED_PIN, OUTPUT); pinMode(E1, OUTPUT); pinMode(E2, OUTPUT); pinMode(M1, PWM); pinMode(M2, PWM); Motor1(0,false); Motor2(0,false); delay(50); } void loop() { char value; while (SerialUSB.available()){ digitalWrite(BOARD_LED_PIN,HIGH); value = SerialUSB.read(); if(value!=-1) { switch(value) // here are all the commands i will be sending from the usb connection { case 'w'://Move ahead Motor1(65000,true); Motor2(65000,true); delay(50); Motor1(0,false); Motor2(0,false); break; case 'x'://move back Motor1(65000,false); Motor2(65000,false); delay(50); Motor1(0,false); Motor2(0,false); break; case 'd'://turn left Motor1(65000,false); Motor2(65000,true); delay(50); Motor1(0,false); Motor2(0,false); break; case 'a'://turn right Motor1(65000,true); Motor2(65000,false); delay(50); Motor1(0,false); Motor2(0,false); break; case 's'://stop Motor1(0,false); Motor2(0,false); break; } } } digitalWrite(BOARD_LED_PIN,LOW); delay(20); } // Basic motor functions void Motor1(int pwm, boolean reverse) { analogWrite(M1,pwm); //set pwm control, 0 for stop, and 255 for maximum speed if(reverse) digitalWrite(E1,HIGH); else digitalWrite(E1,LOW); } void Motor2(int pwm, boolean reverse) { analogWrite(M2,pwm); if(reverse) digitalWrite(E2,HIGH); else digitalWrite(E2,LOW); }