Hackster is hosting Hackster Holidays, Ep. 5: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Friday!Stream Hackster Holidays, Ep. 5 on Friday!
Anshul Singh
Created May 29, 2016 © GPL3+

Drone Collision Avoidance System

I used Arduino boards, NodeJS, and a variety of development components to make a collision avoidance system that works in any lighting.

Full instructions provided6 hours5,470
Drone Collision Avoidance System

Things used in this project

Hardware components

Arduino Pro Mini 328 - 5V/16MHz
SparkFun Arduino Pro Mini 328 - 5V/16MHz
×1
Arduino Mega 2560
Arduino Mega 2560
×1
AR.Drone
Parrot AR.Drone
×1
Ping))) Ultrasonic Distance Sensor
×1
SMAKN® 433Mhz Rf Transmitter and Receiver Link Kit for Arduino/Arm/McU
×1
SMAKN® Arduino Joystick Analog Expansion Board JoyStick Shield keyboard and mouse funct
×1
SparkFun Arduino Stackable Header Kit
×2
Rotary potentiometer (generic)
Rotary potentiometer (generic)
×4
Standard LCD - 16x2 White on Blue
Adafruit Standard LCD - 16x2 White on Blue
×1
Jumper wires (generic)
Jumper wires (generic)
×1
Male/Female Jumper Wires
Male/Female Jumper Wires
×1
Female/Female Jumper Wires
Female/Female Jumper Wires
×1
Solderless Breadboard Full Size
Solderless Breadboard Full Size
×1
SparkFun Toggle Switch
×1

Software apps and online services

Arduino IDE
Arduino IDE
Node.js
Sublime Text

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Schematics

Arduino Remote Schematic

Onboard Drone Platform Schematic

Code

Arduino Mega 2560 Remote Code

Arduino
This code runs on the Arduino Mega 2560 Microcontroller, which controls the remote of the project. It functions as described earlier.
//new shot at remote
//accurate lcd and potentiometer functionality
#include <LiquidCrystal.h>
#include <VirtualWire.h>
LiquidCrystal lcd(48, 46, 42, 40, 38, 36);
int potentiometerpin1 = 7;
int potentiometerpin2 = 8;
int potentiometerpin3 = 9;
int potentiometerpin4 = 10;

int up_button = 2;
int down_button = 4;
int left_button = 5;
int right_button = 3;
int start_button = 6;
int select_button = 7;
int analog_button = 8;
int x_axis = A0;
int y_axis = A1;
int buttons[] = {up_button, down_button, left_button, right_button, start_button, select_button, analog_button};

void setup() {
  initializelcdscreen();
  pinMode(53, INPUT_PULLUP);
  vw_set_ptt_inverted(true);
  vw_setup(2000);
  vw_set_rx_pin(44);
  for (int i; i < 7; i++) {
   pinMode(buttons[i], INPUT);
   digitalWrite(buttons[i], HIGH);
  }
  Serial.begin(9600);
  while (digitalRead(select_button) == 1) {
    delay(100);
  }
  if (digitalRead(select_button) == 0) {
    Serial.println("1000");
    vw_rx_start();
    delay(1000);
  }
}
void loop() {
  int failsafestatus = digitalRead(53);
  if (failsafestatus == 0) { //avoidance on
    uint8_t buflen = VW_MAX_MESSAGE_LEN; //reads the data
    uint8_t buf[buflen];
    if (vw_get_message(buf, &buflen)) {
      for(int i = 0;i < buflen;i++) {
        if (buf[i] == 51) {
          //safe character recieved
          avoidanceremote();
         // Serial.println("safe");
        }
        else if (buf[i] == 49) {
          //alarm character recieved
          Serial.println("22");
          int randomval = 0;
          while (randomval == 0) {
            int updatedavoidance = systemupdate();
            if (updatedavoidance == 0) { return; }
            if (digitalRead(53) == 1) { return; }
            updatepotentiometers();
          }
        }
      }
    }
  }
  if (failsafestatus == 1) { //avoidance off
    remote();
  }
}

