Sistema de sonar marítimo

Implementación

El hardware de nuestro sistema de sonar marítimo consta principalmente de los siguientes componentes:

  1. Sensor HC-SR04: sensor de ultrasonido que emite ondas para medir la distancia a objetos mediante el eco.
  2. Buzzer: genera una alarma sonora que cambia de velocidad según la distancia a la que se encuentra el objeto.
  3. Servomotor SG90: hace que el sensor pueda girar para realizar el barrido del radar en diferentes ángulos.
  4. Arduino Uno: procesa el código y lee las señales del sensor y da ordenes al servomotor y al zumbador.
  5. Pila de 9V: proporciona energía extra para que el motor no reinicie la placa Arduino al moverse.
  6. Cables puente y Dupont: se realizan las conexiones entre los componentes.
  7. Protoboard: conectamos todos los componentes, sirve de puente entre ellos y el Arduino.

Para realizar nuestro sonar hemos realizados las siguientes conexiones:

  • Alimentación principal
    • Linea positiva (+): pin 5v del Arduino
    • Linea negativa (-): pin GND del Arduino
  • Sensor HC-SR04
    • TRIG: Pin digital 10 del Arduino
    • Echo: Pin digital 11 del Arduino
    • VCC: línea roja (+) de la protoboard
    • GND: línea azul (-) de la protoboard
  • Servomotor SG90
    • Cable amarillo: Pin digital 9 del Arduino
    • Cable marrón: línea azul (-) de la protoboard
    • Cable rojo: línea roja (+) de la protoboard
  • Buzzer
    • Pata larga: Pin digital 8 del Arduino
    • Pata corta: línea azul (-) de la protoboard

Pasos dados

  • Idea inicial

La idea pasó de un sensor estático que captaba el movimiento a un sistema dinámico de barrido          angular para detectar obstáculos en un radio de 180º. Por el camino, pensamos en la                                          implementación de un detector de fuego, pero fue rápidamente removido.

  • Selección de materiales

Nos dimos cuenta de que no disponíamos de un motor lo suficientemente estable para realizar                        nuestro proyecto, por lo que tuvimos que comprar un servomotor.

  • Hardware y código

Conforme fuimos conectando el hardware, también utilizamos códigos de prueba para comprobar que           cada uno de los componentes funcionaba por separado y juntos cuando se empezaban a conectar todos. No encontramos ningún problema con los cables, no había ninguno defectuoso.

  • Problemas de potencia

Como se explicará más en detalle más adelante, el servomotor utilizaba más potencia de la que                           prestaba el Arduino, por lo que añadimos una pila de 9V.

  • Processing

Para darle un toque más profesional a nuestro proyecto, desarrollamos mediante la aplicación                    Processing un sonar que utilizaba las señales que le mandaban los pines en la placa de Arduino para   pintarlo de una manera más representativa en la pantalla.

  • Maquetación e integración

Para añadirle algo de decoración y complejidad, construimos una maqueta de un barco que                completara nuestro proyecto y simulara cómo funcionaría en una situación real.

Reparto de tareas

El reparto de tareas ha sido prácticamente equitativo entre todos los integrantes del grupo, aunque cada uno se ha implicado más en un aspecto distinto.

Álvaro ha participado en un mayor porcentaje en el hardware, aunque también ha estado implicado en las otras tareas. Lo mismo para Mark, participando algo más en la programación del código y Leonardo con el montaje del proyecto.

Costes de los materiales

Concepto / ComponenteCantidadCoste Real (€)Procedencia / Notas
Pila de 9V13.49 €Adquirido por el alumno (Mejora de alimentación).
Servomotor SG9014.00 €Adquirido por el alumno (Nota: Se compró un pack de 2 uds. por 8.00 €, imputando la mitad al prototipo).
Placa Arduino Uno R310.00 €Proporcionado por la Universidad (Starter Kit).
Sensor Ultrasónico HC-SR0410.00 €Proporcionado por la Universidad (Starter Kit).
Zumbador (Buzzer activo)10.00 €Proporcionado por la Universidad (Starter Kit).
Protoboard y Cables Dupont1 set0.00 €Proporcionado por la Universidad (Starter Kit).
Chasis (Cartón) y Adhesivos10.00 €Material reciclado y fungible propio.
COSTE TOTAL DEL PROTOTIPO7.49 €

Problemas y soluciones encontradas

  • Problemas de voltaje y alimentación

Al alimentar el circuito solo con el USB al Arduino, el servomotor provocaba picos de corriente que causaban que nuestra placa se reiniciara y hacía que el ordenador desconectara el puerto por seguridad.

Para solucionarlo, conectamos una pila de 9V a la placa. Con ella, la placa pudo suministrar corriente a los elementos de nuestro circuito, evitando así los reinicios.

  • Step Motor

El motor proporcionado en el kit no era lo suficientemente correcto para poder tener todo el ángulo que debía hacer nuestro sensor. Además, su superficie de contacto no era la necesaria para poder pegarlo.

