//Wirelessly Controlled Rover using Arduino and RF Modules //Coded and tested by Sidharth Makhija // Version 1 1/4/2014 //Sensor used is HCSR04 Ultrasonic Sensor /*Working : This is the Receiver code of the Rover. When the joystick on the remote is moved in the forward direction the rover first checks for any obstacle in front of it....if the path is clear the rover moves forward...else it overrides the user's control and performs the obstacle avoidance maneuver. This code uses the VirtualWire and AFMotor(motorshield library). The motor shield used is self soldered since (Used the Adafruit Schematic) I made some modifications by bypassing the enable pins directly to 5V thereby saving 4 PWM pins. I have also added a Knight-Rideresque LED chaser in the front which runs on an ATTiny85 which runs off the Arduino 5V supply. The code for the Attiny85 is separate since the Knight-Rider LED chaser is optional. The robot also has a buzzer that beeps whenever it encounters an obstacle. More pictures,videos and info on the rover here : http://letsmakerobots.com/node/40002 For any doubts,corrections,etc. shoot a mail here : sidharth1295@gmail.com May the force be with you! */ #include #include //Initializing all variables //digital pin 16(analog 2) is the headlight pin. int hLight =16; //digital pin 17 (analog 3) is the buzzer pin. int buz = 17; //counter for the OVerride beep. int buzCount = 0; //counter for the start - up beep. int startBuz = 0; //Vaariables where distances measured are stored. int distFront; int distLeft; int distRight; //Minimum distance of 20cm from any obstacle. int distLimit = 20; //HCSR04 Variables //digital pin 14,15 (analog 0 and 1 respectively) int trig = 14; int echo = 15; unsigned long pulsetime = 0; AF_DCMotor motor1(1, MOTOR12_1KHZ); AF_DCMotor motor2(2, MOTOR12_1KHZ); AF_DCMotor motor3(3, MOTOR34_1KHZ); AF_DCMotor motor4(4, MOTOR34_1KHZ); void setup() { Serial.begin(9600); //Only for Debugging...Comment out Serial.println("setup"); pinMode(trig,OUTPUT); pinMode(echo,INPUT); pinMode(hLight,INPUT); pinMode(buz,OUTPUT); //Starts Receiving Data startRx(); startBeep(); /*Fix speed of all motors to 200...didn't end need these since I bypassed enables to 5V, Un-comment if needed.*/ //Set all motor speeds to 200. //motor1.setSpeed(200); //motor2.setSpeed(200); //motor3.setSpeed(200); //motor4.setSpeed(200); } void loop() { uint8_t buf[VW_MAX_MESSAGE_LEN]; uint8_t buflen = VW_MAX_MESSAGE_LEN; //Check for any Data if (vw_get_message(buf, &buflen)) { int i; // Flash a light to show received good message digitalWrite(13, true); for (i = 0; i < buflen; i++) { if(buf[i] == '1') { //Checks for obtsacle since forward command is received. distFront = readDistance(); if(distFront < distLimit) { //Override the controller since obstacle is detected. Serial.println("Override"); override(); } else { //No obstacle----> move forward. forward(); } } if(buf[i] == '2') { backward(); } if(buf[i] == '3') { right(); } if(buf[i] == '4') { left(); } if(buf[i] == '5') { stopMotor(); } if(buf[i]== '6') { digitalWrite(hLight,HIGH); Serial.println("Light em Up"); } if(buf[i]== '7') { digitalWrite(hLight,LOW); Serial.println("Lights OFF"); } Serial.print(" "); } Serial.println(""); digitalWrite(13, false); } } //////////////////Functions!Functions!Functions!///////////////////////////////////////////// void forward() { motor1.run(FORWARD); motor2.run(FORWARD); motor3.run(FORWARD); motor4.run(FORWARD); Serial.println("Forward"); } void backward() { motor1.run(BACKWARD); motor2.run(BACKWARD); motor3.run(BACKWARD); motor4.run(BACKWARD); Serial.println("Backward"); } void right() { motor1.run(FORWARD); motor2.run(FORWARD); motor3.run(BACKWARD); motor4.run(BACKWARD); Serial.println("Right"); } void left() { motor1.run(BACKWARD); motor2.run(BACKWARD); motor3.run(FORWARD); motor4.run(FORWARD); Serial.println("Left"); } void stopMotor() { motor1.run(RELEASE); motor2.run(RELEASE); motor3.run(RELEASE); motor4.run(RELEASE); Serial.println("Stopped"); } //Returns distance value from ultrasonic sensor int readDistance() { digitalWrite(trig, LOW); delayMicroseconds(2); digitalWrite(trig, HIGH); delayMicroseconds(10); digitalWrite(trig,LOW); pulsetime = pulseIn(echo, HIGH); return pulsetime/58.2;//magic } void override() { /*Note : The time it takes for the rover to turn depends in the motors you use...so that will be fixed during debugging.*/ //Stop receiving data from the user . vw_rx_stop(); delay(10); //Obstacle avoidance maneuver and all that jazz.. stopMotor(); delay(100); beep(); buzCount= 0; delay(500); backward(); delay(300); stopMotor(); delay(10); scanLeft(); delay(100); scanRight(); if(distLeft > distRight && distLeft > distLimit) { left(); delay(500); stopMotor(); } else if(distRight > distLeft && distRight > distLimit) { right(); delay(500); stopMotor(); } else { backward(); delay(300); stopMotor(); } //Restart the receiver. startRx(); } void scanLeft() { Serial.println("Scanning Left...."); delay(10); left(); //turns left to scan delay(300); stopMotor(); delay(10); distLeft = readDistance(); Serial.print("Left is "); Serial.println(distLeft); //scan delay(100); right(); //turns to the centre again delay(300); stopMotor(); } void scanRight() { Serial.println("Scanning Right...."); right(); delay(300); stopMotor(); delay(10); distRight = readDistance(); Serial.print("Right is "); Serial.println(distRight); delay(100); left(); delay(300); stopMotor(); } void startRx() { vw_setup(2000); //Rx on digital pin 2. vw_set_rx_pin(2); vw_rx_start(); } //Obstacle detected beep void beep() { while(buzCount<2) { digitalWrite(buz,LOW); delay(50); digitalWrite(buz,HIGH); delay(50); digitalWrite(buz,LOW); buzCount++; } } //Start-up beep void startBeep() { while(startBuz<2) { digitalWrite(buz,LOW); delay(50); digitalWrite(buz,HIGH); delay(50); digitalWrite(buz,LOW); delay(50); digitalWrite(buz,HIGH); delay(75); digitalWrite(buz,LOW); startBuz++; } }