lunes, 21 de septiembre de 2026

CODIGO CARRO EVASOR DE OBSTACULOS

 CODIGO CARRO EVASOR DE OBSTACULOS


// ==========================================

// EVASOR DE OBSTACULOS

// Arduino UNO + L298N + HC-SR04

// ==========================================


// ---------- MOTORES ----------


const int ENA = 5;

const int IN1 = 8;

const int IN2 = 9;


const int ENB = 6;

const int IN3 = 10;

const int IN4 = 11;


// ---------- HC-SR04 ----------


const int TRIG = 3;

const int ECHO = 4;


// const int TRIG = 12;

// const int ECHO = 13;


// ---------- CONFIGURACION ----------


const int VELOCIDAD = 140;

const int DISTANCIA_MINIMA = 20;



// ==========================================

// FUNCIONES DE MOVIMIENTO

// ==========================================


void adelante() {


  digitalWrite(IN1, LOW);

  digitalWrite(IN2, HIGH);


  digitalWrite(IN3, LOW);

  digitalWrite(IN4, HIGH);


  analogWrite(ENA, VELOCIDAD);

  analogWrite(ENB, VELOCIDAD);

}



void atras() {


  digitalWrite(IN1, HIGH);

  digitalWrite(IN2, LOW);


  digitalWrite(IN3, HIGH);

  digitalWrite(IN4, LOW);


  analogWrite(ENA, VELOCIDAD);

  analogWrite(ENB, VELOCIDAD);

}



void izquierda() {


  digitalWrite(IN1, HIGH);

  digitalWrite(IN2, LOW);


  digitalWrite(IN3, LOW);

  digitalWrite(IN4, HIGH);


  analogWrite(ENA, VELOCIDAD);

  analogWrite(ENB, VELOCIDAD);

}



void derecha() {


  digitalWrite(IN1, LOW);

  digitalWrite(IN2, HIGH);


  digitalWrite(IN3, HIGH);

  digitalWrite(IN4, LOW);


  analogWrite(ENA, VELOCIDAD);

  analogWrite(ENB, VELOCIDAD);

}



void detener() {


  analogWrite(ENA, 0);

  analogWrite(ENB, 0);

}



// ==========================================

// MEDIR DISTANCIA

// ==========================================


float medirDistancia() {


  digitalWrite(TRIG, LOW);

  delayMicroseconds(2);


  digitalWrite(TRIG, HIGH);

  delayMicroseconds(10);


  digitalWrite(TRIG, LOW);


  long tiempo = pulseIn(ECHO, HIGH);


  float distancia = tiempo * 0.0343 / 2;


  return distancia;

}



// ==========================================

// CONFIGURACION

// ==========================================


void setup() {


  pinMode(ENA, OUTPUT);

  pinMode(IN1, OUTPUT);

  pinMode(IN2, OUTPUT);


  pinMode(ENB, OUTPUT);

  pinMode(IN3, OUTPUT);

  pinMode(IN4, OUTPUT);


  pinMode(TRIG, OUTPUT);

  pinMode(ECHO, INPUT);

}



// ==========================================

// PROGRAMA PRINCIPAL

// ==========================================


void loop() {


  float distancia = medirDistancia();


  if (distancia > DISTANCIA_MINIMA) {


    adelante();


  } 

  else {


    detener();

    delay(300);


    atras();

    delay(300);


    detener();

    delay(200);


    derecha();

    delay(600);


    detener();

    delay(200);

  }

}

lunes, 7 de septiembre de 2026

MINI FLASK

 

CLIC AQUI PARA DESCARGAR MINI_FLASK


ATENTOS A LAS INSTRUCCIONES DEL PROFESOR:

CODIGO ADICIONADO:

TEMA: Control de Usuarios y Sesiones en Flask

En esta guía vamos a revisar el código que hemos añadido a nuestra aplicación (app.py) para lograr que cada usuario tenga su propio nombre, inicie sesión y se valide que el nombre ingresado sea correcto.


Para lograr esto, utilizamos algo llamado Sesiones (session). Una sesión es como una memoria temporal que el servidor guarda de cada usuario mientras navega por la página.


A continuación, explicamos cada bloque de código paso a paso:


1. Importar la herramienta y configurar la llave secreta

python


from flask import Flask, render_template, request, redirect, session

app = Flask(__name__)