La solución que encontramos fue la compra de un Servomotor SG90 que permite una mejora en el control preciso de la posición angular y mejorando así la superficie para pegar nuestro sensor.

  • Problemas y evolución del código

Inicialmente, el código usaba la función delay() para mover el servomotor y esperar el eco del sensor. Esto «congelaba» el procesador, impidiendo que el buzzer pitara correctamente mientras el motor giraba.

Lo que hicimos fue reescribir el código y utilizarla función millis() con la que el procesador comprueba el tiempo transcurrido y decide si debe mover el motor, medir la distancia o activar el sonido del buzzer de forma independiente.

Casos de uso

  • Escaneo de zona despejada

El radar escanea los alrededores de la proa del barco, para asi asegurarse de que la ruta está libre de obstáculos, a la vez el servomotor realiza desde 15º hasta 165º de barrido continuo y fluido, el sensor HR-SRC04 es quien se encarga de medir las distancias constantemente, si no detecta objetos a menos de 40cm el sistema se mantiene en silencio. Como resultado la pantalla del ordenador (Processing), se puede visualizar como la línea verde se mueve sin ninguna alerta visual

  • Detección temprana de obstáculos

Un objeto entra en el rango de detección del HR-SRC04 (3-40cm) simulando así un riesgo de colisión

El sensor detecta la distancia exacta del objeto, a continuación, el Arduino envía los datos, en este caso ángulo y distancia por el puerto serie. Al detectar el objeto, el zumbador entonces emite un sonido espaciado, a menor distancia, el sonido se escucha con menor espaciado.

Con los datos recibidos del Arduino, el software Processing dibuja un punto rojo en las coordenadas exactas de la pantalla, así alertando visualmente. También indica a la distancia a la que se encuentra dicho objeto

  • Alarma crítica de colisión inminente

Se detecta que un objeto se acerca peligrosamente al barco, el sensor detecta que la distancia disminuye drásticamente, gracias al millis(), el Arduino calcula un intervalo de espera más corto, en consecuencia, el zumbador aumenta la frecuencia de los pitidos (suena más rápido), el radar sigue girando sin congelarse, por lo tanto, la posición en la pantalla se va actualizando constantemente (punto rojo).

El proyecto implementa lo que se llama Sistema Embebido de Bucle Cerrado y Multitare, esto permite que los Casos de Uso 2 y 3 (pitar y moverse) ocurran simultáneamente sin que el motor se atasque

Código

Se ha decidido explicar el código con comentarios.

Arduino:

#include <Servo.h> // Librería para usar las funciones del Servomotor

// Configuración de pines digitales del buzzer, servo y las patillas trigger y echo del sensor ultrasonido

const int buzzerPin = 8;

const int servoPin = 9;

const int trigPin = 10;

const int echoPin = 11;

Servo myServo; // Objeto tipo Servo que hace referencia al Servomotor

int angle = 15; // Ángulo al que se moverá el servo

int direction = 1; // Dirección del servo

int distance; // Distancia desde el sensor hasta un objeto

long duration; // Duración del pulso del sensor para poder calcular la distancia

unsigned long previousMillisServo = 0; // Última vez que se usó el servo

unsigned long previousMillisBuzzer = 0; // Última vez que se usó el buzzer

const int servoInterval = 30; // Tiempo de intervalos de uso del servo

void setup() {

  pinMode(trigPin, OUTPUT); // Trig del sensor como salida

  pinMode(echoPin, INPUT); // Echo del sensor como entrada

  pinMode(buzzerPin, OUTPUT); // Buzzer como salida

  Serial.begin(9600); // Iniciamos comunicación con el ordenador

  myServo.attach(servoPin); // Le decimos al objeto donde está el pin físico del servo

}

// Bucle infinito

void loop() {

  unsigned long currentMillis = millis(); // Obtener el tiempo actual desde que se encendió el arduino

// Entramos al if si ha pasado suficiente tiempo desde el último uao del servo

  if (currentMillis – previousMillisServo >= servoInterval) {

    previousMillisServo = currentMillis; // Actualizamos última vez

    myServo.write(angle); // Ordenar al servo a qué ángulo ir

    distance = calculateDistance(); // Calcular distancia

// Imprimos el ángulo y la distancia con ese formato

    Serial.print(angle);

    Serial.print(«,»);

    Serial.print(distance);

    Serial.print(«.»);

    angle += direction; // Actualizamos el siguiente ángulo

// Si el ángulo sobrepasa esos límites cambiamos la dirección para que no choque con nuestro modelo físico

    if (angle >= 165 || angle <= 15) {

      direction *= -1;

    }

  }

  gestionarAlarma(distance); // Si se detecta un objeto el buzzer suena

}

int calculateDistance() {

  digitalWrite(trigPin, LOW); // Comprobar que trig está apagado

  delayMicroseconds(5);  // Tiempo de estabilización

  digitalWrite(trigPin, HIGH); // Encender trig para mandar un pulso untrasónido

  delayMicroseconds(10); // Especificación del componente del tiempo de espera para que el Trigger considere la orden

  digitalWrite(trigPin, LOW); // Apagar trig

  duration = pulseIn(echoPin, HIGH); // Fumcion que devuelve el tiempo que ha durado el pulso

  distance = (duration / 2) / 29.1; // Dividimos entre 2 porque el pulso va y vuelve, 29.1 es la constante microsegundos por centímetro

  return distance; // Devolver la distancia

}