int readpotentiometervalue(int potentiometerpin) {
  int potentiometerrawvalue = analogRead(potentiometerpin);
  int potentiometermapvalue = map(potentiometerrawvalue, 0, 1023, 0, 10); //could be problematic with 1-11 value instead of 1-10
  switch (potentiometerpin) {
    case 7:
      lcd.setCursor(0,1);
      lcd.print(potentiometermapvalue);
      break;
    case 8:
      lcd.setCursor(4,1);
      lcd.print(potentiometermapvalue);
      break;
    case 9:
      lcd.setCursor(8,1);
      lcd.print(potentiometermapvalue);
      break;
    case 10:
      lcd.setCursor(13,1);
      lcd.print(potentiometermapvalue);
      break;
  }
  return potentiometermapvalue;
}
int updatepotentiomete(int pin, int compare_number) {
  updatepotentiometers();
  int newpot = readpotentiometervalue(pin) + 1;
  if (newpot != compare_number) {
    return 1;
  }
  if (digitalRead(53) == 1) {
    return 1;
  }
  else {
    return 0;
  }
}
int updatepotentiometer(int pin, int compare_number) {
  updatepotentiometers();
  int newpot = readpotentiometervalue(pin) + 1;
  if (digitalRead(53) == 0) {
    return 1;
  }
  if (newpot != compare_number) {
    return 1;
  }
  else {
    return 0;
  }
}
void initializelcdscreen() { //initializes the lcd screen with settings information
  lcd.begin(16,2); //starts the lcd as a 16x2 display
  lcd.setCursor(0,0);
  lcd.print("F/B");
  lcd.setCursor(4,0);
  lcd.print("L/R");
  lcd.setCursor(8,0);
  lcd.print("U/D");
  lcd.setCursor(13,0);
  lcd.print("R");
  lcd.setCursor(0, 1); //prints the settings page on the LCD
}
void updatepotentiometers() {
  int pot1 = readpotentiometervalue(potentiometerpin1) + 1;
  int pot2 = readpotentiometervalue(potentiometerpin2) + 1;
  int pot3 = readpotentiometervalue(potentiometerpin3) + 1;
  int pot4 = readpotentiometervalue(potentiometerpin4) + 1;
}
void remote() {
  int pot1 = readpotentiometervalue(potentiometerpin1) + 1;
  int pot2 = readpotentiometervalue(potentiometerpin2) + 1;
  int pot3 = readpotentiometervalue(potentiometerpin3) + 1;
  int pot4 = readpotentiometervalue(potentiometerpin4) + 1;
  if (digitalRead(select_button) == 0) {
    Serial.println("1"); //takeoff
    while (digitalRead(select_button) == 0) {
      updatepotentiometers();
    }//while loop to prevent repeated digits
  }
  if (digitalRead(up_button) == 0) {
    int upspeed = 50 + pot3;
    Serial.println(upspeed);
    while (digitalRead(up_button) == 0) {
      int updatereturn = updatepotentiometer(potentiometerpin3, pot3);
      if (updatereturn == 1) { return; }
    } //same type of while loop
    //going up with correct potenitometer speed that is set
    //numbers are designated for certain actions... speed is decoded from the numbers later on
  }
  if (digitalRead(down_button) == 0) {
    int downspeed = 60 + pot3;
    Serial.println(downspeed);
    while (digitalRead(down_button) == 0) {
      int updatereturn = updatepotentiometer(potentiometerpin3, pot3);
      if (updatereturn == 1) { return; }
    }
    //going down with same pattern
  } 
  if (digitalRead(left_button) == 0) {
    int ccspeed = 80 + pot4;
    Serial.println(ccspeed);
    while (digitalRead(left_button) == 0) {
      int updatereturn = updatepotentiometer(potentiometerpin4, pot4);
      if (updatereturn == 1) { return; }
    }
    //going left with same pattern
  } 
  if (digitalRead(right_button) == 0) {
    int cspeed = 70 + pot4;
    Serial.println(cspeed);
    while (digitalRead(right_button) == 0) {
      int updatereturn = updatepotentiometer(potentiometerpin4, pot4);
      if (updatereturn == 1) { return; }
    }
    //going right with same pattern
  }
  if (digitalRead(start_button) == 0) {
    Serial.println("0");
    while (digitalRead(start_button) == 0) {
      updatepotentiometers();
    }
    //landing with same pattern
  }
  int x = map(analogRead(x_axis), 0, 1000, -1, 1); //reads the x data from the joystick
  int y = map(analogRead(y_axis), 0, 1000, -1, 1); //reads the y data from the joystick
  if (x == 0 && y == 1) {
    //forward
    int fspeed = pot1 + 10;
    Serial.println(fspeed); //same type of pattern
    while (map(analogRead(x_axis), 0, 1000, -1, 1) == 0 && map(analogRead(y_axis), 0, 1000, -1, 1) == 1) {
      int updatereturn = updatepotentiometer(potentiometerpin1, pot1);
      if (updatereturn == 1) { return; }
    }//prevents repeated data
  }
  if (x == 0 && y == -1) {
    int bspeed = pot1 + 20;
    Serial.println(bspeed);
    while (map(analogRead(x_axis), 0, 1000, -1, 1) == 0 && map(analogRead(y_axis), 0, 1000, -1, 1) == -1) {
      int updatereturn = updatepotentiometer(potentiometerpin1, pot1);
      if (updatereturn == 1) { return; }
    }
    //backward with same type of pattern
  }
  if (x == -1 && y == 0) {
    //left with same type of pattern
    int lspeed = 40 + pot2;
    Serial.println(lspeed);
    while (map(analogRead(x_axis), 0, 1000, -1, 1) == -1 && map(analogRead(y_axis), 0, 1000, -1, 1) == 0) {
      int updatereturn = updatepotentiometer(potentiometerpin2, pot2);
      if (updatereturn == 1) { return; }
    }
  }
  if (x == 1 && y == 0) {
    //right with same type of pattern
    int rspeed = 30 + pot2;
    Serial.println(rspeed);
    while (map(analogRead(x_axis), 0, 1000, -1, 1) == 1 && map(analogRead(y_axis), 0, 1000, -1, 1) == 0) {
      int updatereturn = updatepotentiometer(potentiometerpin2, pot2);
      if (updatereturn == 1) { return; }
    }
  }
  if (x == 0 && y == 0 && digitalRead(start_button) == 1 && digitalRead(select_button) == 1 && digitalRead(up_button) == 1 && digitalRead(down_button) == 1 && digitalRead(left_button) == 1 && digitalRead(right_button) == 1) {
    Serial.println("2");
    while (map(analogRead(x_axis), 0, 1000, -1, 1) == 0 && map(analogRead(y_axis), 0, 1000, -1, 1) == 0 && digitalRead(start_button) == 1 && digitalRead(select_button) == 1 && digitalRead(up_button) == 1 && digitalRead(down_button) == 1 && digitalRead(left_button) == 1 && digitalRead(right_button) == 1) {
      if (digitalRead(53) == 0) {
        return;
      }
      updatepotentiometers();
    }
  }  
}
void avoidanceremote() {
  int pot1 = readpotentiometervalue(potentiometerpin1) + 1;
  int pot2 = readpotentiometervalue(potentiometerpin2) + 1;
  int pot3 = readpotentiometervalue(potentiometerpin3) + 1;
  int pot4 = readpotentiometervalue(potentiometerpin4) + 1;
  if (digitalRead(select_button) == 0) {
    Serial.println("1"); //takeoff
    while (digitalRead(select_button) == 0) {
      updatepotentiometers();
    }//while loop to prevent repeated digits
  }
  if (digitalRead(up_button) == 0) {
    int upspeed = 50 + pot3;
    Serial.println(upspeed);
    while (digitalRead(up_button) == 0) {
      int updatereturn = updatepotentiomete(potentiometerpin3, pot3);
      if (updatereturn == 1) { return; }
      updatereturn = systemupdate();
      if (updatereturn == 1) { return; }
    } //same type of while loop
    //going up with correct potenitometer speed that is set
    //numbers are designated for certain actions... speed is decoded from the numbers later on
  }
  if (digitalRead(down_button) == 0) {
    int downspeed = 60 + pot3;
    Serial.println(downspeed);
    while (digitalRead(down_button) == 0) {
      int updatereturn = updatepotentiomete(potentiometerpin3, pot3);
      if (updatereturn == 1) { return; }
      updatereturn = systemupdate();
      if (updatereturn == 1) { return; }
    }
    //going down with same pattern
  } 
  if (digitalRead(left_button) == 0) {
    int ccspeed = 80 + pot4;
    Serial.println(ccspeed);
    while (digitalRead(left_button) == 0) {
      int updatereturn = updatepotentiomete(potentiometerpin4, pot4);
      if (updatereturn == 1) { return; }
      updatereturn = systemupdate();
      if (updatereturn == 1) { return; }
    }
    //going left with same pattern
  } 
  if (digitalRead(right_button) == 0) {
    int cspeed = 70 + pot4;
    Serial.println(cspeed);
    while (digitalRead(right_button) == 0) {
      int updatereturn = updatepotentiomete(potentiometerpin4, pot4);
      if (updatereturn == 1) { return; }
      updatereturn = systemupdate();
      if (updatereturn == 1) { return; }
    }
    //going right with same pattern
  }
  if (digitalRead(start_button) == 0) {
    Serial.println("0");
    while (digitalRead(start_button) == 0) {
      updatepotentiometers();
    }
    //landing with same pattern
  }
  int x = map(analogRead(x_axis), 0, 1000, -1, 1); //reads the x data from the joystick
  int y = map(analogRead(y_axis), 0, 1000, -1, 1); //reads the y data from the joystick
  if (x == 0 && y == 1) {
    //forward
    int fspeed = pot1 + 10;
    Serial.println(fspeed); //same type of pattern
    while (map(analogRead(x_axis), 0, 1000, -1, 1) == 0 && map(analogRead(y_axis), 0, 1000, -1, 1) == 1) {
      int updatereturn = updatepotentiomete(potentiometerpin1, pot1);
      if (updatereturn == 1) { return; }
      updatereturn = systemupdate();
      if (updatereturn == 1) { return; }
    }//prevents repeated data
  }
  if (x == 0 && y == -1) {
    int bspeed = pot1 + 20;
    Serial.println(bspeed);
    while (map(analogRead(x_axis), 0, 1000, -1, 1) == 0 && map(analogRead(y_axis), 0, 1000, -1, 1) == -1) {
      int updatereturn = updatepotentiomete(potentiometerpin1, pot1);
      if (updatereturn == 1) { return; }
      updatereturn = systemupdate();
      if (updatereturn == 1) { return; }
    }
    //backward with same type of pattern
  }
  if (x == -1 && y == 0) {
    //left with same type of pattern
    int lspeed = 40 + pot2;
    Serial.println(lspeed);
    while (map(analogRead(x_axis), 0, 1000, -1, 1) == -1 && map(analogRead(y_axis), 0, 1000, -1, 1) == 0) {
      int updatereturn = updatepotentiomete(potentiometerpin2, pot2);
      if (updatereturn == 1) { return; }
      updatereturn = systemupdate();
      if (updatereturn == 1) { return; }
    }
  }
  if (x == 1 && y == 0) {
    //right with same type of pattern
    int rspeed = 30 + pot2;
    Serial.println(rspeed);
    while (map(analogRead(x_axis), 0, 1000, -1, 1) == 1 && map(analogRead(y_axis), 0, 1000, -1, 1) == 0) {
      int updatereturn = updatepotentiomete(potentiometerpin2, pot2);
      if (updatereturn == 1) { return; }
      updatereturn = systemupdate();
      if (updatereturn == 1) { return; }
    }
  }
  if (x == 0 && y == 0 && digitalRead(start_button) == 1 && digitalRead(select_button) == 1 && digitalRead(up_button) == 1 && digitalRead(down_button) == 1 && digitalRead(left_button) == 1 && digitalRead(right_button) == 1) {
    Serial.println("2");
    while (map(analogRead(x_axis), 0, 1000, -1, 1) == 0 && map(analogRead(y_axis), 0, 1000, -1, 1) == 0 && digitalRead(start_button) == 1 && digitalRead(select_button) == 1 && digitalRead(up_button) == 1 && digitalRead(down_button) == 1 && digitalRead(left_button) == 1 && digitalRead(right_button) == 1) {
      if (digitalRead(53) == 1) {
        return;
      }
      int updatereturn = systemupdate();
      if (updatereturn == 1) { return; }
      updatepotentiometers();
    }
  }   
}
int systemupdate() {
  uint8_t buflen = VW_MAX_MESSAGE_LEN; //reads the data
  uint8_t buf[buflen];
  if (vw_get_message(buf, &buflen)) {
    for(int i = 0;i < buflen;i++) {
      if (buf[i] == 51) {
        return 0;
      }
      else if (buf[i] == 49) {
        return 1;
      }
    }
  }
}

