DIY ROV The Unsinkable 2

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 9

instructables

DIY ROV: the Unsinkable #2

by drich1996

An underwater ROV or remotely operated vehicle is a performing other underwater nonsense tasks. Along
tethered underwater mobile device that can be with the arm i added a dredge pump to remove small
controlled by an operator on the surface. They are layers of silt on an object or possibly suction up small
mostly used for marine salvage and recovery objects into a sediment trap. I also attempted to make
operations where sending a diver would be to the design as low cost and efficient as possible using
hazardous or difficult to do. They can also perform off the shelf arduino mega shields and components.
underwater surveying and other similar commercial Unlike most underwater motors, the ones used in this
operations. Now this ROV design isn't a million dollar design will not cost you an arm and a leg (just as long
commercial grade version like most, but for locating as you have access too a metal lathe). A lot of my
lost objects in lakes in rivers, it'll do the job just fine. ideas also came from The ROV Manual, Second
Although this design isn't 100% complete, its proof of Edition: A User Guide for Remotely Operated
concept that it'd perform as advertised is complete. I Vehicles, which is a wealth of knowledge on the topic
designed the ROV in Fusion 360 from its remote all of ROVs and can help you out alot.
the way down to its propeller shafts. I wanted this
submersible to not just be an eye below the surface, https://www.amazon.com/gp/product/0080982883/ref
but an object retriever and dredger. So i incorporated =o...
a 6 axis robotic arm for retrieving objects and

Step 1: Remote Design

DIY ROV: the Unsinkable #2: Page 1


