Measure the Speed of Nerf Darts

25K26020

Intro: Measure the Speed of Nerf Darts

In this instructable I am going to show you a cheap way on how to measure the speed of Nerf darts. Even though I own a chronometer using it annoys me most of the time. To get a good results and not a bunch of errors, you need the lighting to be perfect. Which quite often isn't the case. Hence I wanted to build a cheaper chronometer, that is independent from the light source and preferably integrated into a Nerf barrel.

Honestly I was cursing quite a few times during the construction of this barrel, since the space inside of it is kind of restricted. If you are looking for an easier method, just use a pvc tube and glue the components to the outside of it.
I ended up loving the barrel, since it makes sure that the Nerf darts fly straight through it ever time.

STEP 1: Stuff You Need

Electronics:
  • Atmega328P
  • SAA 1064 7-segment driver
  • IC7805
  • 2 x NPN transistors (z.B. BC547)
  • 2 x IR LEDs (Osram LD 274-3)
  • 2 x photo transistors (SFH 3100 F)
  • 16 MHz quartz
  • 1 x 4.7 uF Capacitor
  • 1 x 1 uF Capacitor
  • 1 x 2.7 nF Capacitor
  • 2 x 22 pF Capacitors
  • 1 x 22 kOhm Resistor
  • 3 x 10 kOhm Resistors
  • 2 x 220 Ohm Resistors
  • 3 x 7-segment displays
  • wire
  • perfboard
Other:
  • Nerf barrel
  • modelling clay
  • drill
  • sanding paper
  • paint
  • JB weld

STEP 2: Attaching the Leds

Start by marking the points, where the holes for the LEDs and the photo transistors are going to be. Try placing them as far apart as possible (to get a better result), but make sure that the Nerf can still be attached. It reaches quite far into the barrel.

Once you have marked the hole and are sure, that it won't interfere with the function of the barrel, drill the holes. You will have to drill two holes for the photo transistors (you will see what I mean, when you take a closer look at it).

Attach wires as shown in the second picture and use a third hand to hold the LEDs in place. It is important, that they don't reach into the barrel, else they will slow down or even stop the Nerf dart. Once you found the right position use JB Weld or an other type of strong two component glue, to hold them in place.

STEP 3: Modifying the Barrel

The space in the barrel is very restricted. In order to hide the electronics, fill the four holes in the front and the ones underneath the rails, as shown in the first picture. I used modelling clay to do so.
Use sanding paper to even the surface. Carefully drill a hole for the segment display. I used diamond files to get them to fit perfectly.
Depending on the size of your battery compartment you might have to mill some of the plastic away, as shown in the third picture. Furthermore you will have to remove parts of the middle rail to fit the wires and drill a hole for the button (as shown in the sixth picture).

If you want you can paint the barrel, but that's up to you.

STEP 4: Electronics

The dart speed is measured using two light barriers which are located at the front and the end of the barrel. The light barriers consist of a infrared LED (Osram LD 274-3) and a photo transistor (Q3 and Q4) (SFH 3100 F) each. The LEDs are irradiating the photo transistors across the barrel (see picture) and allow a current between the 5V VCC and ground respectively. This leads to a measurable signal in A1 and A0. The photo transistor also contain a daylight filter which keeps the ambient light from interfering with the measurements.

When a dart passes the light barrier blocking the IR-LED the current drops instantly to zero. At this time the micro controller starts counting the microseconds until the second LED is blocked. As we know the distance between the LEDs we can calculate the dart speed.
The value is send to a LED driver chip (SAA 1064) to display it on the seven segment display located on the side of the barrel.

I used an Arduino UNO to upload the following code to the Atmega:
#include "Wire.h" // I2C control
#include "Bounce.h"

byte diaplayAddr = 0x70 >> 1; // Address of the I2C control
int digitBytes[16]={63, 6, 91, 79, 102, 109, 125, 7, 127, 111, 119, 124, 57, 94, 121, 113}; // 0 1 2 3 4 5 6 7 8 9, decimal point = +128

//light barrier
int LSFrontPin = A0;  //light barrier at the front of the barrel
int LSBackPin = A1;  //light barrier at the back of the barrel
int TriggerPin = 11;

float meanVal = 0;
float meanCount = 0;

//Datenverarbeitung
int LSFrontVal = 0;
int LSBackVal = 0;
int BaseLineFront = 0;
int BaseLineBack = 0;

