Measure the Speed of Nerf Darts
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.
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
- 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.
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.
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:
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
Black-Jack 5 years ago
JamesR447 6 years ago
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
playgameonlineforever 7 years ago
Can I buy one from you?
IssacK 8 years ago
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.
EpicMinecrafter870 9 years ago
EpicMinecrafter870 9 years ago
PhilippK1 9 years ago
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 !
EpicMinecrafter870 9 years ago
Fostis 10 years ago
BrittLiv 10 years ago
Hi, in m/s
Fostis 10 years ago
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.
nerfrocketeer 10 years ago
BrittLiv 10 years ago
Thank you!
nerfrocketeer 10 years ago
dogilvy 10 years ago
BrittLiv 10 years ago
Thank you!
andrea biffi 10 years ago
Awesome projects! So clean assembling, I love the way the display is well-combined to the barrel.
BrittLiv 10 years ago
Thank you! Getting it to fit was the hardest part.
astral_mage 10 years ago
my dear u need to patent or copy right yr idea. asap as well. u can probably redo 4 live guns as well.
nerfrocketeer 10 years ago