void gestionarAlarma(int dist) {

// Comprobar que detectamos un objeto en ese rango, fuera de ese rango el sensor HC-SR04 suele fallar

  if (dist > 3 && dist <= 40) {

    int intervaloEspera = map(dist, 3, 40, 100, 800); // Convertir la distancia entre el intervalo de cada tono del buzzer (a menor distancia más rápido suena)

    unsigned long currentMillis = millis();

// Si ha pasado suficiente tiempo desde la última vez que se usó el buzzer mandamos un tono

    if (currentMillis – previousMillisBuzzer >= intervaloEspera) {

      previousMillisBuzzer = currentMillis; // Actualizar última vez

      tone(buzzerPin, 1500, 60);

    }

  }

}

Processing:

Import processing.serial.*; // Librería para poder comunicarse con puertos usb

Serial miPuerto; // Objeto tipo Serial que controlará la comunicación

String datos = “”; // String para guardar los datos recibidos

Int angulo = 0; // Ángulo del objeto físico

Int distancia = 0; // Distancia hacia el objeto físico

Void setup() {

  Size(800, 500); // Definir tamaño de la pantalla en píxeles

  Smooth(); // Para que las líneas no se vean pixeladas

  String nombrePuerto = “COM3”;  // Nombre del puerto Windows por el que nos comunicaremos

  miPuerto = new Serial(this, nombrePuerto, 9600); // Inicialización del Serial con 9600 baudios como en el código arduino

  miPuerto.bufferUntil(‘.’);  //  Leer los datos entrantes hasta encontrar un ‘.’

}

// Función principal de animación, se ejecuta continuamente

Void draw() {

  Fill(0, 15); // Rellenar con color negro y 15 de opacidad

  noStroke(); // Sin bordes

  rect(0, 0, width, height);  // Dibuja un rectángulo en toda la pantalla

  pushMatrix(); // guarda el sistema de coordenadas actuales

  translate(400, 450); // Cambiamos el origen del sistema de coordenadas. Estaba en (0,0)

  noFill(); // Sin rellenar

  strokeWeight(2); // Bordes con grosor de 2cm

  stroke(0, 255, 0); // Color verde

// Dibujar dos  semicírculos típicos de un radar

  arc(0, 0, 700, 700, PI, TWO_PI);

  arc(0, 0, 400, 400, PI, TWO_PI);

  float rad = radians(angulo); // Convertimos el ángulo recibido a radianes

  stroke(0, 255, 0);

  line(0, 0, 350 * cos(rad), -350 * sin(rad)); // Dibujar línea que recorra el ángulo actual

// Si detectamos un objeto entre esa distancia:

  if (distancia < 40 && distancia > 2) {

    fill(255, 0, 0); // Rellenar con color rojo

    noStroke();

    float x = map(distancia, 0, 40, 0, 350) * cos(rad); // Convertimos centímetros a píxeles

    float y = -map(distancia, 0, 40, 0, 350) * sin(rad);

    ellipse(x, y, 20, 20); // Dibujamos un punto 20×20

  }

  popMatrix(); // Restauramos las coordenadas para imprimir por pantalla sin problemas

  fill(0, 255, 0);

  textSize(20); // Tamaño de fuente

  text(“Radar de Barco – Activo”, 20, 30);

  text(“Distancia: “ + distancia + “ cm”, 20, 60);

}

// Función que se ejecuta cuando arduino envía datos

Void serialEvent(Serial p) {

  Datos = p.readStringUntil(‘.’); //  Leer hasta encontrar un ‘.’

  If (datos ¡= null) { // Si recibe datos

    Datos = datos.substring(0, datos.length() – 1); // Borramos el ‘.’

    String[] lista = split(datos, ‘,’); // Separamos los datos por la ‘,’

    If (lista.length == 2) { // Si los datos se han recibido correctamente

      Angulo = int(lista[0]); // Obtenemos el ángulo

      Distancia = int(lista[1]); // Obtenemos la distancia

    }

  }

}

En definitiva, el código Arduino contiene la lógica de los siguientes componentes:

Servomotor SG90: se mueve constantemente para permitir al sensor detectar objetos

Sensor HC-SR04: manda pulsos ultrasonido para detectar objetos

Buzzer: emite tonos en función de la distancia, a menor distancia suena en intervalos más rápidos. Esto sirve para que las personas encargadas de controlar la seguridad del barco/submarino puedan recibir feedback auditivo, canal de comunicación fundamental en un sonar.

Por otro lado, el código Processing se encarga de permitir al usuario visualizar la información en un radar, lo que proporciona un cierto grado de confianza extra, ya que se puede ver a los componentes realizando su trabajo

Video

También te podría gustar...

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *