Vamos a montar un sistema que detecte obstáculos mediante un sensor ultrasónico HC-SR04 y utilice un servomotor SG90 para señalar la dirección que está libre.
La idea es construir un pequeño radar inteligente: cuando detecte un obstáculo delante, el sensor mirará hacia la izquierda y hacia la derecha, comparará las distancias y el servo terminará apuntando hacia el lado con más espacio disponible.
1. Material necesario
Arduino UNO o Arduino Mega 2560.
Sensor ultrasónico HC-SR04.
Servomotor SG90 de 180°.
Cables Dupont.
Protoboard (opcional).
Cable USB para programar el Arduino.
2. Conexiones
Sensor ultrasónico HC-SR04
Pin del sensor
Arduino
VCC
5V
GND
GND
TRIG
Digital 9
ECHO
Digital 10
Servomotor SG90
Cable del servo
Arduino
Marrón (GND)
GND
Rojo (alimentación)
5V
Naranja (señal)
Digital 6
Para una prueba sencilla, un SG90 sin carga puede funcionar alimentado por el Arduino. Si hay reinicios, movimientos erráticos o el servo soporta peso, utiliza una fuente externa de 5 V adecuada, compartiendo GND con Arduino. No conectes el servo directamente a una fuente de 12 V.
3. Funcionamiento del proyecto
Ejemplo: el sistema detecta un obstáculo frontal y elige la izquierda porque mide una distancia mayor.
El programa seguirá esta secuencia:
El servo coloca el sensor mirando al frente (90°).
El HC-SR04 mide la distancia.
Si el obstáculo está a menos de 20 cm, comienza la exploración.
El servo gira a 150° para medir la izquierda y a 30° para medir la derecha.
Compara las dos distancias.
El servo se queda apuntando hacia la dirección con más espacio libre durante dos segundos y vuelve al centro.
4. Código completo de Arduino
Puedes copiar directamente este programa en Arduino IDE. No necesitas instalar bibliotecas adicionales: Servo.h viene incluida normalmente con el entorno de placas Arduino AVR.
#include <Servo.h>
// Pines del sensor ultrasónico
const int TRIG = 9;
const int ECHO = 10;
// Pin del servomotor
const int PIN_SERVO = 6;
// Ángulos del servo
const int CENTRO = 90;
const int IZQUIERDA = 150;
const int DERECHA = 30;
// Distancia mínima de seguridad (cm)
const int DISTANCIA_ALERTA = 20;
Servo radar;
// Función para medir distancia en centímetros
long medirDistancia() {
digitalWrite(TRIG, LOW);
delayMicroseconds(2);
digitalWrite(TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG, LOW);
// Esperar respuesta como máximo 30 ms
unsigned long duracion = pulseIn(ECHO, HIGH, 30000UL);
// Sin eco: consideramos distancia máxima
if (duracion == 0) {
return 400;
}
return duracion / 58;
}
// Orientar sensor y realizar medición
long mirar(int angulo) {
radar.write(angulo);
delay(600); // Esperar al movimiento del servo
return medirDistancia();
}
void setup() {
Serial.begin(9600);
pinMode(TRIG, OUTPUT);
pinMode(ECHO, INPUT);
radar.attach(PIN_SERVO);
radar.write(CENTRO);
delay(1000);
Serial.println("Sistema detector de obstaculos");
}
void loop() {
// 1. Miramos hacia delante
long frente = mirar(CENTRO);
Serial.print("Distancia frontal: ");
Serial.print(frente);
Serial.println(" cm");
// 2. Si hay un obstáculo cercano
if (frente < DISTANCIA_ALERTA) {
Serial.println("OBSTACULO DETECTADO");
// 3. Explorar izquierda
long distanciaIzquierda = mirar(IZQUIERDA);
Serial.print("Izquierda: ");
Serial.print(distanciaIzquierda);
Serial.println(" cm");
// 4. Explorar derecha
long distanciaDerecha = mirar(DERECHA);
Serial.print("Derecha: ");
Serial.print(distanciaDerecha);
Serial.println(" cm");
// 5. Elegir dirección con más espacio
if (distanciaIzquierda > distanciaDerecha) {
Serial.println("Direccion recomendada: IZQUIERDA");
radar.write(IZQUIERDA);
} else if (distanciaDerecha > distanciaIzquierda) {
Serial.println("Direccion recomendada: DERECHA");
radar.write(DERECHA);
} else {
Serial.println("Distancias iguales");
radar.write(CENTRO);
}
// 6. Mantener la dirección indicada
delay(2000);
// Volver al centro
radar.write(CENTRO);
delay(600);
} else {
Serial.println("Camino frontal despejado");
}
delay(300);
}
5. Prueba del funcionamiento
Abre el Monitor Serie del Arduino IDE y selecciona una velocidad de 9600 baudios.
Coloca un objeto a unos 10 cm del sensor. Deberías ver algo parecido a esto:
Distancia frontal: 12 cm
OBSTACULO DETECTADO
Izquierda: 85 cm
Derecha: 30 cm
Direccion recomendada: IZQUIERDA
El servo apuntará hacia la izquierda durante dos segundos y después regresará a su posición central.
Puedes modificar la sensibilidad cambiando esta línea:
const int DISTANCIA_ALERTA = 20;
Por ejemplo, puedes cambiar 20 por 40 para que comience a buscar caminos alternativos cuando detecte algo a menos de 40 cm.
6. Montaje físico
Es importante que el sensor HC-SR04 esté sujeto a la parte móvil del servo. De esta manera, cuando el motor gira, también gira el sensor y puede medir las distancias en diferentes direcciones.
Ten en cuenta que los ángulos de izquierda y derecha pueden estar invertidos según cómo coloques físicamente el servomotor. Si ocurre, intercambia los valores 150 y 30.
El código considera una ausencia de eco como 400 cm. Esto es útil para una demostración, pero no demuestra que exista un camino libre: también puede significar que el sensor no ha recibido una reflexión válida.
7. Actividad adicional para los alumnos
Una vez terminado el montaje, puedes pedirles que mejoren el proyecto incorporando tres condiciones diferentes:
Verde: no hay obstáculos a menos de 20 cm.
Amarillo: hay un obstáculo, pero se encuentra una dirección alternativa.
Rojo: las dos direcciones exploradas tienen obstáculos a menos de 20 cm.
Nivel: Iniciación a robótica y programación Arduino
Objetivo: Controlar motores de corriente continua, variar su velocidad, invertir su giro y realizar un pequeño proyecto de vehículo robot.
1. ¿Qué placa tenemos?
La placa de tu fotografía es una Motor Shield L293D V1.0, compatible con el diseño Adafruit Motor Shield V1.
Se conecta directamente sobre el Arduino Mega 2560 y permite controlar motores sin tener que construir manualmente el circuito electrónico de potencia.
La compatibilidad con Arduino Mega 2560 está documentada para este diseño de shield.
Características principales
Elemento
Capacidad
Motores DC
Hasta 4 independientes
Motores paso a paso
Hasta 2
Servomotores
2 conectores
Control de velocidad
PWM, valores de 0 a 255
Inversión de giro
Sí
Controladores principales
2 × L293D
Corriente por canal
600 mA continuos, 1,2 A de pico
Biblioteca
AFMotor
Importante: aunque el circuito L293D admite diferentes tensiones, la alimentación de los motores debe elegirse según los motores utilizados. Además, los L293D producen una caída de tensión apreciable y no son adecuados para motores de gran consumo.
Selección de alimentación compartida o independiente
RESET
Reinicio del Arduino
LED
Indicador de alimentación de motores
El shield utiliza determinados pines digitales del Arduino Mega para gestionar internamente los motores. Por ello, no debemos asignar libremente esos mismos pines a otros dispositivos.
3. Material necesario
Para la primera prueba necesitaremos:
Un Arduino Mega 2560.
La placa Motor Shield L293D V1.0.
Un motor DC pequeño, preferiblemente de 6 V.
Una fuente de alimentación adecuada al motor.
Un cable USB para programar el Arduino.
Un ordenador con Arduino IDE.
Un destornillador pequeño para los bornes.
Para posteriores prácticas podremos incorporar otros tres motores, ruedas, un chasis, servomotores y sensores.
4. Montaje sobre el Arduino Mega 2560
Desconectamos el Arduino del ordenador y de cualquier alimentación.
Colocamos el Motor Shield encima del Mega, haciendo coincidir las filas de pines del shield con los conectores correspondientes del Arduino.
Comprobamos la orientación y que no haya ningún pin desplazado.
Presionamos suavemente hasta que los conectores estén completamente introducidos.
Verificamos que ningún terminal metálico esté produciendo un cortocircuito.
No debemos intentar conectar el shield a todos los conectores del Mega: este modelo utiliza principalmente la distribución de pines del Arduino UNO, que también está presente en el Mega.
5. Alimentación de los motores
Esta es una de las partes más importantes del montaje.
El Arduino Mega necesita energía para ejecutar el programa, mientras que los motores necesitan energía para moverse.
La mejor opción para las prácticas es utilizar alimentaciones independientes.
Esquema conceptual de alimentación independiente.
Alimentación recomendada para las pruebas
Arduino Mega conectado al ordenador mediante USB.
Fuente externa para los motores conectada a EXT_PWR.
Jumper de alimentación PWR retirado.
Cable positivo de la fuente conectado a + y negativo conectado a − del bloque de alimentación.
Precaución: verifica la polaridad impresa en tu placa antes de conectar la fuente. No utilices la salida de 5 V del Arduino para alimentar directamente los motores. Tampoco utilices una pila rectangular de 9 V como solución habitual para varios motores, porque suele entregar poca corriente.
Si se conectan motores pequeños de 6 V, una fuente regulada de 6 V con corriente suficiente puede ser apropiada, teniendo en cuenta que la tensión efectiva en el motor será algo menor debido al L293D.
La alimentación de los servomotores se trata por separado porque los conectores SERVO toman normalmente sus 5 V del Arduino.
Programa → Incluir librería → Añadir biblioteca .ZIP
Seleccionamos el archivo descargado.
Una vez instalada, comprobamos que podemos incluirla en un programa:
#include <AFMotor.h>
El Arduino Mega 2560 está contemplado expresamente en el código de esta biblioteca.
blog.adafruit.com
+1
Parte práctica: nuestros primeros programas
8. Práctica 1. Hacer girar un motor
Objetivo: conseguir que un motor conectado a M1 funcione durante tres segundos y después se detenga.
Conexiones
Con el circuito desconectado, conectamos los dos cables del motor al borne M1.
Retiramos el jumper PWR.
Conectamos una fuente adecuada a EXT_PWR.
Conectamos el Arduino Mega mediante USB.
Cargamos el programa.
Código completo
#include <AFMotor.h>
// Motor conectado al borne M1
AF_DCMotor motor1(1);
void setup() {
// Velocidad entre 0 y 255
motor1.setSpeed(150);
}
void loop() {
// Girar hacia delante
motor1.run(FORWARD);
delay(3000);
// Detener el motor
motor1.run(RELEASE);
delay(2000);
}
¿Qué hace el programa?
AF_DCMotor motor1(1); crea un objeto que representa el motor conectado a M1.
setSpeed(150) establece un valor de velocidad PWM. No significa exactamente 150 revoluciones por minuto, sino un nivel de control dentro de la escala 0–255.
run(FORWARD) ordena girar al motor en uno de los sentidos.
run(RELEASE) deja de alimentar el motor y permite que se detenga libremente. No aplica un frenado activo.
delay(3000) mantiene el programa esperando tres segundos.
Resultado esperado: el motor gira durante tres segundos, se detiene dos segundos y repite el proceso.
9. Práctica 2. Invertir el sentido de giro
Vamos a conseguir que el mismo motor gire alternativamente en ambos sentidos.
El motor acelera hasta alcanzar el máximo valor PWM, comienza a reducir su velocidad y finalmente se detiene.
A velocidades muy bajas es posible que el motor no se mueva, aunque reciba una señal PWM. Esto depende de la fricción y de las características del motor.
11. Práctica 4. Controlar cuatro motores simultáneamente
Conectamos cuatro motores, cada uno a su correspondiente borne M1, M2, M3 y M4.
Resultado esperado: los cuatro motores giran simultáneamente durante tres segundos y se detienen durante dos.
La etiqueta FORWARD no garantiza que todas las ruedas giren hacia delante físicamente, porque depende de cómo estén colocados los motores y de la polaridad de sus cables.
Antes de utilizar los cuatro motores, debemos comprobar que el consumo individual y total es compatible con el shield y con la fuente de alimentación.
12. Práctica 5. Controlar un servomotor
La placa dispone de dos conexiones para servomotores. Podemos utilizarlas, por ejemplo, para girar un sensor de ultrasonidos instalado en un coche robot.
Conectaremos un servomotor SG90 a SERVO1, respetando el orden de señal, positivo y negativo indicado en la placa.
El conector SERVO1 corresponde al pin digital 9 y SERVO2 al pin 10.
Resultado esperado: el servomotor se mueve a tres posiciones, esperando un segundo entre ellas.
Los servomotores reciben alimentación de 5 V desde el Arduino en la configuración habitual del shield. Si se utilizan varios servos o modelos de elevado consumo, habrá que estudiar una alimentación independiente apropiada para evitar reinicios y sobrecargas.
13. Pines utilizados por el Motor Shield
Esta información resulta especialmente importante cuando queramos incorporar sensores al Arduino Mega.
Pines digitales
Utilización
11
Velocidad M1
3
Velocidad M2
5
Velocidad M3
6
Velocidad M4
4, 7, 8, 12
Control interno de dirección
9
SERVO1
10
SERVO2
2 y 13
Disponibles
Los pines indicados corresponden al diseño V1. Los demás pines libres del Mega pueden aprovecharse para sensores, siempre comprobando que no exista conflicto con otros módulos.
Adafruit Learning System
14. Proyecto final: coche robot de cuatro motores
Una vez comprobado el funcionamiento de la placa, podremos construir un vehículo utilizando cuatro motores DC.
Importante: este ejemplo supone que los motores están conectados de forma que FORWARD mueve todas las ruedas hacia delante. Habrá que invertir los cables o ajustar el programa de aquellos motores que giren en sentido contrario. Es preferible hacer la primera prueba con el vehículo levantado, sin que las ruedas toquen el suelo.
Además, comprueba la corriente de bloqueo de cada motor. Los motores TT de algunos kits pueden superar los límites del L293D al arrancar o quedarse atascados.
15. Solución de problemas
Problema
Posible solución
El código no compila porque falta AFMotor.h
Instalar la biblioteca AFMotor V1
El motor no gira
Comprobar fuente externa, LED indicador y conexiones
El motor gira al revés
Intercambiar sus dos cables o invertir el comando
El Arduino se reinicia al arrancar el motor
Revisar alimentación y consumo
El motor no gira con PWM bajo
Aumentar el valor de setSpeed()
El L293D se calienta demasiado
Detener el ensayo y comprobar consumo y posibles bloqueos
Los cuatro motores no funcionan simultáneamente
Comprobar fuente, conexiones y corriente de cada motor
16. Actividades de evaluación
Para comprobar que se ha comprendido el funcionamiento, los alumnos deberán resolver estas actividades:
Hacer que M1 gire cinco segundos hacia delante y otros cinco hacia atrás.
Conseguir que M1 y M2 giren a distintas velocidades.
Programar una aceleración progresiva de 0 a 255.
Poner en marcha los cuatro motores y detenerlos en orden inverso.
Crear las funciones avanzar(), retroceder(), izquierda(), derecha() y detener().
Diseñar un recorrido para que un coche describa aproximadamente un cuadrado, ajustando experimentalmente los tiempos de giro.
Incorporar un servomotor que mire alternativamente a izquierda, centro y derecha.
Siguiente paso recomendado: comenzar probando un único motor DC en M1 y, una vez verificada la alimentación y el funcionamiento, conectar los cuatro motores.
Para el proyecto del coche con Arduino Mega, cuatro motores y sensor de ultrasonidos sobre un servomotor, esta placa es una buena opción didáctica siempre que los motores no superen su capacidad eléctrica.
En este proyecto aprenderás a utilizar los componentes que más adelante formarán parte de un coche robot de cuatro motores.
Antes de construir el coche completo, trabajaremos por etapas para comprender qué hace cada componente, cómo se conecta y cómo se controla desde un programa.
El proyecto se divide en dos partes:
Parte
Qué vamos a trabajar
Resultado
Parte 1. Medir y observar el entorno
Sensor de ultrasonidos, servomotor y combinación de ambos
Un escáner que mide distancias en distintas direcciones
Parte 2. Controlar el movimiento
Motores DC, controlador L293D y combinación con el sensor
Un montaje de banco que detiene los motores ante un obstáculo
En la primera parte no conectaremos motores DC ni el controlador L293D. El servomotor se utilizará para orientar el sensor.
El coche completo será una fase posterior. En estas dos partes nos centraremos en comprender y comprobar sus componentes.
Objetivos generales
Al finalizar el proyecto deberás ser capaz de:
Identificar los cables y conexiones de cada componente.
Distinguir entre un sensor y un actuador.
Medir distancias con un HC-SR04.
Colocar un servo en diferentes posiciones.
Combinar el servo y el sensor para observar distintas direcciones.
Controlar el sentido y la velocidad de motores DC mediante un L293D.
Utilizar una lectura del sensor para tomar una decisión.
Documentar los montajes y explicar los resultados.
Forma de trabajo
En cada práctica seguirás este proceso:
Comprender: lee qué hace el componente y para qué sirve.
Predecir: escribe qué esperas que ocurra.
Montar: realiza las conexiones con la alimentación desconectada.
Programar: introduce el código y súbelo al Arduino.
Comprobar: observa el resultado y registra las pruebas.
Modificar: cambia una parte del programa y explica su efecto.
No basta con conseguir que el montaje funcione. Debes poder explicar por qué funciona.
Parte 1. Medir y observar el entorno
Material necesario
Arduino Uno R3 y cable USB.
Sensor de ultrasonidos HC-SR04.
Servomotor de posición SG90 o similar.
Fuente regulada de 5 V adecuada para el servo.
Cables y protoboard.
Regla o cinta métrica.
Una caja o superficie plana para realizar las mediciones.
Un soporte ligero para colocar el sensor sobre el servo.
Preparación del entorno
Antes de comenzar:
Abre Arduino IDE.
Selecciona la placa Arduino Uno.
Selecciona el puerto al que está conectado el Arduino.
Crea un programa diferente para cada práctica.
Guarda los programas con estos nombres:
01_ultrasonidos
02_servo
03_escaner
Mapa de conexiones de esta parte
Componente
Conexión al Arduino
HC-SR04: VCC
5V
HC-SR04: GND
GND
HC-SR04: TRIG
D12
HC-SR04: ECHO
D13
Señal del servo
D9
Alimentación del servo
Fuente externa regulada de 5 V
GND de la fuente del servo
Unido al GND del Arduino
Práctica 1. Medir distancias con ultrasonidos
Qué vamos a aprender
El HC-SR04 permite medir la distancia hasta un objeto.
Para hacerlo:
El Arduino envía una orden por el pin TRIG.
El sensor emite una señal ultrasónica.
La señal rebota en el objeto.
El sensor comunica por ECHO el tiempo asociado al recorrido.
Como el sonido viaja hasta el objeto y vuelve, debemos dividir el recorrido entre dos.
Conexiones
Pin del HC-SR04
Arduino Uno
VCC
5V
GND
GND
TRIG
D12
ECHO
D13
Comprueba los nombres impresos en el sensor antes de conectar los cables.
Montaje paso a paso
Desconecta el cable USB del Arduino.
Conecta VCC a 5V.
Conecta GND a GND.
Conecta TRIG a D12.
Conecta ECHO a D13.
Coloca el sensor de forma que sus dos cápsulas apunten hacia la zona que quieres medir.
Revisa las conexiones antes de conectar el USB.
Programa
const byte TRIG = 12;
const byte ECHO = 13;
float medirCm() {
// Preparar el disparo.
digitalWrite(TRIG, LOW);
delayMicroseconds(2);
// Enviar el pulso de disparo.
digitalWrite(TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG, LOW);
// Esperar el eco, con un límite de tiempo.
unsigned long tiempo = pulseIn(ECHO, HIGH, 30000UL);
// Un resultado de cero significa que no llegó el eco.
if (tiempo == 0) {
return -1.0;
}
// Convertir el tiempo en distancia.
return tiempo * 0.0343 / 2.0;
}
void setup() {
pinMode(TRIG, OUTPUT);
pinMode(ECHO, INPUT);
Serial.begin(9600);
}
void loop() {
float distancia = medirCm();
if (distancia < 0) {
Serial.println("Sin eco");
} else {
Serial.print("Distancia: ");
Serial.print(distancia, 1);
Serial.println(" cm");
}
delay(100);
}
Cómo comprobarlo
Sube el programa.
Abre el Monitor serie a 9600 baudios.
Coloca una caja plana aproximadamente a 10 cm.
Mide la distancia real con una regla.
Repite a 20 y 40 cm.
Inclina la caja y observa si cambia la lectura.
Retira el objeto y observa qué sucede.
Tabla de resultados
Distancia medida con regla
Lectura del sensor
Diferencia
10 cm
20 cm
40 cm
Resultado esperado
La distancia mostrada cambia al mover el objeto.
Cuando no se recibe el eco dentro del tiempo de espera, aparece «Sin eco». Esto no significa que el objeto esté a cero centímetros.
Modificación obligatoria
Modifica el programa para que, además de la distancia, muestre:
«Objeto cercano» cuando la distancia sea de 20 cm o menos.
«Objeto alejado» cuando supere los 20 cm.
«Sin eco» cuando no exista una lectura.
Preguntas
¿Qué función tiene TRIG?
¿Qué función tiene ECHO?
¿Por qué dividimos entre dos?
¿Por qué una superficie inclinada puede afectar a la lectura?
¿Por qué no debemos interpretar «Sin eco» como cero centímetros?
Práctica 2. Controlar la posición de un servo
Qué vamos a aprender
Un servo de posición permite mover su eje hasta un ángulo determinado.
Lo utilizaremos para orientar el sensor de ultrasonidos hacia diferentes direcciones.
Este servo recibe una orden de posición. Su funcionamiento es distinto al de los motores DC que harán girar las ruedas.
Conexiones
Cable del servo
Conexión
Señal, normalmente naranja o amarillo
D9 del Arduino
Rojo
Positivo de la fuente regulada de 5 V
Marrón o negro
GND de la fuente
GND de la fuente
GND del Arduino
Comprueba los colores y las características de tu modelo.
La masa de la fuente y la del Arduino deben estar unidas.
Montaje paso a paso
Desconecta todas las alimentaciones.
Conecta la señal del servo a D9.
Conecta los cables de alimentación del servo a su fuente.
En este proyecto aprenderás los fundamentos de Arduino utilizando Wokwi, un simulador electrónico que funciona directamente desde el navegador. Durante la primera parte no necesitarás instalar Arduino IDE ni disponer de una placa física.
Realizarás varios ejercicios guiados y resueltos. Deberás reproducirlos, comprobar su funcionamiento, introducir pequeñas modificaciones y documentar el trabajo realizado.
En la última parte trasladarás uno de los circuitos a un Arduino real.
No basta con copiar el código. Debes montar cada circuito, ejecutarlo, observar qué sucede y explicar con tus palabras cómo funciona.
2. Objetivos
Al terminar el proyecto serás capaz de:
Crear y guardar proyectos en Wokwi.
Reconocer las partes principales de una placa Arduino Uno.
Comprender la función de setup() y loop().
Configurar pines digitales como entradas o salidas.
Encender y apagar LED.
Utilizar pausas con delay().
Enviar información al monitor serie.
Leer el estado de un pulsador.
Construir un circuito sencillo en una protoboard.
Documentar una práctica técnica en formato Markdown.
Un equipo preparado por el profesor con Arduino IDE o Arduino Cloud Agent.
4. Normas de trabajo
Para cada ejercicio debes:
Crear o duplicar un proyecto en Wokwi.
Montar el circuito indicado.
Copiar y ejecutar el código proporcionado.
Abrir el monitor serie cuando se solicite.
Comprobar el resultado.
Realizar la modificación propuesta.
Guardar el enlace del proyecto.
Añadir a la documentación una captura y una explicación personal.
En la documentación no se aceptarán explicaciones como «funciona bien» o «enciende el LED». Debes indicar qué elementos intervienen, qué instrucciones se ejecutan y cuál es el resultado observado.
Parte I. Ejercicios guiados y resueltos en Wokwi
Ejercicio 1. Hola, Arduino: uso del monitor serie
Objetivo
Aprender a enviar mensajes desde Arduino al ordenador mediante la comunicación serie.
Componentes
Arduino Uno.
No es necesario añadir componentes externos.
Esquema visual
En este ejercicio no existe cableado externo: la salida se observa en el monitor serie.
flowchart LR
A["Arduino Uno"] -->|"USB / comunicación serie a 9600 baudios"| M["Monitor serie de Wokwi"]
M --> R["Mensajes y resultados"]
Serial.print() escribe sin realizar un salto de línea. A continuación, Serial.println(numeroParpadeo) muestra el valor y termina la línea. De esta manera, texto y número aparecen juntos.
Conecta el LED al pin 7, adapta el programa y haz que parpadee cada 250 milisegundos.
Preguntas
¿Por qué se utiliza una resistencia?
¿Qué ocurriría si cambias el montaje al pin 7 pero no modificas el código?
¿Para qué sirve la variable numeroParpadeo?
Ejercicio 4. Semáforo sencillo
Objetivo
Controlar varias salidas digitales y crear una secuencia.
Componentes
Arduino Uno.
Un LED rojo.
Un LED amarillo.
Un LED verde.
Tres resistencias de 220 Ω o 330 Ω.
Conexiones
LED
Pin de Arduino
Conexión restante
Rojo
10
Resistencia y GND
Amarillo
9
Resistencia y GND
Verde
8
Resistencia y GND
Cada LED debe disponer de su propia resistencia.
Esquema visual
Los tres puntos GND representan la misma conexión de tierra de Arduino. Puedes unir los tres cátodos a la línea negativa de la protoboard y conectar esa línea a un pin GND de la placa.
Observa que solamente debe permanecer encendido un LED en cada momento. Comprueba que el monitor serie muestra el mismo estado que representa el circuito.
Modificación obligatoria
Cambia los tiempos para que:
El rojo dure cuatro segundos.
El verde dure cinco segundos.
El amarillo dure dos segundos.
Añade antes de cada cambio el mensaje Cambiando estado del semaforo.
Preguntas
¿Por qué se declaran tres constantes diferentes?
¿Qué LED se enciende después del rojo?
¿Cuánto dura una secuencia completa tras realizar la modificación?
¿Por qué conviene mostrar el estado en el monitor serie?
Ejercicio 5. Pulsador y monitor serie
Objetivo
Leer una entrada digital y mostrar su estado en el monitor serie.
Componentes
Arduino Uno.
Un pulsador.
Un LED.
Una resistencia para el LED.
Conexiones
Elemento
Conexión
Una patilla del pulsador
Pin 2
Patilla opuesta del pulsador
GND
Pin 8
Resistencia y ánodo del LED
Cátodo del LED
GND
Se utilizará la resistencia interna de Arduino mediante INPUT_PULLUP. Por ello, el pulsador tendrá lógica invertida:
# Proyecto de iniciación a Arduino
## Datos del alumno
- Nombre:
- Grupo:
- Fecha:
## Introducción
Explicación breve del objetivo del proyecto.
## Ejercicio 1. Monitor serie
### Montaje y funcionamiento
Explicación personal.
### Código
```cpp
// Código utilizado
```
### Resultado

