Hackster is hosting Hackster Holidays, Ep. 6: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Monday!Stream Hackster Holidays, Ep. 6 on Monday!
Dulini R
Published

Oil Spill Detection and Remediation using Machine Learning

Unmanned Surface Vessel to revolutionize how mid-ocean oil spills are treated with minimum human intervention.

AdvancedFull instructions provided2,314
Oil Spill Detection and Remediation using Machine Learning

Things used in this project

Hardware components

Raspberry Pi 3 Model B
Raspberry Pi 3 Model B
×1
Camera Module
Raspberry Pi Camera Module
×1
Adafruit Waterproof DS18B20 Digital temperature sensor
Adafruit Waterproof DS18B20 Digital temperature sensor
×1
Ultrasonic Sensor - HC-SR04 (Generic)
Ultrasonic Sensor - HC-SR04 (Generic)
×1
Grove - 2-Channel SPDT Relay
Seeed Studio Grove - 2-Channel SPDT Relay
×1
3-6V submersible water pump
×1
LED (generic)
LED (generic)
×1
Resistor 330 ohm
Resistor 330 ohm
×2
Resistor 1k ohm
Resistor 1k ohm
×1
Through Hole Resistor, 470 kohm
Through Hole Resistor, 470 kohm
×1
Resistor 4.75k ohm
Resistor 4.75k ohm
×1
AA Batteries
AA Batteries
×4
4xAA battery holder
4xAA battery holder
×1
transparent water tube
×1
Solar Panel
×1
Sprinkler head
×1
5V power bank
×1
water proof container
×1
acrylic sheets
×1
Breadboard (generic)
Breadboard (generic)
×1
Jumper wires (generic)
Jumper wires (generic)
×1

Software apps and online services

Ubidots
Ubidots
Microsoft Lobe
TensorFlow
TensorFlow
Used by Lobe

Hand tools and fabrication machines

Wire Stripper & Cutter, 18-10 AWG / 0.75-4mm² Capacity Wires
Wire Stripper & Cutter, 18-10 AWG / 0.75-4mm² Capacity Wires
Laser cutter (generic)
Laser cutter (generic)

Story

Read more

Custom parts and enclosures

CAD file for Acrylic Box

Schematics

Project Prototype Images

Prototype Working Video

Component Connections

Logic for prototype

Hull design

Circuit diagram

Code

sonic_ubidots.py

Python
Ultrasonic sensor to measure volume in tank
#Libraries
import RPi.GPIO as GPIO
import time
from ubidots import ApiClient
 
#GPIO Mode (BOARD / BCM)
GPIO.setmode(GPIO.BCM)
 
#set GPIO Pins
GPIO_TRIGGER = 18
GPIO_ECHO = 24
 
#set GPIO direction (IN / OUT)
GPIO.setup(GPIO_TRIGGER, GPIO.OUT)
GPIO.setup(GPIO_ECHO, GPIO.IN)

api = ApiClient(token='')
volume = api.get_variable("")
 
def v_left():
    # set Trigger to HIGH
    GPIO.output(GPIO_TRIGGER, True)
 
    # set Trigger after 0.01ms to LOW
    time.sleep(0.00001)
    GPIO.output(GPIO_TRIGGER, False)
 
    StartTime = time.time()
    StopTime = time.time()
 
    # save StartTime
    while GPIO.input(GPIO_ECHO) == 0:
        StartTime = time.time()
 
    # save time of arrival
    while GPIO.input(GPIO_ECHO) == 1:
        StopTime = time.time()
 
    # time difference between start and arrival
    TimeElapsed = StopTime - StartTime
    # multiply with the sonic speed (34300 cm/s)
    # and divide by 2, because there and back
    distance = (TimeElapsed * 34300) / 2
    v_left = 15*15*(10-distance) #dimensions of tank
 
    return v_left

while True:
    dist = v_left()
    #print ("Volume left = %.1f l" % dist)
    volume.save_value({'value':dist})
    time.sleep(1)

led_ubidots.py

Python
LED Control
import RPi.GPIO as GPIO
from ubidots import ApiClient
from time import sleep

GPIO.setmode(GPIO.BCM)
GPIO.setup(23, GPIO.OUT)
Use GPIO.setwarnings(False)

api = ApiClient(token="")
led = api.get_variable("")

while True:

    last_value = led.get_values(1)
    if last_value[0].get("value")==1:
        GPIO.output(23, GPIO.HIGH)
    else:
        GPIO.output(23, GPIO.LOW)
    sleep(5)

detector.py

Python
Code to link LOBE model with pump to release dispersant when oil is detected
from picamera import PiCamera
import time
from time import sleep
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM) # GPIO Numbers instead of board numbers
RELAY_GPIO = 17
GPIO.setup(RELAY_GPIO, GPIO.OUT) # GPIO Assign mode

from lobe import ImageModel
 
camera = PiCamera()
 
# Load Lobe TF model
model = ImageModel.load('/home/pi/Lobe/model')
 
# Take Photo
def take_photo():
    # Start the camera preview
    camera.start_preview(alpha=200)
    # wait 2s or more for light adjustment
    sleep(3) 
    camera.capture('/home/pi/Pictures/image.jpg')
    #Stop camera
    camera.stop_preview()
    sleep(1)
    