app.secret_key = 'clave_secreta_super_segura' # Necesario para usar 'session'

¿Qué hicimos? Agregamos session a la lista de importaciones de Flask.

¿Por qué la llave secreta? Para que Flask pueda usar sesiones, necesita encriptar los datos (protegerlos para que nadie los pueda modificar). La secret_key es la contraseña maestra que usa Flask para esto. ¡En un proyecto real, esta clave no debe ser compartida!

2. La ruta de Inicio de Sesión (Login)

python


@app.route("/login", methods=["GET", "POST"])

def login():

    error = None

    if request.method == "POST":

        nombre = request.form.get("nombre")

        

        # Validar que el nombre tenga al menos 10 caracteres

        if nombre and len(nombre.strip()) >= 10:

            session['nombre'] = nombre.strip()

            return redirect("/")

        else:

            error = "El nombre debe tener al menos 10 caracteres."

    

    return render_template("login.html", error=error)

¿Cómo funciona?


Recibimos el nombre del formulario HTML a través de request.form.get("nombre").

Validación: Usamos len(nombre.strip()) >= 10. strip() borra los espacios en blanco al principio y al final para que no hagan trampa. Luego verificamos que la longitud del texto sea de 10 caracteres o más.

Guardar en la Sesión: Si la validación es exitosa, guardamos el nombre usando session['nombre'] = nombre.strip(). De esta forma, Flask recordará a este usuario.

Manejo de errores: Si el nombre es muy corto, guardamos un mensaje de error y lo enviamos al archivo login.html para que el usuario sepa qué hizo mal.

3. Proteger nuestra página principal (Index)

Ahora que tenemos un login, no queremos que cualquier persona pueda ver o enviar mensajes si no se ha registrado antes.


python


@app.route("/", methods=["GET", "POST"])

def inicio():

    # Verificar si el usuario ha iniciado sesión

    if 'nombre' not in session:

        return redirect("/login")

El portero del club: La instrucción if 'nombre' not in session: verifica si el usuario actual tiene su nombre guardado en la "memoria". Si no lo tiene, lo mandamos expulsado al /login usando redirect("/login").

4. Guardar mensajes con el nombre del usuario

Dentro de la misma ruta /, cuando el usuario envía un mensaje nuevo:


python


        # Validar que no envíen mensajes vacíos

        if texto and texto.strip() != "":

            # Usamos insert(0, ...) para agregar el mensaje al inicio de la lista

            mensajes.insert(0, {"nombre": session['nombre'], "texto": texto})

Ahora nuestros mensajes ya no son textos simples, sino Diccionarios de Python que guardan dos cosas: quién lo escribió ("nombre") y qué dijo ("texto").

En lugar de pedirle el nombre en el formulario principal, ¡lo sacamos de session['nombre']! Es más seguro y cómodo.

Al final de la ruta /, le enviamos a nuestra plantilla HTML la lista de mensajes y también el nombre del usuario conectado para saludarlo en pantalla:


python


    return render_template("index.html", mensajes=mensajes, nombre_usuario=session['nombre'])

5. Cerrar Sesión (Logout)

Por último, todo buen sistema debe permitirle al usuario salir de su cuenta.


python


@app.route("/logout")

def logout():

    session.pop('nombre', None)

    return redirect("/login")

¿Qué hace pop? Busca la clave 'nombre' dentro de la memoria de la sesión y la elimina. Una vez eliminada, el usuario es redirigido al /login y como ya no tiene su nombre guardado, no podrá entrar hasta volver a registrarse.

TIP


Resumen para recordar:


session['llave'] = valor -> Guardar un dato temporal.

session['llave'] -> Leer el dato que guardamos.

session.pop('llave', None) -> Borrar el dato de la memoria.


TEORIA

 ¿Qué son las Sesiones y por qué son Vitales?

Para entender las sesiones, primero hay que entender un problema fundamental de la web: Internet sufre de "amnesia".


El protocolo que usamos para navegar por internet (HTTP) es "sin estado" (stateless). Esto significa que cada vez que haces clic en un enlace o envías un formulario, para el servidor eres un completo desconocido. El servidor no tiene memoria de lo que hiciste hace 2 segundos.


¿El problema? Si el servidor no tiene memoria:


Inicias sesión en una página, pero al hacer clic en tu perfil, el servidor te olvida y te vuelve a pedir la contraseña.