Arduino Mini Onboard Module Code

Arduino
This code functions with the Arduino Mini and the Ping))) Ultrasonic Sensor as described earlier.
//MOUNTED ON DRONE FOR AVOIDANCE
int durationPing;                 
int inchesdistancePing;                 
const int PingSens = 7;
#include <VirtualWire.h>
void setup() {
 vw_set_ptt_inverted(true); // Required for DR3100
 vw_setup(2000);	 // Bits per sec
 vw_set_tx_pin(8);
}

void loop() {
   pinMode(PingSens, OUTPUT);	                 
   digitalWrite(PingSens, LOW);	                 
   delayMicroseconds(2);
   digitalWrite(PingSens, HIGH);                      
   delayMicroseconds(2);                               
   digitalWrite(PingSens, LOW);                       
   pinMode(PingSens, INPUT);	                         
   int durationPing = pulseIn(PingSens, HIGH);    
 
   inchesdistancePing = durationPing / 74 / 2;
   if(inchesdistancePing < 26)
 {
  const char *c = "1";
  vw_send((uint8_t *)c, 1);
 }
 if(inchesdistancePing >= 26)
 {
   const char *c = "3";
   vw_send((uint8_t *)c, 1);
 }
}

Node.js Script Code

JavaScript
This code functions in the transfer of movement commands sent from the Arduino Mega 2560 to the drone itself, as described earlier.
var serialport = require("serialport"); //calls an instance of the serialport library
var SerialPort = serialport.SerialPort; //basic setup for the serialport
var arDrone = require('ar-drone'); //creates an instance of the arDrone library
var client  = arDrone.createClient(); //basic setup for the ardrone library
client.disableEmergency(); //disables the drone's emergency functions to improve performance