# Identify prediction and turn on/off relay
def result_select(label):
    print(label)
    if label == "Clean":
        GPIO.output(RELAY_GPIO, GPIO.HIGH)
        sleep(5)
    if label == "oil":
        GPIO.output(RELAY_GPIO, GPIO.LOW)
        sleep(5)
    
# Main Function
while True:
    take_photo()
        # Run photo through Lobe TF model
    result = model.predict_from_file('/home/pi/Pictures/image.jpg')
    result_select(result.prediction)
    

Minor_cam_final.py

Python
Code to get live stream from Pi camera
# Web streaming example
# Source code from the official PiCamera package
# http://picamera.readthedocs.io/en/latest/recipes2.html#web-streaming
import io
import picamera
import logging
import socketserver
from threading import Condition
from http import server

PAGE="""\
<html>
<head>
<title>Live Stream</title>
</head>
<body>
<center><h1>Oil Spill: Live Stream</h1></center>
<center><img src="stream.mjpg" width="350" height="450"></center>
</body>
</html>
"""

class StreamingOutput(object):
    def __init__(self):
        self.frame = None
        self.buffer = io.BytesIO()
        self.condition = Condition()

    def write(self, buf):
        if buf.startswith(b'\xff\xd8'):
            # New frame, copy the existing buffer's content and notify all
            # clients it's available
            self.buffer.truncate()
            with self.condition:
                self.frame = self.buffer.getvalue()
                self.condition.notify_all()
            self.buffer.seek(0)
        return self.buffer.write(buf)

class StreamingHandler(server.BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path == '/':
            self.send_response(301)
            self.send_header('Location', '/index.html')
            self.end_headers()
        elif self.path == '/index.html':
            content = PAGE.encode('utf-8')
            self.send_response(200)
            self.send_header('Content-Type', 'text/html')
            self.send_header('Content-Length', len(content))
            self.end_headers()
            self.wfile.write(content)
        elif self.path == '/stream.mjpg':
            self.send_response(200)
            self.send_header('Age', 0)
            self.send_header('Cache-Control', 'no-cache, private')
            self.send_header('Pragma', 'no-cache')
            self.send_header('Content-Type', 'multipart/x-mixed-replace; boundary=FRAME')
            self.end_headers()
            try:
                while True:
                    with output.condition:
                        output.condition.wait()
                        frame = output.frame
                    self.wfile.write(b'--FRAME\r\n')
                    self.send_header('Content-Type', 'image/jpeg')
                    self.send_header('Content-Length', len(frame))
                    self.end_headers()
                    self.wfile.write(frame)
                    self.wfile.write(b'\r\n')
            except Exception as e:
                logging.warning(
                    'Removed streaming client %s: %s',
                    self.client_address, str(e))
        else:
            self.send_error(404)
            self.end_headers()

class StreamingServer(socketserver.ThreadingMixIn, server.HTTPServer):
    allow_reuse_address = True
    daemon_threads = True

with picamera.PiCamera(resolution='640x480', framerate=24) as camera:
    output = StreamingOutput()
    #Uncomment the next line to change your Pi's Camera rotation (in degrees)
    #camera.rotation = 90
    camera.start_recording(output, format='mjpeg')
    try:
        address = ('', 8000)
        server = StreamingServer(address, StreamingHandler)
        server.serve_forever()
    finally:
        camera.stop_recording()  

ubidots_pump.py

Python
Pump control with UBIDOTS
import time
from ubidots import ApiClient
import RPi.GPIO as GPIO
from w1thermsensor import W1ThermSensor

GPIO.setmode(GPIO.BCM)

RELAY_GPIO = 17
LED_GPIO = 23
GPIO_TRIGGER = 18
GPIO_ECHO = 24
 

GPIO.setup(RELAY_GPIO, GPIO.OUT)
GPIO.setup(LED_GPIO, GPIO.OUT)
GPIO.setup(GPIO_TRIGGER, GPIO.OUT)
GPIO.setup(GPIO_ECHO, GPIO.IN)

sensor = W1ThermSensor()
temperature = sensor.get_temperature()

Use GPIO.setwarnings(False)

try:
    api = ApiClient(token='')
    pump = api.get_variable('')

except:
    
    print("cant connect")


while True:

#Relay/ dispersion system control
    last_value = pump.get_values(1)
    if last_value[0]['value']:
     GPIO.output(RELAY_GPIO, GPIO.LOW) 
    else:
     GPIO.output(RELAY_GPIO, GPIO.HIGH) 

ubidots_temp.py

Python
Get Temperature data from sensor and display on UBIDOTS
import time
import RPi.GPIO as GPIO
from ubidots import ApiClient
GPIO.setmode(GPIO.BCM)
from w1thermsensor import W1ThermSensor

sensor = W1ThermSensor()
temperature = sensor.get_temperature()

api = ApiClient(token='')
temp = api.get_variable("")

while True:
    temp.save_value({'value':temperature})
    time.sleep(10)
 
        

Credits

Dulini R

Dulini R

1 project • 1 follower
Thanks to Sea Swarm by MIT.

Comments