//threshold, to recognise a dart
int TriggerFront = 0;
int TriggerBack = 0;

//measuring the speed
int measuringBack = 0;
float length = 0.173; //m
int loopTime = 100; //time of the measuring point in micro seconds 
unsigned long measureLoops = 0;
unsigned long heartBeat = 0;

float TempBaseLineFront = 0;
float TempBaseLineBack = 0;

Bounce Taster = Bounce(TriggerPin, 10);

void setup(){
  Serial.begin(9600);
  Wire.begin(); // start up I2C bus 
  delay(500);
  createDisplay();
  
  pinMode(LSFrontPin, INPUT);
  pinMode(LSBackPin, INPUT);
  pinMode(TriggerPin, INPUT);
  delay(1000);
  
  //create a base line
  for (int ii=0; ii<100; ii++){
    TempBaseLineFront = TempBaseLineFront + analogRead(LSFrontPin);
    TempBaseLineBack = TempBaseLineBack + analogRead(LSBackPin);
    delay(10);
  }
  BaseLineFront = (int)(TempBaseLineFront / 100);
  TriggerFront = (int)(0.8*BaseLineFront);
  BaseLineBack = (int)(TempBaseLineBack / 100);
  TriggerBack = (int)(0.8*BaseLineBack);

  //Show that the initialisation is done: blink three times with the base line values
  writeNumber(TriggerFront, 500);
  delay(200);

  writeNumber(TriggerBack, 500);
  delay(200);
  
//  writeNumber(888, 500);
//  delay(200);
//  writeNumber(888, 500);
//  delay(200);
//  writeNumber(888, 500);
//  delay(200);
  
  measuringBack = 1; //start measuring and wait for the darts
}

void createDisplay(){
 Wire.beginTransmission(diaplayAddr);
 Wire.write(B00000000);  entgegen
                        // Subadressing: B00000001 = Digit 1, Subadressing: B00000010 = Digit 2, Subadressing: B00000011 = Digit 3, Subadressing: B00000100 = Digit 4
 Wire.write(B00110111); // control byte (dynamic modus on, 9 mA)
 Wire.endTransmission();
 
 Wire.beginTransmission(diaplayAddr);
 Wire.write(1); // instruction byte - first digit to control is 1 (right hand side)
 Wire.write(digitBytes[0]); // digit 1 (RHS)
 Wire.write(digitBytes[1]); // digit 2
 Wire.write(digitBytes[2]); // digit 3
 Wire.endTransmission();
 
 
 Wire.beginTransmission(diaplayAddr);
 Wire.write(1); // instruction byte - first digit to control is 1 (right hand side)
 Wire.write(digitBytes[9]); // digit 1 (RHS)
 Wire.write(digitBytes[0] + 128); // digit 2 + Dezimal point
 Wire.write(digitBytes[1]); // digit 3
 Wire.endTransmission(); 
}

void writeNumber(int number, int waitTime){
  // creat number and show it for waitTime ms 
  int digit1 = number/100;
  int digit2 = (number - (digit1*100)) / 10;
  int digit3 = number - digit1*100 - digit2*10;
  
  Serial.println(number);
  Serial.print("digit1: "); Serial.println(digit1);
  Serial.print("digit2: "); Serial.println(digit2);
  Serial.print("digit3: "); Serial.println(digit3);
  
  Wire.beginTransmission(diaplayAddr);
  Wire.write(1); // instruction byte - first digit to control is 1 (right hand side)
  Wire.write(digitBytes[digit3]); // digit 1 (RHS)
  Wire.write(digitBytes[digit2] + 128); // digit 2 + decimal point
  Wire.write(digitBytes[digit1]); // digit 3
  Wire.endTransmission();
  
  delay(waitTime);
  Wire.beginTransmission(diaplayAddr);
  Wire.write(1); // instruction byte - first digit to control is 1 (right hand side)
  Wire.write(0); // digit 1 (RHS)
  Wire.write(0); // digit 2 + decimal point
  Wire.write(0); // digit 3
  Wire.endTransmission();
}

