How to Make a Human Seeking Nerf Auto-Turret Robot

Welcome to the party pal! Here I'll be showing you how to build your very own robot that can track and target humans using a DIY Nerf auto-turret. This robot is perfect for anyone who is interested in robotics, electronics, or just wants a fun weekend project. We will be using a DF Robot Tank Devastator as the base for our robot, and outfitting it with a HuskyLens for the object detection and targeting system. Whether you're a beginner or an experienced maker, this Instructable will guide you through the entire process, so let's get started!

HARDWARE LIST
1 Huskylens
1 Tank Robot
1 Romeo BLE
1 Nerf Machine Gun
1 Powerful Servo
STEP 1
These will change slightly based on the type of nerf gun you get, but not by much. So long as you pick a nerf gun that can fire multiple shots one after another before needing to reload, we'll just be communicating with a servo to make that happen. If the nerf gun only requires pushing down the trigger, that's easy enough. We just need to mount the servo such that when it rotates a certain amount it pushes down the trigger and either hold it down or repeat the process based on how the nerf gun works. Mine was a bit more complicated, and required the trigger to be held down to allow for rapid fire, and then a mechanism on top needed pulled back and forth. This is still able to be accomplished with just a servo (though mine needed a more powerful one). This is the nerf gun I used, but I honestly would recommend looking for a different one for your project. It's big, which is fun, but even that aspect was a bit tricky because it really weighs down the tank robot. The bigger issue, though, is it requires a lot of force to pull back the triggering mechanism far enough to actually fire.
STEP 2
Mount the servo motor on top of the tank, in a position that allows the Nerf gun parts to still move correctly. This can be done by using screws or a 3D printed mount. Make sure that the servo is secured in place and that the arm of the servo is connected to the trigger of the Nerf gun. Once the servo and Nerf gun are mounted, test the rotation of the servo by connecting it to a power source and making sure that the Nerf gun can rotate to different angles. If you don't have 3D printer or access to a 3D printing service, you can use alternatives methods like using adhesives, clamps, or even hot glue to fix the servo and nerf gun in place. As you may have noticed if you watched the video at the start, this is a just for fun project and I want the servo back at the end of it so I just used duct tape. It may be a little silly looking, but it works! If your gun has the same kind of mechanism mine does, you may need to get a bit creative. I tend to go overboard when it comes to repurposing things and ended up using a pole and a socket cover (actually), but the idea can be using in a much more normal way. The idea is just that the pole needs to be able to push and pull the mechanism, but would be resting up against different parts of it so we can't just adhere them together. As such, having something for the pole to move within like the socket cover made it so that the pole could move up and down due to the angle while still pushing and pulling effectively. To accomplish this without such an odd-looking combination, you could use something like a thinner pole (like a tent stake) and a circular metal piece like a decent-sized washer. The code for the servo depends on your setup, including the angle needed, but all I needed to successfully fire my nerf turret was the little snippet below:
CODE
//Just runs once - it should be continually triggered if the person is still there
void fireNerfGun(){
  Serial.println("FIRE!!!");
  
  myservo.write(130);       // tell servo to go to position
  delay(1000);              //Wait briefly
  myservo.write(50);
  delay(1000);
 
}

The HuskyLens acts as the eyes for the tank and the nerf turret alike. The code is attached in the next step, but let's work on getting to that phase by setting up the HuskyLens!

A lot of what I'll reference below is found in the wiki (found here - https://wiki.dfrobot.com/HUSKYLENS_V1.0_SKU_SEN0305_SEN0336), but I'll include the steps to get started here for convenience:

 -Download the HuskyLens Uploader. Click here to download it. -Download the USB to UART driver, and install it. Click here to download it. -At this point you should be able to plug your HuskyLens into your computer via USB. -Run the HuskyLens Uploader, a small black cmd window will pop up first, and after a while, the interface window will appear, then click the "Select File" button to load the firmware.

 -Click the "Upload" button and wait till it finishes. 

When it finishes, so long as it's plugged in it will be able to be used to switch between different modes by moving the rotator on the top and pressing the button. It can detect faces and such without modification.

Per the HuskyLens wiki: The R and T pins of HuskyLens (their functions are SCL and SDA here) are connected to the SCL (P19) and SDA (P20) pins of the micro: bit respectively. The communication protocol between HuskyLens and micro: bit is I2C.

 

Now for a bit of fun. Navigate to the Object Tracking section on the HuskyLens and teach it what you look like. I did this close range, but it'd be easier with a second person.

Now that we've made it this far... it's time to make the HuskyLens guide a tank robot armed with a nerf turret to hunt us down!

STEP 3
The same microcontroller (in this case a Romeo BLE) will control both the tank robot and fire the nerf turret. I modified the example HuskyLens code that is set to have a robot follow the object it's tracking such that the nerf turret will open fire whenever it sees the target (sometimes it will move to look for the target but won't see the target at that moment). If your robot isn't already assembled, begin by putting together the Tank Devastator according to the instructions provided in the package. It's, thankfully, pretty painless. Be sure to get the code uploaded to your microcontroller before you put the top piece of the tank on, though! The HuskyLens comes with an attachment that can be used to adhere it to the Devastator, but I used mine to put it on the front instead of the top so that there'd be room for the nerf gun. This will likely work well for your solution as well, since the top of the tank is the most intuitive place to house the nerf gun. Lastly put the nerf gun on top and connect everything together! The code assumes that the servo is connected to pin 2.
CODE
//This code is modified from the HuskyLens example code
/***************************************************
 HUSKYLENS An Easy-to-use AI Machine Vision Sensor
 <https://www.dfrobot.com/product-1922.html>
 
 ***************************************************
 This example shows how to play with object tracking.
 
 Created 2020-03-13
 By [Angelo qiao](Angelo.qiao@dfrobot.com)
 
 GNU Lesser General Public License.
 See <http://www.gnu.org/licenses/> for details.
 All above must be included in any redistribution
 ****************************************************/