Agregas unos zapatos a un carrito de compras, pero al ir a pagar, el carrito está vacío porque el servidor olvidó quién eres.

La Solución: Las Sesiones (session)

Una sesión es un mecanismo que le da memoria temporal al servidor sobre un usuario específico.


Funciona como un brazalete VIP en una discoteca:


Cuando el usuario inicia sesión (muestra su ID en la entrada), el servidor verifica que sea válido.

Si es válido, el servidor le da un "brazalete virtual" (una Cookie encriptada) que se guarda en el navegador web del usuario.

Cada vez que el usuario va a otra página del sitio web, su navegador muestra automáticamente el brazalete.

El servidor ve el brazalete, dice "¡Ah! Ya sé quién eres" y le deja pasar sin pedirle la contraseña de nuevo.

¿Por qué es tan importante manejar bien las Sesiones?

Identidad (Logins): Es la única forma de mantener a un usuario conectado mientras navega por diferentes páginas (como Facebook, Netflix o el correo electrónico).

Personalización: Permite recordar preferencias del usuario, como el modo oscuro, el idioma elegido o el contenido de su carrito de compras.

Seguridad (Control de Acceso): Nos permite proteger rutas. Gracias a las sesiones, podemos decirle al servidor: "Si alguien intenta entrar a la página principal y no tiene el brazalete de la sesión, échalo y envíalo al login" (exactamente lo que hicimos en nuestro código).

domingo, 23 de agosto de 2026

TEORIA GENERAL COMPLEMENTARIA PYTHON

 TEORIA GENERAL COMPLEMENTARIA PYTHON

TRANSCRIBIR EN EL CUADERNO, PREPARARSE PARA PREGUNTAS LA PROXIMA CLASE

1. ¿Qué es Flask? (Recordando)

Flask es un microframework para Python que permite crear aplicaciones web.

Un framework es un conjunto de herramientas y estructuras que facilitan el desarrollo de aplicaciones.

Flask permite que un programa escrito en Python pueda:

  • Crear páginas web.
  • Recibir información de los usuarios.
  • Procesar formularios.
  • Trabajar con bases de datos.
  • Crear sistemas de usuarios.
  • Crear aplicaciones administrativas.
  • Generar respuestas para navegadores.
  • Crear servicios y APIs.

Flask se caracteriza por ser sencillo y flexible, por lo que es apropiado para aprender cómo funciona una aplicación web desde sus fundamentos.


2. ¿Qué es app.py?

En una aplicación Flask, app.py suele ser el archivo principal de la aplicación.

Su función es coordinar el funcionamiento de la aplicación.

En términos sencillos:

app.py es el archivo que inicia la aplicación Flask, define sus rutas y determina qué debe hacer el programa cuando un usuario realiza una petición.

Por ejemplo, cuando un usuario escribe:

http://localhost:5000/

Flask recibe esa petición y busca dentro de app.py qué función está asociada a esa dirección.


3. ¿Qué es una aplicación web?

Una aplicación web funciona mediante la comunicación entre un cliente y un servidor.

El cliente normalmente es el navegador.

El servidor es el programa que recibe las solicitudes y genera las respuestas.

El proceso básico es:

NAVEGADOR
    
PETICIÓN
    
SERVIDOR FLASK
    
PROCESAMIENTO
    
RESPUESTA
    
NAVEGADOR

Por ejemplo:

Un estudiante escribe en el navegador:

http://localhost:5000/

El navegador realiza una petición al servidor.

Flask recibe la petición.

Flask determina qué función debe ejecutarse.

La función procesa la información.

Finalmente Flask devuelve una respuesta al navegador.


4. ¿Qué es una petición HTTP?

Una petición HTTP es una solicitud que un navegador realiza a un servidor.

Existen diferentes métodos HTTP, pero los dos más importantes para comenzar son:

GET

Se utiliza principalmente para solicitar o consultar información.

Por ejemplo:

GET /usuarios

Significa:

"Quiero obtener la página o información correspondiente a usuarios."

POST

Se utiliza principalmente para enviar información al servidor.

Por ejemplo, cuando un usuario llena un formulario de registro:

POST /registro

El navegador envía los datos al servidor para que Python pueda procesarlos.


5. ¿Qué es una ruta?

Una ruta, o route, es la relación entre una dirección URL y una función de Python.