I started off by purchasing a 11.4" x 8.3" x 3.1" Plastic links for purchase on amazon at the end), i then
Enclosure Project Case off amazon (ill include the began to lay it out in autodesk fusion 360 till i had the

DIY ROV: the Unsinkable #2: Page 2


general layout of how i wanted the remote to look like. //Variables int flag=0;//Store buttonA condition 0:1st
I then printed out the DFX file to scale and taped it to display mode / 1: 2nd display mode int i=1; //Store
the top of the project box. Once it was laid out as my buttonB condition 1: light on / 0: light off
template i began to cut out the holes with a dremel
and drill. void setup() { delay(10000); //The 10 second delay to
upload new programs. Serial.begin(9600); //Begin
I then mounted the components in their spots and Serial to talk to the Serial Monitor
began to plan out their wiring. Serial1.begin(9600); //Begin Serial to talk to the Slave
Arduino Serial.println("Serial Monitor Connected");
Wiring was a bit more complicated, i used cat5 cable Serial.parseInt(); //clear any garbage in the buffer.
to help with wire management and keep everything
together but its still kind of a work in progress, 2hrs of pinMode(lcdLight, OUTPUT); // lcd led
soldering and redesigning l finally had a successful compass.begin(); Wire.begin(); display.begin();
layout. display.setContrast(30); //Print a welcome message
in startup for 6sec.////////// digitalWrite(lcdLight,HIGH);
For the compass LCD i used someone elses display.clearDisplay(); // clears the screen and buffer
instructable for a reference and combined it with my display.setTextColor(BLACK); display.setCursor(0,2);
own code to incorporate it in the remote. display.print(" ROV "); display.setCursor(0,13);
https://www.instructables.com/id/Arduino-Digital-M... display.print(" Compass "); display.setCursor(0,23);
display.print(" "); display.setCursor(0,33);
Code: display.print(" Derrico Industries"); display.display(); //
show splashscreen digitalWrite(lcdLight,HIGH);
*/ delay(10000); /////////////////////////////////////////////////////////
display.clearDisplay(); // clears the screen and buffer}
const int potpin1 = 1; const int potpin = 0; // analog
pin used to connect the potentiometer int pan = 0; // void loop() { //Read the flex sensor. We'll keep this
variable to read the value from the analog pin int tilt = value raw. pan = analogRead(potpin);// reads the
1; //Include libraries #include #include #include value of the potentiometer(value between 0 and
#include #include #include #include 1023) tilt = analogRead(potpin1); Serial1.println(pan);
//Send the potentiometer value to the Slave Arduino
//Init Display (SCLK, DIN, D/C, CS, RST) Serial1.println(tilt); // keep an ear out for messages
Adafruit_PCD8544 display = Adafruit_PCD8544(7, 6, back from the Slave. You know // complaints and the
5, 4, 3); //Init HMC5883L sensor like. delay(10); //This delay is added to give the Slave
Adafruit_HMC5883_Unified compass = a chance to //return data
Adafruit_HMC5883_Unified(12345);
if(Serial1.available()) //while there is data available {
//Constants const int lcdLight = 13; //BL pin of LCD to delay(10); //This delay is added to give the Slave a
arduino pin 13 (BL = Back Light) Button buttonA = chance to //return data } //if buttonB is pressed, 'flag'
Button(2,PULLUP); //Button to turn on/off display light will change between 0 and 1 if(buttonB.isPressed()){
Button buttonB = Button(8,PULLUP); //Button for delay(100);//small delay if(flag==0){ flag=1; } else{
changing display mode // For 1st display mode: static flag=0; } } //if buttonA is pressed, 'i' will change
unsigned char Leters[] = { 'N' , 'E' , 'S' , 'W' }; between 0 and 1 if(buttonA.isPressed()){ if(i==0){ i=1;
} else{ i=0; } } //if i is equal with 0, set display light on,
const static unsigned char PROGMEM arrow_bmp[] else set display light off if (i==0){
= { B00100000, B00100000, B01110000, digitalWrite(lcdLight,HIGH);} else{
B01110000, B11111000}; // For 2nd display mode: int digitalWrite(lcdLight,LOW); } //Reading and calculate
r = 24; // radius of compass rose int x0= 60; // x-origin degrees: ///////////////////////////////////// //Get new sensor
int y0= 24; // y-origin value every time that loop starting again
sensors_event_t event; compass.getEvent(&event);

DIY ROV: the Unsinkable #2: Page 3


//Variable heading stores value in radians float Mode void DrawRow(int angle) {
heading = atan2(event.magnetic.y, event.magnetic.x);
// Once you have your heading, you must then add display.drawLine(0, 0, 84, 0, BLACK);
your 'Declination Angle', which is the 'Error' of the display.drawLine(0, 1, 84, 1, BLACK);
compassnetic field in your location. // Find yours here:
http://www.compassnetic-declination.com/ // Mine is: - display.drawLine(0, 22, 91, 22, BLACK);
13* 2' W, which is ~13 Degrees, or (which we need) display.drawLine(0, 23, 95, 23, BLACK);
0.22 radians float declinationAngle = 0.22; //<-- display.setTextSize(2); display.setTextColor(BLACK);
Change 0.22 with yours. If you can't find your int start = 42 - angle / 3 ; if (start > 120) start += -120 ;
declination juct delete those lines ;) heading +=
declinationAngle; // Correct for when signs are int x = 0 ; int y = 18 ; for (int i=0; i<4; i++) { x = start +
reversed. if(heading < 0) heading += 2*PI; // Check (i*30) -1; if (x>119) x += -120; display.drawPixel(x+1,
for wrap due to addition of declination. if(heading > y-2, 1); display.drawPixel(x, y, 1);
2*PI)heading -= 2*PI; // Convert radians to degrees display.drawPixel(x+1, y, 1); display.drawPixel(x+2,
for readability. float headingDegrees = heading * y, 1); display.drawPixel(x, y-1, 1);
180/M_PI; //Convert float to int int angle= display.drawPixel(x+1, y-1, 1); display.drawPixel(x+2,
(int)headingDegrees; y-1, 1); display.setCursor((x-4),(y-16));
////////////////////////////////////////////////////////////////////////// display.write(Leters[i]); } for (int i=0; i<24; i++) { x =
start + (i*5) -1; if (x>119) x += -120;
display.clearDisplay(); // Just in case... //if flag is display.drawPixel(x+1, y+1, 1); display.drawPixel(x,
equal with 0 - 1st Display Mode if (flag==0){ y+2, 1); display.drawPixel(x+1, y+2, 1);
DrawRow(angle); //call DrawRow function display.drawPixel(x+2, y+2, 1); display.drawPixel(x,
display.drawBitmap(40, 24, arrow_bmp, 5, 5, 1); y+3, 1); display.drawPixel(x+1, y+3, 1);
display.drawLine(42, 0, 42, 24, BLACK); display.drawPixel(x+2, y+3, 1); }; for (int i=0; i<8; i++)
display.setCursor(32,34); display.print(angle); { x = start + (i*15)-1; if (x>119) x += -120;
display.setTextSize(1); display.print("o"); display.drawPixel(x+1, y-1, 1);
display.display(); delay(500); //print new value every
0.5sec } //if flag is equal with 1 - 2nd Display Mode if display.drawPixel(x, y, 1); display.drawPixel(x+1, y,
(flag==1){ // Calculation of compass needle on lcd 1); display.drawPixel(x+2, y, 1); display.drawPixel(x,
pointing to the direction DrawCircle(angle); //call y+1, 1); display.drawPixel(x+1, y+1, 1);
DrawCircle function // Display actual heading display.drawPixel(x+2, y+1, 1);
display.setTextSize(2); display.setTextColor(BLACK);
display.setCursor(0,0); display.println(angle); }; }
display.setTextSize(1); display.setTextColor(BLACK);
display.setCursor(x0-2,0); display.println("N"); ////Draw circle and print letters to display - 1st Display
display.setTextSize(1); display.setTextColor(BLACK); Mode void DrawCircle(int angle) { if (angle >= 0 &&
display.setCursor((x0+r)-5,y0-3); display.println("E"); angle <=45) { // 0-45 degrees int angle = angle/2;
display.setTextSize(1); display.setTextColor(BLACK); display.drawLine(x0, y0, x0+angle, y0-r, BLACK); }
display.setCursor(x0-2,y0+r-8); display.println("S"); else if (angle >45 && angle <=90) {// 46-90 degrees
display.setTextSize(1); display.setTextColor(BLACK); int angle = (angle-44)/2 ; display.drawLine(x0, y0,
display.setCursor((x0-r)+5,y0-3); display.println("W"); x0+r, (y0-r)+angle, BLACK); } else if (angle >90 &&
// Triangle for direction display.drawTriangle(0, 46, 20, angle <=135) {// 91-135 degrees int angle = (angle-
46, 10, 18, BLACK); display.fillTriangle (0, 46, 20, 46, 90)/2; display.drawLine(x0, y0, x0+r, y0+angle,
10, 18, BLACK); display.display(); delay(150); //print BLACK); } else if (angle >135 && angle <=180){//
new value every 0.5sec } 136-180 degrees int angle = (angle-134)/2;
display.drawLine(x0, y0, (x0+r)-angle, y0+r, BLACK);
} //////////// Functions /////////// } else if (angle >180 && angle <=225){// 181-225
degrees int angle = (angle-178)/2;
/Draw rows and print letters to display - 1st Display display.drawLine(x0, y0, x0-angle, y0+r, BLACK); }

