Arduino Target Shooter
This will be a guide to help anyone build a mini Target Shooting Range, without spending an absurd amount of money.
What I'll be covering in the tutorial are the basic steps to have fully working prototype, it's up to you to personalize it and making it more fun or difficult depending what you are looking for.
It's not extremely demanding in terms of coding, and the components that we'll be connecting are fairly simple to use separately, the challenge will be having everything working together.
Components & Tools
- 1 Arduino Board & Breadboard
- 4 AA Batteries + 1 Battery Case
- 1 9V Battery + 1 Battery Case
- 6 Photo Resistors
- 6 Servo Modules
- 1 Laser Module
- 6 Resistors
- Jump Wires
NB: This list is quite minimal and generalized, I know, but in return everything in this list can be modified as needed, with minimal change in terms of coding and execution.
Connect & Use a Servo
During this step, we'll make use of one Servo, the Arduino board and the 4 AA batteries.
The servo will be later used to rotate the targets to shot at, while the batteries will enable us to use more then one servo with a single Arduino board.
The Arduino board itself could control up to 12 servos, but it doesn't have enough power to make them all work simultaneously.
- Connecting a single Servo
As shown in the picture, will need to link the batteries hot and ground wire to the breadboard.
Then having the Servo drawing power from that circuit.
All that's left is connecting the Servo to one of the Arduino digital pin as well.
NB: Even though we are just going to use one servo I prepared the code to work for multiple servos since we'll need it later on in the project.
*As I stated in the introduction I personally used 4 AA batteries, since my Servos need such voltage, but be sure to check which voltage does your Servo need to work properly, otherwise you'll risk to fry it before even starting the project
- Output a command to the Servo
#include <Servo.h> //define total servos #define TOT_TARGETS 1 //define servos rotation state #define UP_STATE 0 #define DOWN_STATE 90 #define LIT_LIMIT 30 //create servo objects to control Servo Targets[TOT_TARGETS]; int TargetTimer[TOT_TARGETS]; int TargetState[TOT_TARGETS]; //set the reaction time depending how many target it controls int ReactionTime = 5000/TOT_TARGETS; void setup() { //attaches the servos from pin 2 onwards & reset their rotation for (int TargetNum = 0; TargetNum < TOT_TARGETS; TargetNum++) { Targets[TargetNum].attach(TargetNum + 2); TargetState[TargetNum] = DOWN_STATE; } } void loop() { //for each servo for (int TargetNum = 0; TargetNum < TOT_TARGETS; TargetNum++) { //if timeout limit is passed change rotation if (TargetTimer[TargetNum] > ReactionTime) { TargetState[TargetNum] = UP_STATE; TargetTimer[TargetNum] = 0; } //if timeout limit is passed change rotation if (TargetTimer[TargetNum] < -ReactionTime) { TargetState[TargetNum] = DOWN_STATE; TargetTimer[TargetNum] = 0; } //depending on the servo state increase/decrease counter if (TargetState[TargetNum] == DOWN_STATE) { TargetTimer[TargetNum]++; } //depending on the servo state increase/decrease counter if (TargetState[TargetNum] == UP_STATE) { TargetTimer[TargetNum]--; } //change to current state Targets[TargetNum].write(TargetState[TargetNum]); } }
Photoresitor & Laser "Combo"
Making a laser emitter work is fairly easy, all we need to do is connecting vcc and ground wire to a power supply, making the Photoresistor receive the laser light and act accordingly is a little bit more tricky.
What I meant with tricky is that, in an ideal environment, any sensor will output an exact reading value, but since most of times we have external "noises", our results will rarely be perfectly the same or very steady.
Having said that, what I did to fix this issue is using an average of the Photoresistor outputs when lit by the laser at different times, decrease that average value by 25% and use that result as trigger for the targets.
Obviously this is a cheap trick that would work in our project, simply because thanks to the laser, the Photoresistor will output an abnormal spike over the ambient lighting. But that's all we need for now.
This is the Arduino code to use the Servo as explained in the previous step with the new readings from the sensor.
NB: To be able to use multiple servos using my code snippet, all that needs to be done is increasing the number of defined servos, and add the correspondent analog pin.
#include <Servo.h> //define total servos #define TOT_TARGETS 1 //#define TOT_TARGETS 6 //define servos rotation state #define UP_STATE 0 #define DOWN_STATE 90 #define LIT_LIMIT 30 //create servo objects to control Servo Targets[TOT_TARGETS]; int TargetTimer[TOT_TARGETS]; int TargetState[TOT_TARGETS]; //enable analog reading from photoresistors int TargetSensor[] = {A0}; //int TargetSensor[] = {A0,A1,A2,A3,A4,A5}; //set the reaction time depending how many target it controls int ReactionTime = 5000/TOT_TARGETS; void setup() { //attaches the servos from pin 2 onwards & reset their rotation for (int TargetNum = 0; TargetNum < TOT_TARGETS; TargetNum++) { Targets[TargetNum].attach(TargetNum + 2); TargetState[TargetNum] = DOWN_STATE; } } void loop() { //for each servo for (int TargetNum = 0; TargetNum < TOT_TARGETS; TargetNum++) { //convert sensor output value int LitValue = map(analogRead(TargetSensor[TargetNum]), 0, 1023, 0, 255); //if lit reset rotation if (LitValue > LIT_LIMIT) { TargetState[TargetNum] = DOWN_STATE; TargetTimer[TargetNum] = 0; } //if timeout limit is passed change rotation if (TargetTimer[TargetNum] > ReactionTime) { TargetState[TargetNum] = UP_STATE; TargetTimer[TargetNum] = 0; } //if timeout limit is passed change rotation if (TargetTimer[TargetNum] < -ReactionTime) { TargetState[TargetNum] = DOWN_STATE; TargetTimer[TargetNum] = 0; } //depending on the servo state increase/decrease counter if (TargetState[TargetNum] == DOWN_STATE) { TargetTimer[TargetNum]++; } //depending on the servo state increase/decrease counter if (TargetState[TargetNum] == UP_STATE) { TargetTimer[TargetNum]--; } //change to current state Targets[TargetNum].write(TargetState[TargetNum]); } }
Wrap Everything Together
This steps simply require you to put together everything we worked on so far separately.
That means having all servos receiving commands from the Arduino board and reacting accordingly to the light sensors.
Mounting the Box/Targets/Pistol
During this step we will leave aside the Arduino, since all that's left to built are the actual Chassis/Box, Targets and the Pistol.
To build the Box we need a blueprint that will suit our needs, made from sheets of the preferred material (in my case foam), and glue.
The Targets will be made by rectangular sections cut out from the material sheets, each of them will need 2 holes, that will allow sensors to be inserted.
Targets will also need a correspondent servo to be attached to its side (glue will do just fine).
To lastly make a simple Pistol, we can either 3D print our personal design or buy a cheap one.
NB: The Pistol design might be different for each project, but the way the laser circuit works stay the same.
At this point of the project, you should have a fully working prototype which you can now fully personalize and customize with your own graphics and decals.
End/Conclusions
Many thanks for whoever decided to follow this guide, and please do let me know if you think I should change something regarding the project and such. This is not a complete Tutorial yet, but if you have any problem following the current steps do not hesitate and let me know commenting this Instructable.