Por ejemplo:

@app.route("/")
def inicio():
    return "Hola mundo"

La expresión:

@app.route("/")

indica que la función inicio() responderá cuando alguien solicite:

/

Por lo tanto:

URL
/
ruta Flask
función Python
respuesta

Una aplicación puede tener muchas rutas.

Por ejemplo:

/              → página principal
/login         → inicio de sesión
/usuarios      → usuarios
/contacto      → contacto
/admin         → administración

6. ¿Qué es una función en Flask?

Una función es un bloque de código Python que realiza una determinada tarea.

Por ejemplo:

def saludo():
    return "Hola"

En Flask, una función puede estar asociada a una ruta:

@app.route("/saludo")
def saludo():
    return "Hola"

Cuando alguien visita:

/saludo

Flask ejecuta:

saludo()

y devuelve el resultado.


miércoles, 29 de julio de 2026

CARRO SEGUIDOR DE LÍNEA - TCRT5000

 

CARRO SEGUIDOR DE LÍNEA CON SENSOR INFRARROJO TCRT5000

Introducción

Un carro seguidor de línea es un robot móvil capaz de desplazarse automáticamente siguiendo una línea dibujada sobre una superficie. Generalmente, la línea es de color negro sobre un fondo blanco, aunque también puede funcionar de forma inversa si se configura adecuadamente.

Este tipo de robot constituye uno de los proyectos más importantes para iniciarse en la robótica móvil, ya que integra conocimientos de electrónica, programación, sensores y control de movimiento.

En este proyecto, el "cerebro" del robot es una placa Arduino, mientras que sus "ojos" son los sensores infrarrojos TCRT5000, encargados de detectar la posición de la línea durante el recorrido.


¿Qué es un robot seguidor de línea?

Un robot seguidor de línea es un sistema automático diseñado para desplazarse siguiendo un camino previamente marcado.

Su funcionamiento se basa en tres etapas fundamentales:

1.     Detectar la posición de la línea.

2.     Procesar la información recibida por los sensores.

3.     Controlar los motores para mantenerse sobre la trayectoria.

Todo este proceso ocurre cientos de veces por segundo.


¿Qué es el sensor TCRT5000?

El TCRT5000 es un sensor óptico infrarrojo de reflexión ampliamente utilizado en robótica educativa.

Su función consiste en detectar diferencias de color mediante la reflexión de luz infrarroja.

Está formado por dos componentes principales:

  • Un LED emisor infrarrojo.
  • Un fototransistor receptor.

El LED emite luz infrarroja continuamente hacia el suelo.

El fototransistor mide cuánta luz regresa después de reflejarse sobre la superficie.


Principio de funcionamiento

El sensor no detecta colores directamente.

Lo que realmente detecta es la cantidad de luz infrarroja reflejada.

Cuando la luz emitida golpea una superficie:

  • Si la superficie refleja mucha luz, el sensor recibe una señal alta.
  • Si la superficie absorbe la luz, el sensor recibe una señal baja.

¿Por qué distingue entre blanco y negro?

Los colores poseen diferentes propiedades de reflexión.

Superficie blanca

  • Refleja gran parte de la luz.
  • El sensor recibe mucha luz infrarroja.
  • Detecta un nivel alto de reflexión.

Superficie negra

  • Absorbe gran parte de la luz.
  • El sensor recibe muy poca luz.
  • Detecta un nivel bajo de reflexión.

Gracias a esta diferencia el robot puede identificar dónde se encuentra la línea.


Componentes principales del TCRT5000

El módulo normalmente incluye:

  • LED infrarrojo emisor.
  • Fototransistor receptor.
  • Comparador electrónico.
  • Potenciómetro para ajustar sensibilidad.
  • LED indicador.
  • Pines de alimentación y salida.

¿Qué hace el potenciómetro?

El potenciómetro permite ajustar la sensibilidad del sensor.

Con él es posible determinar qué cantidad de luz reflejada será considerada como blanco o negro.

Este ajuste depende de:

  • La iluminación del ambiente.
  • El color del piso.
  • El tipo de cinta utilizada.
  • La distancia entre el sensor y la superficie.

Importancia de la distancia

El sensor funciona mejor cuando se encuentra aproximadamente entre 2 mm y 10 mm de la superficie.

