// sobre el proyecto
Un robot que te saluda según qué tan cerca estás.
AND-Y nació del encargo de crear una máquina saludadora. Somos estudiantes del Taller de Diseño de Máquinas Computacionales de la Universidad Diego Portales, donde relacionamos el diseño con la programación y la interacción persona-máquina.
Mediante un sensor ultrasónico, AND-Y detecta la distancia de quien se acerca y responde con comportamientos distintos: tiembla de nervios, reproduce audios de voz y levanta su brazo para compartir datos curiosos.
⊹ aprendimos a programar hace solo 3 meses.
// fases de interacción
AND-Y te detecta desde lejos y te grita que te acerques. El motor vibrador comienza a activarse levemente.
Te pide con humor que te acerques más. La vibración aumenta, como si estuviera nervioso por tu presencia.
El servomotor levanta su brazo de 0° a 180° y comparte datos curiosos del mundo de la tecnología.
// diálogos de AND-Y
// componentes utilizados
| COMPONENTE | MODELO | FUNCIÓN |
|---|---|---|
| Arduino UNO | R4 Minima | Controlador principal del robot |
| Sensor Ultrasónico | HC-SR04 | Detecta distancia y presencia humana |
| ServoMotor | SG90 | Levanta el brazo de 0° a 180° |
| Motor Vibrador | Joystick | Vibra según la cercanía del usuario |
| Reproductor MP3 | DFPlayer Mini | Reproduce los audios de voz |
| Altavoz | Mini Parlante 3W | Salida de audio |
| Tarjeta SD | 255gb | Almacena los archivos de audio |
// etapas del código
// detecta la distancia y define en qué zona está el humano float EntradaUltrasonico::medirDistancia() { digitalWrite(patitaTrigger, LOW); delayMicroseconds(2); digitalWrite(patitaTrigger, HIGH); delayMicroseconds(10); digitalWrite(patitaTrigger, LOW); duracion = pulseIn(patitaEcho, HIGH); // convierte a cm (velocidad del sonido = 343 m/s) distanciaCm = int(float(duracion) * 0.0343 / 2.0); return distanciaCm; } void EntradaUltrasonico::decidirCercania() { int nuevoEstado = -1; if (distanciaCm >= 0 && distanciaCm <= 20) nuevoEstado = 0; // cercana else if (distanciaCm >= 50 && distanciaCm <= 90) nuevoEstado = 1; // mediana else if (distanciaCm >= 120 && distanciaCm <= 180) nuevoEstado = 2; // lejana // cambia estado solo si pasó tiempo suficiente (anti-loro) if (nuevoEstado != ultimoEstado && (millis() - ultimoCambio > tiempoEstabilidad)) { ultimoCambio = millis(); ultimoEstado = nuevoEstado; dondeEsta = nuevoEstado; } }
// controla el brazo servomotor de AND-Y void SalidaDedo::configurar() { servo.attach(patitaServo); servo.write(0); // posición inicial: abajo } void SalidaDedo::levantar() { servo.write(180); // sube el brazo a 180° } void SalidaDedo::bajar() { servo.write(0); // baja el brazo a 0° } int patitaServo = 13; // pin de conexión
// vibra según la distancia detectada void SalidaMotorVibracion::vibrar(int cuantoVibrar) { if (cuantoVibrar == 0) { intensidad = 0; // cercana: no vibra } else if (cuantoVibrar == 1) { intensidad = 80; // mediana: vibra mucho } else if (cuantoVibrar == 2) { intensidad = 20; // lejana: vibra poco } else { intensidad = 0; } analogWrite(MOTOR_PIN, intensidad); delay(300); }
// archivo principal — orquesta todo void loop() { ultrasonico.medirDistancia(); ultrasonico.decidirCercania(); // controla el brazo if (ultrasonico.dondeEsta == 0) dedo.levantar(); else dedo.bajar(); // vibra según distancia motor.vibrar(ultrasonico.dondeEsta); // reproduce audio solo si cambió de zona if (ultrasonico.dondeEsta != estadoAnterior) { estadoAnterior = ultrasonico.dondeEsta; if (ultrasonico.dondeEsta == 2) reproducirAudioDirecto(1); else if (ultrasonico.dondeEsta == 1) reproducirAudioDirecto(2); else if (ultrasonico.dondeEsta == 0) reproducirAudioDirecto(3); } delay(200); }
// dificultades y aprendizajes
La primera idea era un selector de idiomas con joystick. Redactamos muchas ideas pero no nos convencían. Partir desde cero fue el primer desafío real.
La distancia medida no era exacta ni se redondeaba bien. Requirió muchas pruebas y ajuste de rangos para que detectara las tres zonas de forma estable.
La tarjeta SD requería formato específico y los audios debían estar en orden preciso. Los primeros códigos fallaban hasta encontrar el repositorio correcto de DFPlayer.
Cada módulo funcionaba bien por separado. Al juntarlos, el audio iba en loop, el motor no vibraba y el servo no respondía. Aprendimos a coordinar tiempos y estados.
// equipo ANDlid
todas complementamos en todos los roles ⊹

