Industrial manufacturing
Industrial Internet of Things | Industrial materials | Equipment Maintenance and Repair | Industrial programming |
home  MfgRobots >> Industrial manufacturing >  >> Manufacturing Technology >> Manufacturing process

DIY Autonomous Nerf Sentry Turret – Build a Smart Nerf Gun with Stepper Motors, Camera, and Arduino

Components and supplies

DIY Autonomous Nerf Sentry Turret – Build a Smart Nerf Gun with Stepper Motors, Camera, and Arduino
OpenBuilds NEMA 17 Stepper Motor
×1
DFRobot Stepper Motor with Gearbox
×1
DFRobot Stepper Motor Driver
×1
DFRobot Pixy 2 Cam
×1
DIY Autonomous Nerf Sentry Turret – Build a Smart Nerf Gun with Stepper Motors, Camera, and Arduino
Arduino Mega 2560
×1
DIY Autonomous Nerf Sentry Turret – Build a Smart Nerf Gun with Stepper Motors, Camera, and Arduino
Ultrasonic Sensor - HC-SR04 (Generic)
×1
Nerf Nitron Gun
×1

Necessary tools and machines

DIY Autonomous Nerf Sentry Turret – Build a Smart Nerf Gun with Stepper Motors, Camera, and Arduino
3D Printer (generic)
DIY Autonomous Nerf Sentry Turret – Build a Smart Nerf Gun with Stepper Motors, Camera, and Arduino
Soldering iron (generic)
CNC Router

Apps and online services

DIY Autonomous Nerf Sentry Turret – Build a Smart Nerf Gun with Stepper Motors, Camera, and Arduino
Arduino IDE
DIY Autonomous Nerf Sentry Turret – Build a Smart Nerf Gun with Stepper Motors, Camera, and Arduino
Autodesk Fusion 360

About this project

Idea

A few years ago, I saw a project that showcased a semi-autonomous turret that could fire on its own once aimed. That gave me the idea to use a Pixy 2 camera to acquire targets and then aim the nerf gun automatically, which could then lock on and fire all on its own.

DIY Autonomous Nerf Sentry Turret – Build a Smart Nerf Gun with Stepper Motors, Camera, and Arduino

The Components

For this project, the gun would need eyes, so I chose to use the Pixy 2 due to how easily it can interface with the mainboard. Then I needed a microcontroller, so I chose an Arduino Mega 2560 due to how many pins it has.

DIY Autonomous Nerf Sentry Turret – Build a Smart Nerf Gun with Stepper Motors, Camera, and Arduino

Since the gun needs two axes, yaw and pitch, it requires two stepper motors. Because of that, DFRobot sent me their dual DRV8825 motor driver board.

DIY Autonomous Nerf Sentry Turret – Build a Smart Nerf Gun with Stepper Motors, Camera, and Arduino

CAD

I began by loading up Fusion 360 and inserting an attached canvas of the nerf gun. Then I created a solid body from that canvas. After the gun was designed, I made a platform with a few bearing-based supports that would allow the gun to rotate left to right. I placed a stepper motor next to the rotating platform to drive it.

DIY Autonomous Nerf Sentry Turret – Build a Smart Nerf Gun with Stepper Motors, Camera, and Arduino

But the bigger question is how to make the gun pitch up and down. For that, a linear drive system with one point attached to the moveable block and another point at the back of the gun was needed. A rod would connect the two points, allowing the gun to pivot along its central axis.

DIY Autonomous Nerf Sentry Turret – Build a Smart Nerf Gun with Stepper Motors, Camera, and Arduino

Manufacturing the Parts

Almost all the parts in my design are meant to be 3D printed, so I used my two printers to create them. Then I created the moveable platform by first using Fusion 360 to generate the necessary toolpaths for my CNC router, then I cut out the disk from a sheet of plywood.

DIY Autonomous Nerf Sentry Turret – Build a Smart Nerf Gun with Stepper Motors, Camera, and Arduino

Assembly

After all the parts had been created, it was time to assemble them. I started by connecting the bearing supports to the rotating disk. Then I put together the linear pitch assembly by running the 6mm aluminum rods and the threaded rod through the pieces.

DIY Autonomous Nerf Sentry Turret – Build a Smart Nerf Gun with Stepper Motors, Camera, and Arduino

DIY Autonomous Nerf Sentry Turret – Build a Smart Nerf Gun with Stepper Motors, Camera, and Arduino

