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").
If you are interested our Wi-Fi Car and want make your own, watch the videos in this Youku playlist (instructions in Chinese).
There are a few current versions of the hardware:
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.
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.
(needs review/check)
// 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); }
// 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); }