### Modificación realizada
Explicación y resultado.
### Respuestas
Respuestas a las preguntas del ejercicio.
## Ejercicio 2. LED integrado
Repetir la misma organización.
## Ejercicio 3. LED externo
Repetir la misma organización.
## Ejercicio 4. Semáforo
Repetir la misma organización.
## Ejercicio 5. Pulsador
Repetir la misma organización.
## Implementación en Arduino real
Descripción, código, fotografías y problemas encontrados.
## Conclusiones
Qué has aprendido y qué parte te ha resultado más difícil.
## Enlaces a los proyectos de Wokwi
- Ejercicio 1:
- Ejercicio 2:
- Ejercicio 3:
- Ejercicio 4:
- Ejercicio 5:
Para evitar problemas al incluir bloques de código dentro del README, utiliza tres acentos graves antes y después del código y escribe cpp junto a los tres primeros.
Requisitos de la documentación
El README.md debe contener:
Portada o título.
Datos del alumno.
Índice.
Explicación de cada ejercicio con palabras propias.
Código correctamente presentado en bloques cpp.
Una captura de cada simulación.
Capturas del monitor serie.
Enlaces a los proyectos de Wokwi.
Respuestas a todas las preguntas.
Evidencias del montaje real.
Problemas encontrados y soluciones aplicadas.
Conclusión personal.
Penalizaciones
No entregar enlaces funcionales de Wokwi.
No incluir las capturas solicitadas.
Presentar código sin explicar su funcionamiento.
Copiar explicaciones de otras personas o generadas automáticamente sin revisarlas.
Conectar físicamente LED sin resistencia.
Entregar un documento distinto de README.md sin autorización.
6. Lista de comprobación antes de entregar
He completado los cinco ejercicios de Wokwi.
He realizado todas las modificaciones obligatorias.
He probado el monitor serie.
He respondido las preguntas con mis palabras.
Los enlaces de Wokwi se pueden abrir.
He construido y probado el semáforo real.
He incluido el código en bloques Markdown.
Las imágenes se encuentran dentro de la carpeta img.
Todas las imágenes aparecen correctamente en el README.md.
He escrito una conclusión personal.
El archivo principal se llama exactamente README.md.
7. Ampliación voluntaria
Si terminas antes, modifica el semáforo de Wokwi para que el LED amarillo parpadee tres veces antes de encenderse el rojo. El monitor serie deberá informar de cada parpadeo.
Documenta la ampliación indicando qué instrucciones has añadido y por qué.
PARTE 4 – Instalar librería para comunicación serie
Abrir:
Inicio → escribir “cmd” → Enter
Ejecutar:
pip install pyserial
Si aparece “Successfully installed”, está correcto.
PARTE 5 – Crear el programa que guarda datos
5.1 Crear archivo
En el escritorio:
Crear archivo llamado:
guardar_datos.py
Abrir con Bloc de notas y pegar:
import serial
import csv
from datetime import datetime
# CAMBIAR ESTE PUERTO POR EL CORRECTO
PUERTO = "COM3"
BAUDIOS = 9600
try:
ser = serial.Serial(PUERTO, BAUDIOS, timeout=1)
except:
print("No se puede abrir el puerto. Verifica el COM.")
exit()
archivo = open("datos_sensores.csv", mode="a", newline="")
writer = csv.writer(archivo, delimiter=";")
print("Capturando datos... Presiona Ctrl+C para detener.")
try:
while True:
linea = ser.readline().decode("utf-8").strip()
if linea:
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
datos = linea.split(";")
fila = datos + [timestamp]
writer.writerow(fila)
archivo.flush()
print(fila)
except KeyboardInterrupt:
print("Finalizando captura...")
archivo.close()
ser.close()
En esta práctica vais a construir un pequeño sistema de adquisición de datos distribuido. En lugar de trabajar con un único sensor conectado a un solo dispositivo, vais a montar una arquitectura formada por varios Arduinos, cada uno con uno o varios sensores, y una Raspberry Pi que actuará como centro de recepción y almacenamiento.
El objetivo no es solo «leer sensores», sino comprender cómo se organiza un sistema real donde varios nodos capturan información y un equipo central la recibe, la procesa y la guarda para su análisis posterior.
Este tipo de arquitectura se parece mucho a sistemas reales de monitorización, automatización, IoT, domótica o control industrial.
2. Objetivos de la práctica
Al finalizar la práctica, debéis ser capaces de:
Conectar sensores a varios Arduinos.
Leer datos de sensores desde Arduino.
Enviar esos datos por comunicación serie a través de USB.
Conectar varios Arduinos a una Raspberry Pi.
Identificar los puertos serie de cada Arduino en Linux.
Crear en la Raspberry Pi un programa en Python que reciba datos desde varios Arduinos.
Guardar los datos recibidos en archivos CSV o JSON.
Documentar correctamente el montaje, el código y el funcionamiento del sistema.
3. Descripción general del sistema
La arquitectura general de la práctica será la siguiente:
18. Script Python de ejemplo para varios Arduinos y CSV
import serial
import threading
import csv
import os
from datetime import datetime
PUERTOS = [
"/dev/ttyACM0",
"/dev/ttyACM1",
"/dev/ttyACM2"
]
BAUDIOS = 9600
ARCHIVO_CSV = "datos_sensores.csv"
CAMPOS = ["timestamp", "arduino", "sensor", "valor"]
lock_csv = threading.Lock()
def parsear_linea(linea):
datos = {}
partes = linea.strip().split(";")
for parte in partes:
if "=" in parte:
clave, valor = parte.split("=", 1)
datos[clave.strip()] = valor.strip()
return datos
def inicializar_csv():
if not os.path.exists(ARCHIVO_CSV) or os.path.getsize(ARCHIVO_CSV) == 0:
with open(ARCHIVO_CSV, "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=CAMPOS)
writer.writeheader()
def guardar_csv(registro):
with lock_csv:
with open(ARCHIVO_CSV, "a", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=CAMPOS)
writer.writerow(registro)
def escuchar_puerto(puerto):
try:
ser = serial.Serial(puerto, BAUDIOS, timeout=1)
print(f"Escuchando {puerto}")
while True:
linea = ser.readline().decode("utf-8", errors="ignore").strip()
if linea:
print(f"{puerto} -> {linea}")
datos = parsear_linea(linea)
if "arduino" in datos and "sensor" in datos and "valor" in datos:
registro = {
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"arduino": datos["arduino"],
"sensor": datos["sensor"],
"valor": datos["valor"]
}
guardar_csv(registro)
except Exception as e:
print(f"Error en {puerto}: {e}")
def main():
inicializar_csv()
hilos = []
for puerto in PUERTOS:
hilo = threading.Thread(target=escuchar_puerto, args=(puerto,), daemon=True)
hilo.start()
hilos.append(hilo)
for hilo in hilos:
hilo.join()
if __name__ == "__main__":
main()
19. Script Python de ejemplo para guardar en JSON
import serial
import threading
import json
from datetime import datetime
PUERTOS = [
"/dev/ttyACM0",
"/dev/ttyACM1"
]
BAUDIOS = 9600
ARCHIVO_JSON = "datos_sensores.jsonl"
lock_json = threading.Lock()
def parsear_linea(linea):
datos = {}
partes = linea.strip().split(";")
for parte in partes:
if "=" in parte:
clave, valor = parte.split("=", 1)
datos[clave.strip()] = valor.strip()
return datos
def guardar_json(registro):
with lock_json:
with open(ARCHIVO_JSON, "a", encoding="utf-8") as f:
f.write(json.dumps(registro, ensure_ascii=False) + "\n")
def escuchar_puerto(puerto):
try:
ser = serial.Serial(puerto, BAUDIOS, timeout=1)
print(f"Escuchando {puerto}")
while True:
linea = ser.readline().decode("utf-8", errors="ignore").strip()
if linea:
print(f"{puerto} -> {linea}")
datos = parsear_linea(linea)
if "arduino" in datos and "sensor" in datos and "valor" in datos:
registro = {
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"arduino": datos["arduino"],
"sensor": datos["sensor"],
"valor": datos["valor"]
}
guardar_json(registro)
except Exception as e:
print(f"Error en {puerto}: {e}")
def main():
hilos = []
for puerto in PUERTOS:
hilo = threading.Thread(target=escuchar_puerto, args=(puerto,), daemon=True)
hilo.start()
hilos.append(hilo)
for hilo in hilos:
hilo.join()
if __name__ == "__main__":
main()
FASE 7. Ejecución del programa
20. Guardar y ejecutar el script
Guardad el script con un nombre como:
nano receptor_sensores.py
Pegad el código, guardadlo y ejecutadlo:
python3 receptor_sensores.py
Si todo funciona, deberíais ver en pantalla líneas como estas:
Esta práctica os permitirá trabajar con una arquitectura completa de adquisición de datos usando varios microcontroladores y un sistema Linux central.
No se trata solo de conectar cables y leer números, sino de entender cómo diseñar un sistema modular, organizado y ampliable. Ese enfoque es mucho más valioso que hacer una sola lectura aislada en un monitor serie.
Cuando el sistema funcione, habréis construido una pequeña red de sensores con almacenamiento centralizado, algo muy cercano a muchos proyectos reales de automatización, IoT y monitorización.