DIY Autonomous Nerf Sentry Turret – Build a Smart Nerf Gun with Stepper Motors, Camera, and Arduino

Lastly, I attached the nerf gun itself with a steel rod and two post made from aluminum extrusions.

DIY Autonomous Nerf Sentry Turret – Build a Smart Nerf Gun with Stepper Motors, Camera, and Arduino

Programming

Now for the most difficult part of the project: programming. A projectile-firing machine is very complex, and the math behind it can be confusing. I started by writing out the program flow and logic step-by-step, detailing what would happen at each machine state. The different states go as follows:

  • Acquire target
  • Position the gun
  • Spool up the motors
  • Fire the gun
  • Wind down the motors

Acquiring the target involves first setting up the Pixy to track neon pink objects as targets. Then the gun moves until the target is centered in the Pixy’s view, where its distance from the gun barrel to the target is then measured. By using this distance, the horizontal and vertical distances can be found by using some basic trigonometric functions. My code has a function called get_angle() which uses these two distances to calculate how much of an angle is needed to hit that target.

The gun then moves to this position and turns on the motors via a MOSFET. After it has spooled up for five seconds it then moves the servo motor to pull the trigger. The MOSFET then switches the motor off and then the nerf gun returns to looking for targets.

Having Fun

I put a neon pink index card to the wall to test the gun’s accuracy. It did well, as my program calibrates and adjusts the angle for the measured distance. Here is a video demonstrating the gun working:

Code

  • Schematic
SchematicC/C++
Upload to Arduino Mega
#include <math.h>
#include <Arduino.h>
#include "BasicStepperDriver.h"
#include <Servo.h>
#include <Pixy2I2C.h>

//X is pitch, Y is yaw

const int pins[] = {6,7,8,5,4,12}; //MX STEP, DIR, EN, MY STEP, DIR, EN
const int limit_switch = 26, laser_pin = 11, spool_pin = 10, servo_pin = 13, distance_trig = 29, distance_echo = 30;
double velocity = 21.336;
double velocity_squared = 455.225;
float current_angle = 0.0;
float hyp_distance; //distance from gun to target in meters

#define X_MID 164
#define Y_MID 150
#define DEADZONE 15

#define G 9.8
#define STP_PER_DEG_YAW 3.333
#define STP_PER_DEG_PITCH 184859

#define MICROSTEPS 32
#define RPM 120

#define MOTOR_STEPS_Y 200
#define MOTOR_STEPS_X 1036

//17.7777 steps / degree

BasicStepperDriver pitch_stepper(MOTOR_STEPS_X, pins[1], pins[0]);
BasicStepperDriver yaw_stepper(MOTOR_STEPS_X, pins[4], pins[3]);
Servo trigger;
Pixy2I2C pixy;

enum States {
  ACQUIRE,
  POSITION,
  SPOOL,
  FIRE,
  WIND_DOWN,
  RETURN
};

States state = ACQUIRE;

void setup() {
  Serial.begin(115200);
  init_pins();
  delay(1000);
  //home_pitch();
  pixy.init();
  Serial.println("Ready...");
}

void loop() {
  switch(state){
    case ACQUIRE:
      acquire_target();
      state = POSITION;
      digitalWrite(laser_pin,HIGH);
      break;
    case POSITION:
      Serial.println("positioning");
      position_gun();
      state = SPOOL;
      break;
    case SPOOL:
      Serial.println("spooling");
      digitalWrite(spool_pin,HIGH);
      delay(5000);
      state = FIRE;
      break;
    case FIRE:
      fire_gun();
      state = WIND_DOWN;
      break;
    case WIND_DOWN:
      Serial.println("winding down");
      digitalWrite(spool_pin,LOW);
      delay(2000);
      state = RETURN;
      digitalWrite(laser_pin,LOW);
      state = ACQUIRE;
      break;
  }
}

void fire_gun(){
  Serial.println("Firing gun!");
  trigger.write(108);
  delay(400);
  trigger.write(90);
  delay(2000);
}

void position_gun(){
  float x, y;
  hyp_distance = ping();
  hyp_distance /= 100;
  while(!hyp_distance){   
    hyp_distance = ping();
    hyp_distance /= 100;
  }Serial.println(hyp_distance);
  x = cos(current_angle) * hyp_distance;
  y = sin(current_angle) * hyp_distance;
  float target_angle = get_angle(x,y);
  target_angle /= 100;
  Serial.println(target_angle);
  move_pitch(target_angle - current_angle);
  current_angle = target_angle;
}

