Skip to content

1. Documentación corta

evafc003 edited this page Dec 14, 2024 · 25 revisions

Para este proyecto, estaremos versionando el robot que se ve en este vídeo, para que en lugar de pulsar de vuelta el botón por sí mismo, te obligue a ti a hacerlo.

1. Materiales

Los materiales que necesitamos para este proyecto son:

  • Una placa Arduino (en mi caso mega)
  • 2 servomotores
  • 1 Switch de palanca
  • 1 LED (da igual el color)
  • 1 Sensor de ultrasonidos
  • 1 Sensor de humedad DHT11
  • 1 Zumbador
  • Una impresora 3D para poder imprimir los siguientes diseños:
  • Silicona Caliente
  • Cartón, esponjas, madera, etc (Cualquier cosa que te sirva para seguir los pasos del montaje

2. Montaje

Una vez obtenidos los materiales descritos anteriormente, para el montaje seguiremos el siguiente diagrama eléctrico para el arduino:

Y los siguientes pasos para el resto (ATENCIÓN, NO MONTES NADA EN EL ARDUINO ANTES DE SEGUIR ESTOS PASOS, YA QUE EL ORDEN ES IMPORTANTE Y SE IRÁ INDICANDO A CONTINUACIÓN).

Paso 0

Antes de comenzar el montaje, adjunto un esquema/plano del resultado final que esperamos, para que te sea de ayuda a la hora de seguir los siguientes pasos:

Caja por dentro

Acople de piezas a los motores

Paso 1

Primero, coloca la placa arduino y la protoboard de forma que no se vayan a mover dedntro de la caja, en mi caso, utilicé unas esponjas que tenía por casa, pero puedes utilizar el material que tengas a mano:

Paso 2

Después, enchufa adecuadamente el led y el switch, sin sacar nada de la caja:

Paso 3

A continuación, conecta a la placa el sensor de humedad y el ultrasonidos, de modo que, por fuera de la caja se vean asÍ (o cómo te ve nga bien según los materiales de los que dispongas). Para sujetarlos a la caja, también usé esponjas:

Paso 4

Conecta los motores con sus correspondientes estructuras de la siguiente manera. Es aquí dónde se diseña el brazo, en mi caso, hice una estructura en forma de U con cartón, alambre y cinta, pero se puede hacer de cualquier otra forma siempre y cuando se vea bien al moverse:

brazo_cascarrabias.mp4

3. Programación

Para programar el comportamiento, es necesario tener instalado Arduino Ide, si no lo tienes, puedes descargarlo aquí.

Una vez instalado, necesitamos instalar 2 librerías, DHT y Servo, para que esos 2 componentes del proyecto funcionen correctamente. Dejo a continuación un tutorial de instalación de dichas librerías:

3.1. Instalación de librerías para Arduino

Una vez instalado y funcionando Arduino ide, necesitaremos instalar 2 librerías, éstas son DHT y Servo. Para instalarlas, sigue los pasos de estas imágenes (estas que se muestran son para instalar DHT, Servo se explica después):

Paso 1: Métete en el menú de librerías de Arduino

Paso 2: Mete en el buscador el término DHT

Paso 3: Busca la librería DHT que se muetra aquí entre todos los resultados

Paso 4: Haz click en instalar

Paso 5: Acepta la instalación

Paso 6: ¡Listo! Si todo va bien verás lo siguiente

Para el caso del servo, los pasos son los mismos, pero la librería es la siguiente:

3.2. Código necesario

Cuando ya esté todo, insertar este código en un fichero para el arduino (TENIENDO EN CUENTA LOS PINES UTILIZADOS, Y CAMBIANDO LOS NECESARIOS. TAMBIÉN PUEDE SER NECESARIO CAMBIAR EL VALOR FALSE A TRUE DEL BOTÓN, DEPENDIENDO DE CÓMO ESTÉ CONECTADO, TAMBIÉN PUEDE SER NECESARIO QUE CAMBIES LOS GIROS DE LOS MOTORES, DEPENDIENDO DE LOS TUYOS):

Y subirlo a la placa pulsando el botón con forma de flecha hacia a la derecha situado en la esquina superior izquierda de Arduino ide.

#include <Servo.h> 
#include <DHT.h>

// Initialice servos
Servo cabeza;
Servo brazo;

// Neccesary pins, EDIT AS YOU NEED
int LED = 13;
int SWITCH = 12;
int TRIG = 10;
int ECHO = 9;
int HUM = 7;
int HEAD_PIN = 4; 
int ARM_PIN = 5;
int BUZZER = 2;

// Motor angles. EDIT AS YOU NEED
int HEAD_UP = 50;
int HEAD_DOWN = 180;
int ARM_OUT = -180;
int ARM_IN = 180;
int HEAD_MED = 90;
int ARM_MED = 90;

// initialise dht11 sensor
DHT dht(HUM, DHT11);

// For control states
bool first_time = false;
bool secuence_done = false;
unsigned long initial_time = 0;
int hum = 0;
int dist = 0;
int SCARED = 1;
int DONT_SCARED = 2;

// FUNCTIONS WE NEED
long get_distance(){
  long t;
  long d;

  digitalWrite(TRIG, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG, LOW);
  
  t = pulseIn(ECHO, HIGH);
  d = t/59;

  return d;
}

float get_humidity(){
  float h = dht.readHumidity();
  return h;
}

void get_out_of_box(int state){
  digitalWrite(LED, HIGH);
  delay(200);
  cabeza.write(HEAD_UP);
  if (state != SCARED){
    delay(600);
    brazo.write(ARM_OUT);
    delay(1000);
    brazo.write(ARM_IN);
    delay(600);
    brazo.write(ARM_OUT);
    delay(1000);
    brazo.write(ARM_IN);
    delay(600);
    brazo.write(ARM_OUT);
    delay(1000);
    brazo.write(ARM_IN);
  }
  
  return;
}

void get_in_box(){
  digitalWrite(LED, LOW);
  delay(200);
  brazo.write(HEAD_DOWN);
  delay(600);
  cabeza.write(ARM_IN);
  return;
}

void move_head(int velocity){
  cabeza.write(HEAD_MED);
  delay(velocity);
  cabeza.write(HEAD_UP);
  delay(velocity);
  cabeza.write(HEAD_MED);
  delay(velocity);
  cabeza.write(HEAD_UP);
  return;
}

void move_arm(int velocity){
  brazo.write(ARM_OUT);
  delay(velocity);
  brazo.write(ARM_MED);
  delay(velocity);
  brazo.write(ARM_OUT);
  delay(velocity);
  brazo.write(ARM_MED);
  delay(velocity);
  brazo.write(ARM_IN);
  return;
}

// Setup function for getting started our proyect
void setup() {
  Serial.begin(9600);
  pinMode(LED, OUTPUT);
  pinMode(TRIG, OUTPUT);
  pinMode(ECHO, INPUT);
  pinMode(HUM, INPUT);
  pinMode(SWITCH, INPUT_PULLUP);
  pinMode(BUZZER, OUTPUT);
  digitalWrite(TRIG, LOW);
  dht.begin();
  cabeza.attach(HEAD_PIN);
  brazo.attach(ARM_PIN); 
  return;
}

void get_scared_if_necesary(){
  int hum = get_humidity();
  int dist = get_distance();
  Serial.println(hum);
  Serial.println(dist);
  if (hum > 70 || dist < 10){
    tone(BUZZER, 2000);
    get_in_box();
    get_out_of_box(SCARED);
  }
  noTone(BUZZER);
  return;
}

// Principal program
void loop() {
  if (digitalRead(SWITCH) == false) {
    // Elapsed time since button is pressed
    unsigned long current_time = millis();
    unsigned long elapsed_time = current_time - initial_time;
    
    if (first_time == false){
      for(int i=900; i>=800; i--) {
        tone(BUZZER, i);
        delay(10);
      }
      noTone(BUZZER);
      get_out_of_box(DONT_SCARED);
      first_time = true;
    }
    
    get_scared_if_necesary();

    if (elapsed_time > 10000 && elapsed_time <= 11000){ // SIENDO AMABLES
      if (secuence_done == false){
        tone(BUZZER, 900);
        delay(100);
        tone(BUZZER, 800);
        delay(100);
        noTone(BUZZER);
        delay(100);
        move_arm(1000);
        secuence_done = true;
      }

      get_scared_if_necesary();
      
    }else if (elapsed_time > 20000 && elapsed_time <= 21000) { // SIENDO MENOS AMABLES
      if (secuence_done == true){
        tone(BUZZER, 900);
        delay(1000);
        tone(BUZZER, 800);
        delay(1000);
        noTone(BUZZER);
        
        delay(100);
        move_arm(700);
        secuence_done = false;
      }

      get_scared_if_necesary();

    }else if (elapsed_time > 32000 && elapsed_time <= 33000) { // RECORDANDO NUESTRA EXISTENCIA 
      if (secuence_done == false){
        for(int i=800; i<=900; i++) {
          tone(BUZZER, i);
          delay(10);
        }
        noTone(BUZZER);
        secuence_done = true;
        delay(100);
        move_arm(500);
        delay(100);
        move_arm(500);
      }

      get_scared_if_necesary();

    }else if (elapsed_time > 40000 && elapsed_time <= 41000) { // COMENZANDO A ENFADARNOS
      if (secuence_done == true){
        for (int i = 0; i<=3; i++){
          tone(BUZZER, 900);
          delay(100);
          tone(BUZZER, 800);
          delay(100);
        }
        noTone(BUZZER);

        move_head(500);
        move_head(500);
        move_arm(200);
        move_arm(200);
        move_arm(200);

        secuence_done = false;
      }

      get_scared_if_necesary();

    }else if (elapsed_time > 55000 && elapsed_time <= 60000) { // PERDIENDO LA CORDURA
      if (secuence_done == false){
        tone(BUZZER, 900);
        delay(100);
        move_head(300);
        move_head(300);
        move_head(300);
        move_head(300);
        move_arm(150);
        move_arm(150);
        move_arm(150); 
        secuence_done = true;
      }
      noTone(BUZZER);
      get_scared_if_necesary();

    }else if (elapsed_time > 80000) { // VOLVIENDONOS LOCOS
      tone(BUZZER, 1000);
      move_head(200);
      move_head(200);
      move_head(200);
      move_head(200);
      move_arm(100);
      move_arm(100);
      move_arm(100); 
    }

  } else {
    // Button don't pressed, be inside the box and sleep
      if (first_time == true){
        tone(BUZZER, 1000);
        delay(100);
        tone(BUZZER, 1200);
        delay(100);
        noTone(BUZZER);
        first_time= false;
      }
      
      get_in_box();
      
      unsigned long current_time = millis();

      if (current_time - initial_time >= 10000) {
        initial_time = current_time;
        tone(BUZZER, 200);
        delay(100);
        tone(BUZZER, 250);
        delay(1000);
        noTone(BUZZER);
      }
  } 
}

4. Demostración

Si todo ha ido bien, el resultado del proyecto debería ser el siguiente (CABE DESTACAR QUE ME FUE NECESARIO REEMPLAZAR LA TAPA ORIGINAL POR UNA LÁMINA DE CARTÓN DEBIDO A QUE MI PLACA SE REINICIABA AL LEVANTAR LA TAPA, SI VAS A REPLICAR EL PROYECTO, ASEGÚRATE DE QUE TUS MOTORES SON POTENTES O QUE LA ALIMENTACIÓN ESTÁ SEPARADA, SI NO, TAMBIÉN PUEDES REEMPLAZAR LA TAPA AL IGUAL QUE HICE YO):

video_funcionamiento.mp4