/***********Notice and Trouble shooting***************
 1.Connection and Diagram can be found here
 <https://wiki.dfrobot.com/HUSKYLENS_V1.0_SKU_SEN0305_SEN0336#target_23>
 2.This code is tested on Arduino Uno, Leonardo, Mega boards.
 ****************************************************/


#include "HUSKYLENS.h"
#include "DFMobile.h"
#include <Servo.h>

DFMobile Robot (7,6,4,5);     // initiate the Motor pin

HUSKYLENS huskylens;
//HUSKYLENS green line >> SDA; blue line >> SCL

Servo myservo; // create a servo object
void setup() {
    Serial.begin(115200);
    Robot.Direction (HIGH, LOW);  // initiate the positive direction  

    Wire.begin();
    while (!huskylens.begin(Wire))
    {
        Serial.println(F("Begin failed!"));
        Serial.println(F("1.Please recheck the \"Protocol Type\" in HUSKYLENS (General Settings>>Protocol Type>>I2C)"));
        Serial.println(F("2.Please recheck the connection."));
        delay(100);
    }

    huskylens.writeAlgorithm(ALGORITHM_OBJECT_TRACKING); //Switch the algorithm to object tracking.

    // while (true)
    // {Robot.Speed (200-50,200+50);
    // delay(2000);
    // Robot.Speed (0,0);
    // delay(2000);
    // Robot.Speed (200,200);
    // delay(2000);
    // Robot.Speed (0,0);
    // delay(2000);
    // Robot.Speed (200+50,200-50);
    // delay(2000);
    // Robot.Speed (0,0);
    // delay(2000);}

  myservo.attach(2);  // attaches the servo on pin 9 to the servo object
  myservo.write(90);              // tell servo to go to position in variable 'pos'
}

int widthLevel = 50;

int xLeft = 160-40;
int xRight = 160+40;

bool isTurning = false;
bool isTurningLeft = true;

bool isInside(int value, int min, int max){
    return (value >= min && value <= max);
}

void printResult(HUSKYLENSResult result);

void loop() {
    int32_t error;

    int left = 0, right = 0;

    if (!huskylens.request()) Serial.println(F("Fail to request objects from HUSKYLENS!"));
    else if(!huskylens.isLearned()) {Serial.println(F("Object not learned!")); Robot.Speed (0,0);}
    else if(!huskylens.available()) Serial.println(F("Object disappeared!"));
    else
    {
        HUSKYLENSResult result = huskylens.read();

        if (result.width < widthLevel){
            widthLevel = 65;
            if (isInside(result.xCenter, 0, xLeft)){
                if (isTurningLeft){
                    if (!isTurning){
                        Robot.Speed (200-50,200+50);
                    }
                }
                else{
                    if (isTurning){
                        isTurning = false;
                        isTurningLeft = !isTurningLeft;
                    }
                    Robot.Speed (200-50,200+50);
                }
            }
            else if (isInside(result.xCenter, xLeft, xRight)){
                if (isTurning){
                    isTurning = false;
                    isTurningLeft = !isTurningLeft;
                }
                Robot.Speed (200,200);
            }
            else if (isInside(result.xCenter, xRight, 320)){
                if (isTurningLeft){
                    if (isTurning){
                        isTurning = false;
                        isTurningLeft = !isTurningLeft;
                    }
                    Robot.Speed (200+50,200-50);
                }
                else{
                    if (!isTurning){
                        Robot.Speed (200+50,200-50);
                    }
                }
            }
        }
        else
        {
            widthLevel = 55;
            isTurning = true;
            if (isTurningLeft){
                Robot.Speed (0,200);
            }
            else{
                Robot.Speed (200,0);
            }
        }
        printResult(result);
        fireNerfGun();
        
    }
}

void printResult(HUSKYLENSResult result){
    if (result.command == COMMAND_RETURN_BLOCK){
        Serial.println(String()+F("Block:xCenter=")+result.xCenter+F(",yCenter=")+result.yCenter+F(",width=")+result.width+F(",height=")+result.height+F(",ID=")+result.ID);
    }
    else if (result.command == COMMAND_RETURN_ARROW){
        Serial.println(String()+F("Arrow:xOrigin=")+result.xOrigin+F(",yOrigin=")+result.yOrigin+F(",xTarget=")+result.xTarget+F(",yTarget=")+result.yTarget+F(",ID=")+result.ID);
    }
    else{
        Serial.println("Object unknown!");
    }
}


//Just runs once - it should be continually triggered if the person is still there
void fireNerfGun(){
  Serial.println("FIRE!!!");
  
  myservo.write(130);       // tell servo to go to position
  delay(1000);              //Wait briefly
  myservo.write(50);
  delay(1000);
 
}
projectImage
STEP 4
The robot is after you! Kidding. Maybe? Either way, it's time to enjoy evading your new robot overlord, or sending it after your friends. Have a good one!
License
All Rights
Reserved
licensBg
0