void acquire_target(){
  int x=0, y=0;
  long steps_taken=0;
  bool lock = false;
  while(!lock){
    pixy.ccc.getBlocks();
    if(pixy.ccc.numBlocks){
      x = pixy.ccc.blocks[0].m_x;
      y = pixy.ccc.blocks[0].m_y;
      Serial.print("Target seen at location X: ");Serial.print(x);Serial.print(", Y: ");Serial.println(y);
      if(x <= (X_MID - DEADZONE)){ //If too far left, move gun left
        move_yaw(1);
      }
      else if(x >= (X_MID + DEADZONE)){
        move_yaw(-1);
      }
      else if(y <= (Y_MID - DEADZONE)){ //too far up, move gun up
        pitch_stepper.move(33152);
        steps_taken += 33152;
      }
      else if(y >= (Y_MID + DEADZONE)){
        pitch_stepper.move(33152);
        steps_taken += 33152;
      }
      else{
        lock = true;
        Serial.print("Target locked at location X: ");Serial.print(x);Serial.print(", Y: ");Serial.println(y);
        Serial.print("Steps taken: ");Serial.println(steps_taken);
      }
    }
    
  }
  current_angle = steps_taken / STP_PER_DEG_PITCH;
  Serial.print("Current angle: ");Serial.println(current_angle);
}

void init_pins(){
  pinMode(pins[2],OUTPUT);
  pinMode(pins[5],OUTPUT);
  pinMode(limit_switch, INPUT_PULLUP);
  pinMode(laser_pin, OUTPUT);
  pinMode(spool_pin, OUTPUT);
  pinMode(distance_echo, INPUT);
  pinMode(distance_trig, OUTPUT);
  digitalWrite(pins[2],LOW);
  digitalWrite(pins[5],LOW);
  digitalWrite(laser_pin,LOW);
  digitalWrite(spool_pin,LOW);
  trigger.attach(servo_pin);
  pitch_stepper.begin(RPM, MICROSTEPS);
  yaw_stepper.begin(5, MICROSTEPS);
  trigger.write(90);
}

void move_yaw(float degrees){
  yaw_stepper.move(degrees*STP_PER_DEG_YAW*32);
}

void move_pitch(float degrees){
  current_angle += degrees;
  pitch_stepper.move(degrees*STP_PER_DEG_PITCH);
}

float get_angle(float distance, float height){
  float i = 2 * height * 455.225;
  float j = G * distance * distance;
  i += j;
  j = 9.8 * i;
  i = sqrt(pow(velocity_squared,2) - j);
  
  return atan((velocity_squared-i) / (G * distance))*(180/PI);
}

float ping(){
  Serial.println("Getting distance...");
  long duration;
  digitalWrite(distance_trig, LOW);
  delayMicroseconds(5);
  digitalWrite(distance_trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(distance_trig, LOW);
  duration = pulseIn(distance_echo, HIGH);
  return duration / 2 / 29.1; //distance in meters
}

void home_pitch(){
  Serial.println(digitalRead(limit_switch));
  if(!digitalRead(limit_switch)){ //If switch is active
    pitch_stepper.rotate(720);
  }
  while(digitalRead(limit_switch)){
    //Serial.println(digitalRead(limit_switch));
    pitch_stepper.move(-32);
  }
  pitch_stepper.rotate(2880*2);
}

Custom parts and enclosures

Thingiverse Repository
CAD file on thingiverse.com

Schematics

DIY Autonomous Nerf Sentry Turret – Build a Smart Nerf Gun with Stepper Motors, Camera, and Arduino

Manufacturing process

  1. Stepper Motors: Types, Characteristics, and Practical Applications
  2. Comprehensive Bipolar Stepper Motor Library for Arduino
  3. Automated Tinder & Bumble Swiper Using Arduino UNO Stepper Motor
  4. Build an Autonomous Home Assistant Robot: Full Parts List & Setup Guide
  5. Arduino-Powered Serial-Controlled Stepper Motor Rotating Stand
  6. Precise Stepper Motor Control: 28BYJ-48 with Arduino UNO & Joystick
  7. Custom 3D‑Printed Stepper Motor: Build Your Own Precision Drive
  8. Build a Bluetooth‑Controlled Nerf Turret: Parts & Assembly Guide
  9. Comprehensive Guide to 3D Printer Stepper Motors for Superior Print Quality
  10. 4 Simple Ways to Keep Your 3D Printer Stepper Motors Cool