Si queda demasiado alto:

  • La reflexión disminuye.
  • Puede dejar de detectar correctamente la línea.

Si queda demasiado bajo:

  • Puede rozar el suelo.
  • Las mediciones pueden volverse inestables.

¿Por qué se utilizan dos sensores?

Un solo sensor únicamente puede indicar si está sobre la línea o fuera de ella.

Con dos sensores el robot puede conocer la posición relativa de la línea.

Normalmente se colocan:

  • Sensor izquierdo.
  • Sensor derecho.

Así el robot puede decidir hacia dónde debe girar.


Interpretación de los sensores

Ambos sensores detectan blanco

El robot ha perdido la línea.

Debe buscar nuevamente la trayectoria.


Ambos sensores detectan negro

El robot se encuentra completamente sobre la línea o ha llegado a una intersección.


Sensor izquierdo detecta negro

La línea se encuentra hacia la izquierda.

El robot debe corregir su trayectoria hacia ese lado.


Sensor derecho detecta negro

La línea está hacia la derecha.

El robot debe girar ligeramente hacia la derecha.


El cerebro del robot: Arduino

Arduino recibe continuamente la información de los sensores.

Después toma decisiones para controlar los motores.

El proceso ocurre de manera repetitiva:

1.     Leer sensores.

2.     Analizar información.

3.     Decidir movimiento.

4.     Mover motores.

5.     Volver a comenzar.

Este ciclo se ejecuta muchas veces por segundo.


Importancia de la calibración

Antes de utilizar el robot es necesario calibrar los sensores.

Una mala calibración puede provocar:

  • Que no detecte la línea.
  • Que gire continuamente.
  • Que avance en zigzag.
  • Que se salga del recorrido.

Una buena calibración mejora considerablemente el desempeño del robot.


Factores que afectan el funcionamiento

Existen varios factores que pueden alterar las lecturas del sensor.

Iluminación

Una luz solar intensa puede interferir con la luz infrarroja.


Color del piso

No todos los pisos blancos reflejan igual cantidad de luz.


Tipo de cinta

Las cintas negras mate suelen funcionar mejor que las brillantes.


Polvo

La suciedad puede reducir la reflexión de la luz.


Vibraciones

Si el robot vibra demasiado, las lecturas pueden cambiar constantemente.


Ventajas del sensor TCRT5000

  • Bajo costo.
  • Fácil de utilizar.
  • Alta velocidad de respuesta.
  • Bajo consumo de energía.
  • Excelente para proyectos educativos.
  • Compatible con Arduino.
  • Muy utilizado en competencias de robótica.

Limitaciones

  • Depende de una buena iluminación.
  • Requiere calibración.
  • Funciona mejor a corta distancia.
  • No identifica colores; solamente mide reflexión.
  • Puede verse afectado por superficies muy brillantes.

Aplicaciones del sensor TCRT5000

El TCRT5000 no solo se utiliza en robots seguidores de línea.

También tiene aplicaciones industriales y comerciales.

Entre ellas:

  • Robots seguidores de línea.
  • Robots de reparto.
  • Vehículos autónomos educativos.
  • Detección de objetos cercanos.
  • Conteo de piezas en bandas transportadoras.
  • Sistemas automáticos de clasificación.
  • Detección de marcas de posición.
  • Robots de competencias.
  • Sistemas de automatización industrial.
  • Sensores de presencia de objetos pequeños.

Aplicaciones de los robots seguidores de línea

Aunque suelen emplearse con fines educativos, también tienen aplicaciones reales.

En la industria

  • Transporte automático de materiales.
  • Movimiento de herramientas.
  • Distribución de piezas.
  • Líneas de ensamblaje.

En hospitales

  • Transporte de medicamentos.
  • Distribución de alimentos.
  • Entrega de muestras de laboratorio.

En bodegas

  • Transporte de cajas.
  • Organización de inventarios.
  • Distribución automática de productos.

En aeropuertos

  • Transporte automático de equipaje.
  • Vehículos de mantenimiento.

En agricultura

  • Robots para inspección de cultivos.
  • Transporte de pequeñas cargas.

En educación

  • Enseñanza de programación.
  • Electrónica.
  • Robótica.
  • Automatización.
  • Inteligencia artificial.

Competencias de robótica

Los robots seguidores de línea participan en numerosas competencias nacionales e internacionales.