DIY ROV: the Unsinkable #2: Page 4


https://www.youtube.com/watch?v=17p2Bp7uK2g

DIY ROV: the Unsinkable #2: Page 5


Step 2: Motor

Unlike most underwater motors, the ones used in this design will not cost you an arm and a leg (just as long as
you have access too a metal lathe). I chose to use cheap simple bilge pumps that one can find on amazon fairly
cheap. I then found simple rc boat propellers to mount on them. The propeller shafts are made out of 1/2"
aluminum round stock and ill include the blue prints for them.

DIY ROV: the Unsinkable #2: Page 6


DIY ROV: the Unsinkable #2: Page 7
Step 3: Pan and Tilt for Camera

I chose to use a simple usb camera and a usb to Pin out:


ethernet for the tether to the surface, its pretty simple
and works well. The pan tilt is just a simple 2 servo A0= Pot 1
pan and tilt you can pick up on amazon for around
$17. I designed the camera bracket for it in fusion 360 A1= Pot 2
and ill include the stl file for it.
Digital pin 8 = Servo 1
Camera:
https://www.amazon.com/gp/product/B01E8OC3EO/r Digital pin 9 = Servo 2
ef=o...
Code:
Pan tilt: https://www.amazon.com/Adafruit-Mini-Pan-
Tilt-Kit-... #include

STL: https://www.thingiverse.com/thing:2709264 Servo myservo1; Servo myservo2; // create servo


object to control a servo ;
The camera just bolts to the bracket using m3 screws
that can be found at any local hardware store. int potpin1 = 0; // analog pin used to connect the
potentiometer int potpin2 = 1;
From there the bracket just clips into the pan an tilt
and your ready to program! int val; // variable to read the value from the analog
pin int val2;
Now the program with the pan and tilt communicating
between two arduinos is listed in the remote design void setup() { myservo1.attach(8); // attaches the
step, but to test your pan and tilt you can use this servo on pin 9 to the servo object myservo2.attach(9);
program and it will work just fine }

void loop() { val = analogRead(potpin1); // reads the according to the scaled value val2 =
value of the potentiometer (value between 0 and analogRead(potpin2); val2 = map(val2, 0, 1023, 0,
1023) val = map(val, 0, 1023, 0, 180); // scale it to use 180); myservo2.write(val2); }
it with the servo (value between 0 and 180)
myservo1.write(val); // sets the servo position

https://www.youtube.com/watch?v=b9hjBDJCVkE

Wow ! That is an impressive project. Please record some video of it in the sea when it is all
finished. Great instructable. I wonder what the sea otters will think of it :-)

That's really responsive, great build :)

DIY ROV: the Unsinkable #2: Page 8


Thank you!! This was my final project for my microprocessors class and i was a little too ambitious
for the time frame in which we had to complete our finals so i didn't end up getting it all together,
but we had to upload and make an instructable for what we were able to accomplish.So one day i
will actually complete it Lol!!

DIY ROV: the Unsinkable #2: Page 9

You might also like