void heartBeatBeat(){
  //lets the decimal point blink 
  Wire.beginTransmission(diaplayAddr);
  Wire.write(1); // instruction byte - first digit to control is 1 (right hand side)
  Wire.write(0); // digit 1 (RHS)
  Wire.write(128); // digit 2 + decimal point
  Wire.write(0); // digit 3
  Wire.endTransmission();
  
  delay(100);
  Wire.beginTransmission(diaplayAddr);
  Wire.write(1); // instruction byte - first digit to control is 1 (right hand side)
  Wire.write(0); // digit 1 (RHS)
  Wire.write(0); // digit 2 + decimal point
  Wire.write(0); // digit 3
  Wire.endTransmission();
}


void loop(){  
  //Hearbeat interval
  if (millis() > (heartBeat + 5000)){
    heartBeat = millis();
    heartBeatBeat();
  }
  
  //read the push button
  Taster.update();
  int TasterStatus = Taster.read();
  unsigned long duration = Taster.duration();
  if ((TasterStatus == HIGH) && (duration < 2000)){
    writeNumber((int)(meanVal*10/meanCount), 1000);
  }
  else if (TasterStatus == HIGH){
    Serial.println("reset");
    writeNumber(0, 500); delay(200);
    writeNumber(0, 500); delay(200);
    writeNumber(0, 500); delay(200);
    meanVal = 0;
    meanCount = 0;
    delay(500);
  }
  
  //delayMicroseconds(loopTime);
  //if (digitalRead(TriggerPin) == HIGH) { Serial.println("Trigger!"); }
  
  if (measuringBack == 1){
    //Pfeil wurde noch nicht detektiert
    LSBackVal = analogRead(LSBackPin);
    if (LSBackVal < TriggerBack) { measuringBack = 0; measureLoops = micros(); Serial.print("Start Trigger :"); Serial.println(TriggerBack); Serial.println(LSBackVal); }
  }
  else
  {
    //dart was detected, but didn't arrive in the front
    LSFrontVal = analogRead(LSFrontPin);
    if (LSFrontVal < TriggerFront){
      unsigned long stopTime=micros();
      float deltaTus = (float)(stopTime-measureLoops);
      deltaTus = deltaTus / 1.0e6;
      float mSpeed = length / deltaTus;
      measuringBack = 1; 
      
      Serial.println(measureLoops);
      Serial.println(stopTime);      
      Serial.println(deltaTus);
      Serial.println(mSpeed);
      
      meanCount = meanCount + 1;
      meanVal = meanVal + mSpeed;
      
      Serial.println(meanVal);
      Serial.println(meanCount);
      
      writeNumber((int)(mSpeed*10), 500);
      delay(200);
    }
  }
  
  
  //#Reset after 1 s
  if ((measuringBack == 0) && (micros() > (measureLoops + 1000000)))
  {
    measuringBack = 1;
  }
}
 

20 Comments

I would like to make a similar device to determine the requisite speed for a hypodermic needle to penetrate rather than indent a target vein (during central venous cannulation).
1. ¿Have you verified the accuracy of this system?
2. If so, ¿what method of verification did you use?
2. If accuracy has been determined, ¿over what range of speeds is this system accurate
(i.e., what is the precision, e.g. +/- 20%)?
3. ¿Do you think that using lasers as light sources might give more accurate results than LEDs?
4. ¿Do you have any idea how much precision will be lost if the light emitters are fairly close together?--
e.g. 1 cm apart.
Thank you
James Riopelle jriope@lsuhsc.edu

This is very cool, but I suggest you add a orange tip, as it is necessary to do so.

In some areas, police are trained to shoot first and then question, so just a warning.

Heya ! I got sent here from blasted.de and gotta admit I'm totally amazed. Brilliant design and super sweet integration.

I realized you were using a full size 5mm LED as IR emitter. There's more compact components for this purpose like the Osram IRL 81 A. Maybe worth taking a look if you plan to build something similar (like an integrated shot counter ...)

Hopefully I can stay focused on this hobby long enough to finish some projects myself. This will definitely be the blueprint for my speedometer !

You didn't have to put all the components inside you know. Perhaps wiring it to a box on top and integrate some optics so it looks cool.
this mod looks great. I do have one question tho. Does this more measure in feet per second or meters per second?

Ok thank you. I may have to change the coding around to measure in feet per second. I'll let everyone know how that turns out.

Yup! All of your projects are worth a vote!
Voted this is very clever of you

Awesome projects! So clean assembling, I love the way the display is well-combined to the barrel.

Thank you! Getting it to fit was the hardest part.

my dear u need to patent or copy right yr idea. asap as well. u can probably redo 4 live guns as well.

Really nice! This could come in handy! ;)