Durante estas pruebas se evalúan aspectos como:

  • Velocidad.
  • Precisión.
  • Estabilidad.
  • Tiempo de respuesta.
  • Calidad de la programación.
  • Diseño mecánico.

Relación con otras áreas

Este proyecto integra conocimientos de diferentes asignaturas:

  • Matemáticas: medición de distancias, ángulos y lógica.
  • Física: reflexión de la luz, movimiento y velocidad.
  • Tecnología: diseño y construcción del robot.
  • Electrónica: sensores, motores y circuitos.
  • Programación: desarrollo de algoritmos de control.
  • Ingeniería: integración de sistemas mecánicos y electrónicos.

Conceptos clave

  • Sensor: dispositivo que detecta cambios en el entorno.
  • Infrarrojo: tipo de luz invisible para el ojo humano.
  • Reflexión: rebote de la luz sobre una superficie.
  • Calibración: ajuste para obtener mediciones correctas.
  • Automatización: realización de tareas sin intervención humana.
  • Algoritmo: conjunto ordenado de instrucciones para resolver un problema.
  • Control: proceso mediante el cual el robot toma decisiones para corregir su trayectoria.

Conclusión

El carro seguidor de línea representa uno de los proyectos más importantes para iniciarse en la robótica, ya que combina sensores, programación, electrónica y control automático. El sensor TCRT5000 permite detectar la diferencia entre superficies claras y oscuras mediante la reflexión de luz infrarroja, mientras que Arduino procesa esa información para controlar el movimiento del robot en tiempo real. Comprender estos principios constituye la base para desarrollar sistemas más avanzados, como robots autónomos, vehículos inteligentes y aplicaciones de automatización industrial.

 

CONTINUACION CONCEPTOS PYTHON - FLASK

 CONTINUACION CONCEPTOS FUNDAMENTALES EN PYTHON

LAS CONSTANTES

¿Qué es una constante?

Una constante es un dato que no debería cambiar durante el programa.

Python no tiene constantes verdaderas como otros lenguajes.

Por convenio se escriben con letras MAYÚSCULAS.

Ejemplo

PI = 3.1416

IVA = 19

MAX_ESTUDIANTES = 40

Aunque Python permite cambiar el valor:

IVA = 20

No se recomienda hacerlo.


Diferencia entre variable y constante

Variable

Constante

Su valor puede cambiar.

Su valor no debería cambiar.

Se escribe normalmente en minúsculas.

Se escribe en MAYÚSCULAS.

Se usa para almacenar datos del programa.

Se usa para valores fijos.


Comentarios

Los comentarios sirven para explicar el código.

Python los ignora.

Ejemplo

# Esta variable guarda el nombre del estudiante

nombre = "Carlos"


Operadores matemáticos

Operador

Significado

+

Suma

-

Resta

*

Multiplicación

/

División

//

División entera

%

Residuo

**

Potencia


Concatenación

Consiste en unir textos.

nombre = "Ana"

apellido = "Gómez"

print(nombre + " " + apellido)

Resultado

Ana Gómez


Variables dentro de Flask

En Flask también utilizamos variables.

Ejemplo

from flask import Flask

app = Flask(__name__)

@app.route("/")

def inicio():

    mensaje = "Bienvenidos al curso de Flask"

    return mensaje

app.run()

La variable mensaje guarda el texto que será enviado al navegador.


Variables enviadas a una página HTML

En Flask podemos enviar variables al archivo HTML.

from flask import Flask, render_template

app = Flask(__name__)

@app.route("/")

def inicio():

    nombre = "Carlos"

    return render_template("index.html", nombre=nombre)

app.run()

En el archivo index.html

<h1>{{ nombre }}</h1>

El navegador mostrará

Carlos


Variables Globales

Son variables que pueden ser utilizadas por varias funciones.

Ejemplo

colegio = "Colegio Trinitario"

@app.route("/")

def inicio():

    return colegio


Variables Locales

Solo existen dentro de una función.

@app.route("/")

def inicio():

    saludo = "Hola"

    return saludo

La variable saludo solamente existe dentro de la función inicio().

CODIGO CARRO EVASOR DE OBSTACULOS

 CODIGO CARRO EVASOR DE OBSTACULOS // ========================================== // EVASOR DE OBSTACULOS // Arduino UNO + L298N + HC-SR04 //...