serialport.list(function (err, ports) { //function for listing the ports
  ports.forEach(function(port) { //action for each port
    if (port.manufacturer == ('Arduino (www.arduino.cc)')) { //finds the port on which the arduino mega is connected on
    	console.log("Found Arduino On: " + port.comName); //serial prints the port on which the arduino was found on
    	var serialPort = new SerialPort(port.comName, { //sets the serialport variable to the arduino serialport
      		baudrate: 9600, //setting the baudrate the arduino is set at
      		parser: serialport.parsers.readline("\n") //setting the parser
    	});
    	serialPort.on("open", function () { //actions which execute when the serialport opens
      		console.log('');
      		console.log('SerialPort open!');
      		console.log('Make sure to hit that takeoff button!')
      		console.log(''); //console log that the serial port is open
      		serialPort.on('data', function(data) { //executes when data comes over the serialport
        		console.log(data); //serialprints the data coming on the serialport
        		if (data == 0) {
          			console.log('landing');
          			console.log('');
          			console.log('');
          			client.land(); //lands the drone
        		}
        		if (data == 1) {
          			console.log('taking off');
          			console.log('');
          			console.log('');
          			client.takeoff(); //has the drone take off
        		} 
        		if (data == 2) {
          			console.log('hovering');
          			console.log('');
          			console.log('');
          			client.stop(); //has the drone hover
        		}
        		if (data >= 11 && data <= 20) {
          			var fspeed = (data - 10) / 10; //calculate the speed which is sent by the arduino for the action desired
          			console.log('going forward');
          			console.log('speed: ' + fspeed);
          			console.log('');
          			client.front(fspeed); //makes the drone go forward with the desired speed
        		}
        		if (data >= 21 && data <= 30) {
          			var bspeed = (data - 20) / 10; //calculate the speed which is sent by the arduino for the action desired
          			console.log('going backward');
          			console.log('speed: ' + bspeed);
          			console.log('');
          			client.back(bspeed); //makes the drone go backward with the desired speed
        		}
        		if (data >= 31 && data <= 40) {
          			var rspeed = (data - 30) / 10; //calculate the speed which is sent by the arduino for the action desired
          			console.log('going right');
          			console.log('speed: ' + rspeed);
          			console.log('');
          			client.right(rspeed); //makes the drone go right with the desired speed
        		}
        		if (data >= 41 && data <= 50) {
          			var lspeed = (data - 40) / 10; //calculate the speed which is sent by the arduino for the action desired
          			console.log('going left');
          			console.log('speed: ' + lspeed);
          			console.log('');
          			client.left(lspeed); //makes the drone go left with the desired speed
        		}
        		if (data >= 51 && data <= 60) {
          			var uspeed = (data - 50) / 10; //calculate the speed which is sent by the arduino for the action desired
          			console.log('going upward');
          			console.log('speed: ' + uspeed);
          			console.log('');
          			client.up(uspeed); //makes the drone go up with the desired speed
        		}
        		if (data >= 61 && data <= 70) {
          			var dspeed = (data - 60) / 10; //calculate the speed which is sent by the arduino for the action desired
          			console.log('going downward');
          			console.log('speed: ' + dspeed);
          			console.log('');
          			client.down(dspeed); //makes the drone go downward with the desired speed
        		}
        		if (data >= 71 && data <= 80) {
          			var cspeed = (data - 70) / 10; //calculate the speed which is sent by the arduino for the action desired
          			console.log('turning clockwise');
          			console.log('speed: ' + cspeed);
          			console.log('');
          			client.clockwise(cspeed); //makes the drone turn clockwise with the desired speed
        		}
        		if (data >= 81 && data <= 90) {
          			var ccspeed = (data - 80) / 10; //calculate the speed which is sent by the arduino for the action desired
          			console.log('turning counterclockwise');
          			console.log('speed: ' + ccspeed);
          			console.log('');
          			client.counterClockwise(ccspeed); //makes the drone turn counterclockwise with the desired speed
        		}
        	});
    	});
    }
  });
});  

Credits

Anshul Singh

Anshul Singh

1 project • 1 follower
I'm an Arduino hackster!

Comments