Introduction: Sentriduino! Its the All New Sentry Turret Made of Recycled Things You Would Find Around Your House!
Hey guys, Today I would like to show you how to make a simple sentry turret out of household Items! You would only need to get an Arduino UNO or Mega, a Ping))) Ultrasonic Range finder, two servos, and an electronic water squinter! The rest of the project is things that you may find around your house and recycle!
Contest Age Group 13 - 17
Contest Age Group 13 - 17
Step 1: Supplies!
Laundry detergent bottle (E.G. Tide...)
Laundry Detergent Cap (of the detergent bottle)
Tin Can (E.G. Evaporated Milk, Beans...)
Tape
Screws
Some sort of a flat building Material (E.G. Cardboard, Poly Carbonate sheets...)
Arduino UNO or Mega
Wires
an extra RC cable Connector
1 180º Servo Motor
1 Servo motor you can rip apart
1 Electric water squirter
Ping))) Ultrasonic Range Finder
Laundry Detergent Cap (of the detergent bottle)
Tin Can (E.G. Evaporated Milk, Beans...)
Tape
Screws
Some sort of a flat building Material (E.G. Cardboard, Poly Carbonate sheets...)
Arduino UNO or Mega
Wires
an extra RC cable Connector
1 180º Servo Motor
1 Servo motor you can rip apart
1 Electric water squirter
Ping))) Ultrasonic Range Finder
Step 2: Step 1: Making the Turret Turn.
First you will need your Laundry Detergent Cap. Cut 2 parallel slits to fit a piece of your building material through to hold up the water gun. Next make two holes so that your servo can be connected to the turning piece. Now screw the Servo to the platform. You should now have a place to put your gun, on top.
Step 3: Step 2: Making the Electric Water Gun Work.
First grab the servo you are willing to rip apart. Unscrew it and take out the electronics, before cutting the motor off of the old servo, be sure to remember where the motor was. Next take out your soldering iron and solder the two wires of the motor of the water squirter to where the old motor was. If your servo is either continuous or wont start, ajust the potentiometer until the squirter works accordingly.
Step 4: Step 3: Attaching the Gun.
All you really have to do for this step is securely tape the gun onto the top of the detergent cap.
Step 5: Step 4: Making a Secondary Base.
Now this is the hardest step, so read carefully (I would read this whole step before actually doing it.). First Grab the Tin can. Next grab some polycarbonate or whatever you are using as a material, and make it into a circle right on top of your can, I melted mine into a circle. Next after getting your circle, make a hole in it that the servo can fit in and make two holes for their screws too. Put the servo in and screw it to the circular platform. Get your tin can again and glue it onto the top of the tin can. Now you should have your secondary base.
Step 6: Step 5: Main Base
Now get your big detergent container, and make a hole in the area that the little press nozzle is, make it big enough so that the can can be put there. Now before putting the can in, make a hole in the can and grab the servo motor's cable, you will need to connect that to the Arduino later. after getting the cable, glue the can to the detergent container.
Step 7: Step 6: Wiring Up.
First get the extra RC cable connector and plug it into the Ping))) Ultrasonic Range Finder. Wire the Ping From GND>GND, From 5V>5V, and From Sig>Arduino's pin 6. Next wire the Turner servo. The wiring will be From Red wire>5V, From Black wire>GND, and From White/Yellow/(any color but black or red)>Arduino's pin 9. The squirter servo's wire connects From Black>GND, From Red>5V, and From White/Yellow/(any color but black or red)>Arduino's pin 10. Last and the most important, connect the programming cable to the computer.
Step 8: Step 7: the Program.
There are two different codes, I personally like algorithm 2 better. algorithm 1 Sort-of works, you can modify it for your own use.
// algorithm 1
#include <Servo.h>
int map_table[140][14];
int tablex = 0;
int tabley = 0;
int cm2 = 1; //set to 1 if you want measurements in cm, 0 if inches.
Servo myservo; // create servo object to control a servo (axis)
Servo myservo2; // create servo object to control a servo (squirt gun)
// a maximum of eight servo objects can be created
const int MeasureOutput = 6; // Ping))) pin
int range = 80; //range
int pos = 0; // variable to store the servo position
int sweep = 1;
void setup()
{
Serial.begin(9600);
myservo.attach(9); // attaches the servo on pin 9 to the servo object
myservo2.attach(10); // attaches the servo on pin 10 to the servo object
}
void loop()
{
if (sweep == 1)
{
for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
map(pos);
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
for(pos = 180; pos>1; pos-=1) // goes from 180 degrees to 0 degrees
{
myservo.write(pos); // tell servo to go to position in variable 'pos'
// map();
delay(15); // waits 15ms for the servo to reach the position
}
sweep = 2;
}
if (sweep == 2) {
for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
measure(pos);
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
for(pos = 180; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees
{
measure(pos);
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
}
}
void measure(int number)
{
long duration, inches, cm;
pinMode(MeasureOutput, OUTPUT);
digitalWrite(MeasureOutput, LOW);
delayMicroseconds(2);
digitalWrite(MeasureOutput, HIGH);
delayMicroseconds(5);
digitalWrite(MeasureOutput, LOW);
pinMode(MeasureOutput, INPUT);
duration = pulseIn(MeasureOutput, HIGH);
cm = microsecondsToCentimeters(duration);
inches = microsecondsToInches(duration);
convert_to_1D_number(number);
if (cm2 == 1)
{
if (cm < map_table[tablex][tabley] - 10 && range < cm) {
sweep = 3;
attack(cm);
}
if (cm > map_table[tablex][tabley]) {
map_table[tablex][tabley] = cm;
}
}
else {
}
}
void attack(int org)
{
myservo.attach(9);
int pos2;
for(pos2 = pos; pos < 180; pos += 1)
{
Serial.println("attack!");
// pos++;
delay(15);
target(pos, org);
myservo.write(pos);
myservo2.write(100);
}
for(pos2 = pos; pos > 1; pos -= 1)
{
Serial.println("attack!");
// pos++;
delay(15);
target(pos, org);
myservo.write(pos);
myservo2.write(100);
}
sweep = 2;
}
void left(int org)
{
Serial.println("attackL!");
pos--;
delay(15);
myservo.attach(9);
target(pos, org);
myservo.write(pos);
}
void right(int org)
{
Serial.println("attackR!");
pos++;
delay(15);
myservo.attach(9);
target(pos, org);
myservo.write(pos);
// myservo2.write(100);
}
void target(int number, int org)
{
long duration, inches, cm;
pinMode(MeasureOutput, OUTPUT);
digitalWrite(MeasureOutput, LOW);
delayMicroseconds(2);
digitalWrite(MeasureOutput, HIGH);
delayMicroseconds(5);
digitalWrite(MeasureOutput, LOW);
pinMode(MeasureOutput, INPUT);
duration = pulseIn(MeasureOutput, HIGH);
cm = microsecondsToCentimeters(duration);
inches = microsecondsToInches(duration);
convert_to_1D_number(number);
if (cm2 == 1)
{
if (map_table[tablex][tabley] < range) {
if (cm < map_table[tablex][tabley]/2) {
right(org);
}
if (cm < map_table[tablex][tabley]) {
left(org);
}
}
else {
if (cm < map_table[tablex][tabley]-10 && range < cm) {
right(org);
}
if (cm < map_table[tablex][tabley]-10 && range > cm) {
left(org);
}
}
if (cm > map_table[tablex][tabley]) {
map_table[tablex][tabley] = cm;
}
}
else {
}
}
void map(int number)
{
long duration, inches, cm;
pinMode(MeasureOutput, OUTPUT);
digitalWrite(MeasureOutput, LOW);
delayMicroseconds(2);
digitalWrite(MeasureOutput, HIGH);
delayMicroseconds(5);
digitalWrite(MeasureOutput, LOW);
pinMode(MeasureOutput, INPUT);
duration = pulseIn(MeasureOutput, HIGH);
inches = microsecondsToInches(duration);
cm = microsecondsToCentimeters(duration);
convert_to_1D_number(number);
if (cm2 == 1)
{
map_table[tablex][tabley] = cm;
}
else {
map_table[tablex][tabley] = inches;
}
Serial.println(map_table[tablex][tabley]);
Serial.print(", ");
Serial.print(number);
}
void convert_to_1D_number(int number)
{
tablex = ((number % 14) + 1);
tabley = number / 14;
}
long microsecondsToInches(long microseconds)
{
// According to Parallax's datasheet for the PING))), there are
// 73.746 microseconds per inch (i.e. sound travels at 1130 feet per
// second). This gives the distance travelled by the ping, outbound
// and return, so we divide by 2 to get the distance of the obstacle.
// See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
return microseconds / 74 / 2;
}
long microsecondsToCentimeters(long microseconds)
{
// The speed of sound is 340 m/s or 29 microseconds per centimeter.
// The ping travels out and back, so to find the distance of the
// object we take half of the distance travelled.
return microseconds / 29 / 2;
}
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// algorithm 2
#include <Servo.h>
Servo myservo; // create servo object to control a servo
Servo myservo2; // a maximum of eight servo objects can be created
int dist = 80;
int direction = 1;
// Variables will change:
int ledState = LOW; // ledState used to set the LED
long previousMillis = 0; // will store last time LED was updated
// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 1000; // interval at which to blink (milliseconds)
int squirt = 0;
int pos = 0; // variable to store the servo position
const int MeasureOutput = 6;
int currentMillis = 0;
void setup()
{
Serial.begin(9600);
myservo.attach(9); // attaches the servo on pin 9 to the servo object
// myservo2.attach(10);
// myservo2.write(147);
}
void loop()
{
Serial.println(squirt);
// Serial.println(currentMillis);
if(currentMillis - previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
if (ledState == LOW && squirt == 1) {
ledState = HIGH;
myservo2.attach(10);
myservo2.write(155);
delay(120);
squirt = 0;
}
if (ledState == HIGH && squirt == 0) {
ledState = LOW;
myservo2.detach(); }
}
digitalWrite(13, ledState);
delay(1);
scan();
delay(14);
currentMillis = currentMillis + 15;
//digitalWrite(10, LOW);
}
void scan()
{
long duration, inches, cm;
pinMode(MeasureOutput, OUTPUT);
digitalWrite(MeasureOutput, LOW);
delayMicroseconds(2);
digitalWrite(MeasureOutput, HIGH);
delayMicroseconds(5);
digitalWrite(MeasureOutput, LOW);
pinMode(MeasureOutput, INPUT);
duration = pulseIn(MeasureOutput, HIGH);
cm = microsecondsToCentimeters(duration);
inches = microsecondsToInches(duration);
if (dist >= cm) {
left();
}
if (dist < cm) {
right();
}
if (dist > cm) {
// myservo2.attach(10);
squirt = 1;
// myservo2.detach();
}
}
void left() {
if (direction == 1)
{
pos--;
myservo.write(pos);
if (pos < 1) {
direction = 0;
}
}
if (direction == 0)
{
pos++;
myservo.write(pos);
if (pos > 150) {
direction = 1;
}
}
}
void right() {
if (direction == 1)
{
pos++;
// myservo2.attach(10);
myservo.write(pos);
myservo.write(pos);
if (pos > 150) {
direction = 0;
}
}
if (direction == 0)
{
pos--;
// myservo2.attach(10);
myservo.write(pos);
// myservo2.write(155); // set servo to mid-point
// delay(15);
// myservo2.detach();
myservo.write(pos);
if (pos < 1) {
direction = 1;
}
}
}
long microsecondsToInches(long microseconds)
{
// According to Parallax's datasheet for the PING))), there are
// 73.746 microseconds per inch (i.e. sound travels at 1130 feet per
// second). This gives the distance travelled by the ping, outbound
// and return, so we divide by 2 to get the distance of the obstacle.
// See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
return microseconds / 74 / 2;
}
long microsecondsToCentimeters(long microseconds)
{
// The speed of sound is 340 m/s or 29 microseconds per centimeter.
// The ping travels out and back, so to find the distance of the
// object we take half of the distance travelled.
return microseconds / 29 / 2;
}
// algorithm 1
#include <Servo.h>
int map_table[140][14];
int tablex = 0;
int tabley = 0;
int cm2 = 1; //set to 1 if you want measurements in cm, 0 if inches.
Servo myservo; // create servo object to control a servo (axis)
Servo myservo2; // create servo object to control a servo (squirt gun)
// a maximum of eight servo objects can be created
const int MeasureOutput = 6; // Ping))) pin
int range = 80; //range
int pos = 0; // variable to store the servo position
int sweep = 1;
void setup()
{
Serial.begin(9600);
myservo.attach(9); // attaches the servo on pin 9 to the servo object
myservo2.attach(10); // attaches the servo on pin 10 to the servo object
}
void loop()
{
if (sweep == 1)
{
for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
map(pos);
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
for(pos = 180; pos>1; pos-=1) // goes from 180 degrees to 0 degrees
{
myservo.write(pos); // tell servo to go to position in variable 'pos'
// map();
delay(15); // waits 15ms for the servo to reach the position
}
sweep = 2;
}
if (sweep == 2) {
for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
measure(pos);
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
for(pos = 180; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees
{
measure(pos);
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
}
}
void measure(int number)
{
long duration, inches, cm;
pinMode(MeasureOutput, OUTPUT);
digitalWrite(MeasureOutput, LOW);
delayMicroseconds(2);
digitalWrite(MeasureOutput, HIGH);
delayMicroseconds(5);
digitalWrite(MeasureOutput, LOW);
pinMode(MeasureOutput, INPUT);
duration = pulseIn(MeasureOutput, HIGH);
cm = microsecondsToCentimeters(duration);
inches = microsecondsToInches(duration);
convert_to_1D_number(number);
if (cm2 == 1)
{
if (cm < map_table[tablex][tabley] - 10 && range < cm) {
sweep = 3;
attack(cm);
}
if (cm > map_table[tablex][tabley]) {
map_table[tablex][tabley] = cm;
}
}
else {
}
}
void attack(int org)
{
myservo.attach(9);
int pos2;
for(pos2 = pos; pos < 180; pos += 1)
{
Serial.println("attack!");
// pos++;
delay(15);
target(pos, org);
myservo.write(pos);
myservo2.write(100);
}
for(pos2 = pos; pos > 1; pos -= 1)
{
Serial.println("attack!");
// pos++;
delay(15);
target(pos, org);
myservo.write(pos);
myservo2.write(100);
}
sweep = 2;
}
void left(int org)
{
Serial.println("attackL!");
pos--;
delay(15);
myservo.attach(9);
target(pos, org);
myservo.write(pos);
}
void right(int org)
{
Serial.println("attackR!");
pos++;
delay(15);
myservo.attach(9);
target(pos, org);
myservo.write(pos);
// myservo2.write(100);
}
void target(int number, int org)
{
long duration, inches, cm;
pinMode(MeasureOutput, OUTPUT);
digitalWrite(MeasureOutput, LOW);
delayMicroseconds(2);
digitalWrite(MeasureOutput, HIGH);
delayMicroseconds(5);
digitalWrite(MeasureOutput, LOW);
pinMode(MeasureOutput, INPUT);
duration = pulseIn(MeasureOutput, HIGH);
cm = microsecondsToCentimeters(duration);
inches = microsecondsToInches(duration);
convert_to_1D_number(number);
if (cm2 == 1)
{
if (map_table[tablex][tabley] < range) {
if (cm < map_table[tablex][tabley]/2) {
right(org);
}
if (cm < map_table[tablex][tabley]) {
left(org);
}
}
else {
if (cm < map_table[tablex][tabley]-10 && range < cm) {
right(org);
}
if (cm < map_table[tablex][tabley]-10 && range > cm) {
left(org);
}
}
if (cm > map_table[tablex][tabley]) {
map_table[tablex][tabley] = cm;
}
}
else {
}
}
void map(int number)
{
long duration, inches, cm;
pinMode(MeasureOutput, OUTPUT);
digitalWrite(MeasureOutput, LOW);
delayMicroseconds(2);
digitalWrite(MeasureOutput, HIGH);
delayMicroseconds(5);
digitalWrite(MeasureOutput, LOW);
pinMode(MeasureOutput, INPUT);
duration = pulseIn(MeasureOutput, HIGH);
inches = microsecondsToInches(duration);
cm = microsecondsToCentimeters(duration);
convert_to_1D_number(number);
if (cm2 == 1)
{
map_table[tablex][tabley] = cm;
}
else {
map_table[tablex][tabley] = inches;
}
Serial.println(map_table[tablex][tabley]);
Serial.print(", ");
Serial.print(number);
}
void convert_to_1D_number(int number)
{
tablex = ((number % 14) + 1);
tabley = number / 14;
}
long microsecondsToInches(long microseconds)
{
// According to Parallax's datasheet for the PING))), there are
// 73.746 microseconds per inch (i.e. sound travels at 1130 feet per
// second). This gives the distance travelled by the ping, outbound
// and return, so we divide by 2 to get the distance of the obstacle.
// See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
return microseconds / 74 / 2;
}
long microsecondsToCentimeters(long microseconds)
{
// The speed of sound is 340 m/s or 29 microseconds per centimeter.
// The ping travels out and back, so to find the distance of the
// object we take half of the distance travelled.
return microseconds / 29 / 2;
}
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// algorithm 2
#include <Servo.h>
Servo myservo; // create servo object to control a servo
Servo myservo2; // a maximum of eight servo objects can be created
int dist = 80;
int direction = 1;
// Variables will change:
int ledState = LOW; // ledState used to set the LED
long previousMillis = 0; // will store last time LED was updated
// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 1000; // interval at which to blink (milliseconds)
int squirt = 0;
int pos = 0; // variable to store the servo position
const int MeasureOutput = 6;
int currentMillis = 0;
void setup()
{
Serial.begin(9600);
myservo.attach(9); // attaches the servo on pin 9 to the servo object
// myservo2.attach(10);
// myservo2.write(147);
}
void loop()
{
Serial.println(squirt);
// Serial.println(currentMillis);
if(currentMillis - previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
if (ledState == LOW && squirt == 1) {
ledState = HIGH;
myservo2.attach(10);
myservo2.write(155);
delay(120);
squirt = 0;
}
if (ledState == HIGH && squirt == 0) {
ledState = LOW;
myservo2.detach(); }
}
digitalWrite(13, ledState);
delay(1);
scan();
delay(14);
currentMillis = currentMillis + 15;
//digitalWrite(10, LOW);
}
void scan()
{
long duration, inches, cm;
pinMode(MeasureOutput, OUTPUT);
digitalWrite(MeasureOutput, LOW);
delayMicroseconds(2);
digitalWrite(MeasureOutput, HIGH);
delayMicroseconds(5);
digitalWrite(MeasureOutput, LOW);
pinMode(MeasureOutput, INPUT);
duration = pulseIn(MeasureOutput, HIGH);
cm = microsecondsToCentimeters(duration);
inches = microsecondsToInches(duration);
if (dist >= cm) {
left();
}
if (dist < cm) {
right();
}
if (dist > cm) {
// myservo2.attach(10);
squirt = 1;
// myservo2.detach();
}
}
void left() {
if (direction == 1)
{
pos--;
myservo.write(pos);
if (pos < 1) {
direction = 0;
}
}
if (direction == 0)
{
pos++;
myservo.write(pos);
if (pos > 150) {
direction = 1;
}
}
}
void right() {
if (direction == 1)
{
pos++;
// myservo2.attach(10);
myservo.write(pos);
myservo.write(pos);
if (pos > 150) {
direction = 0;
}
}
if (direction == 0)
{
pos--;
// myservo2.attach(10);
myservo.write(pos);
// myservo2.write(155); // set servo to mid-point
// delay(15);
// myservo2.detach();
myservo.write(pos);
if (pos < 1) {
direction = 1;
}
}
}
long microsecondsToInches(long microseconds)
{
// According to Parallax's datasheet for the PING))), there are
// 73.746 microseconds per inch (i.e. sound travels at 1130 feet per
// second). This gives the distance travelled by the ping, outbound
// and return, so we divide by 2 to get the distance of the obstacle.
// See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
return microseconds / 74 / 2;
}
long microsecondsToCentimeters(long microseconds)
{
// The speed of sound is 340 m/s or 29 microseconds per centimeter.
// The ping travels out and back, so to find the distance of the
// object we take half of the distance travelled.
return microseconds / 29 / 2;
}
Step 9: Step 8: Completion!
Congratz you have now completed a Sentriduino and can show it off to your friends, feel free to post comments on it, I would be happy to help reply and hear about your experience with the Sentriduino! Thanks for reading and spending your time. Thanks again, Simon.
PS: If your Sentriduino is not too stable and falls over, just fill your detergent container partially with water, Thanks again.
PS: If your Sentriduino is not too stable and falls over, just fill your detergent container partially with water, Thanks again.