Ejercicio 01 — Barrido (sweep) de un servo

Dificultad: verde · Módulo 07 (Actuadores y potencia)

Enunciado

Barrido (sweep) de un servo: 0 180 0 grados, suave.

Montaje (Arduino UNO)

Servo cable de señal (naranja/amarillo) al pin 9 (PWM); V+ (rojo) a 5V; GND (marrón/negro) a GND. OJO: un servo pequeño (SG90) puede tirar del 5V de la placa en arranque; si tienes varios o uno grande, aliméntalos con fuente externa (masa común).

Cómo se resuelve

Primer contacto con un actuador que se mueve. Un servo no es un motor al que se le diga “gira”: lleva dentro un motor pequeño, una reductora y un sensor de posición, y una electrónica que compara dónde está el eje con dónde le has pedido que esté, corrigiendo hasta que coinciden. Por eso a un servo se le manda una posición en grados, de 0 a 180, y él se encarga del resto.

Esa señal de posición son pulsos de una anchura muy concreta, y generarlos a mano sería incómodo. La librería Servo, que viene con el IDE, lo hace por nosotros:

#include <Servo.h>
 
Servo miServo;
const int PIN_SERVO = 9;

Servo miServo; crea un objeto que representa nuestro servo, y PIN_SERVO = 9 es el pin de señal. Tiene que ser un pin capaz de PWM, y el 9 lo es. En setup(), una sola línea:

miServo.attach(PIN_SERVO);

attach asocia el objeto al pin: a partir de ese momento la librería empieza a generar la señal ahí y ya podemos mandar ángulos.

El cuerpo del ejercicio son dos bucles simétricos:

for (int angulo = 0; angulo <= 180; angulo++) {
    miServo.write(angulo);
    delay(15);
}
for (int angulo = 180; angulo >= 0; angulo--) {
    miServo.write(angulo);
    delay(15);
}

Cuidado con write aquí, porque es la confusión más habitual del módulo: miServo.write(angulo) no es digitalWrite. El argumento no es HIGH/LOW ni un valor de PWM de 0 a 255, son grados. miServo.write(90) significa “ponte a 90 grados”.

Lo interesante es de dónde sale la suavidad. Si escribieras solo miServo.write(0) y miServo.write(180) con una espera entre medias, el servo saltaría de un extremo al otro tan rápido como su motor le permita: un latigazo. Aquí, en cambio, se mandan 181 posiciones consecutivas, una por grado, con delay(15) entre cada una. Cada orden pide un salto de un solo grado, que el servo cubre sin esfuerzo, y el ojo lo percibe como un movimiento continuo. La cuenta sale: 181 pasos × 15 ms ≈ 2,7 segundos por barrido, unos 5,4 segundos el ciclo completo de ida y vuelta.

Ese delay(15) es un compromiso, no un número mágico. Si lo bajas mucho, mandas ángulos más deprisa de lo que el eje puede moverse: el servo no llega a la posición antes de recibir la siguiente y el barrido se ve entrecortado o más corto de lo esperado. Si lo subes, el movimiento se ralentiza y a partir de cierto punto deja de parecer suave y se ven los saltos de grado en grado. Cámbialo a 5 y a 50 y observa: entender ese límite físico vale más que el ejercicio en sí.

No hace falta ningún estado final que devuelva el servo al principio, porque loop() ya vuelve arriba por su cuenta y el segundo bucle deja el eje en 0, justo donde el primero lo va a recoger.

Del lado del montaje, el servo tiene tres cables con código de color bastante estándar: la señal (naranja o amarillo) al pin 9, V+ (rojo) a 5 V y GND (marrón o negro) a GND. Un micro servo SG90 solo y sin carga suele aguantar con el 5 V de la placa, pero conviene saber que en el arranque, y sobre todo si fuerzas el eje con la mano, da tirones de corriente que pueden hundir la tensión y resetear el UNO. Con dos servos, o con uno grande, se alimentan desde una fuente aparte y se unen las masas: ese es el patrón que domina el resto del módulo.

Un último detalle que te morderá más adelante: la librería Servo se queda con el temporizador que también genera el PWM de los pines 9 y 10 del UNO. Mientras haya un servo enganchado, analogWrite deja de funcionar en esos dos pines. Si algún día mezclas servo y fade de LED, pon el LED en el 3, el 5, el 6 o el 11.

Para practicar — cópialo y complétalo

Pega este esqueleto y completa los TODO. Es la mejor forma de aprender: inténtalo antes de mirar la solución.

/*
 * Curso de Arduino — Módulo 07: Actuadores y potencia
 * Ejercicio 01 — PRÁCTICA (rellena los TODO)
 * Enunciado: Barrido (sweep) de un servo: 0 -> 180 -> 0 grados, suave.
 * Dificultad: verde
 * Placa: Arduino UNO    Libreria: Servo (incluida con el IDE)
 * Montaje: señal al pin 9 (PWM), V+ a 5V, GND a GND.
 * Correr: Arduino IDE / Wokwi (wokwi/ej01) / arduino-cli (ver README)
 */
#include <Servo.h>
 
Servo miServo;
const int PIN_SERVO = 9;
 
void setup() {
    // TODO: asocia el objeto al pin -> miServo.attach(PIN_SERVO)
}
 
void loop() {
    // TODO: bucle for de angulo = 0 a 180 (angulo++):
    //         miServo.write(angulo);  delay(15);
    // TODO: bucle for de angulo = 180 a 0 (angulo--):
    //         miServo.write(angulo);  delay(15);
}

Solución — cópiala y ejecútala

/*
 * Curso de Arduino — Módulo 07: Actuadores y potencia
 * Ejercicio 01 — MODELO (resuelto)
 * Enunciado: Barrido (sweep) de un servo: 0 -> 180 -> 0 grados, suave.
 * Dificultad: verde
 * Placa: Arduino UNO    Libreria: Servo (incluida con el IDE)
 * Montaje: servo -> cable de señal (naranja/amarillo) al pin 9 (PWM);
 *          V+ (rojo) a 5V; GND (marrón/negro) a GND.
 *          OJO: un servo pequeño (SG90) puede tirar del 5V de la placa en arranque;
 *          si tienes varios o uno grande, aliméntalos con fuente externa (masa común).
 * Correr: Arduino IDE / Wokwi (wokwi/ej01) / arduino-cli (ver README)
 */
#include <Servo.h>           // librería que genera el pulso de posición del servo
 
Servo miServo;               // objeto que representa nuestro servo
const int PIN_SERVO = 9;     // pin de señal (debe ser PWM-capable; el 9 lo es)
 
void setup() {
    miServo.attach(PIN_SERVO);   // asociar el objeto al pin: a partir de aquí mandamos ángulos
}
 
void loop() {
    // ir de 0 a 180 grados, un grado cada 15 ms (movimiento suave)
    for (int angulo = 0; angulo <= 180; angulo++) {
        miServo.write(angulo);   // write() en grados (0..180), NO es digitalWrite
        delay(15);
    }
    // volver de 180 a 0 grados
    for (int angulo = 180; angulo >= 0; angulo--) {
        miServo.write(angulo);
        delay(15);
    }
}

Cómo ejecutar la simulación

Sin instalar nada, en el navegador

  1. Abre wokwi.com y crea un proyecto nuevo de la placa que pide el ejercicio.
  2. Pega la solución (o tu intento) en la pestaña sketch.ino.
  3. Abre la pestaña diagram.json, borra lo que haya y pega el circuito de aquí abajo.
  4. Dale al play. Verás el circuito funcionando: LEDs, pantallas y monitor serie.
Circuito del ejercicio (diagram.json)
{
  "version": 1,
  "author": "ESIBot",
  "editor": "wokwi",
  "parts": [
    { "type": "wokwi-arduino-uno", "id": "uno", "top": 0, "left": 0, "attrs": {} },
    { "type": "wokwi-servo", "id": "servo1", "top": -100, "left": 180, "attrs": {} }
  ],
  "connections": [
    [ "servo1:PWM", "uno:9", "orange", [] ],
    [ "servo1:V+", "uno:5V", "red", [] ],
    [ "servo1:GND", "uno:GND.1", "black", [] ]
  ],
  "dependencies": {}
}

En VS Code, con el repo del curso

El paquete de simulación de este ejercicio está en practica/07-actuadores-y-potencia/wokwi/ej01/. Con la extensión Wokwi instalada y la licencia activada (lo cuenta el onboarding del curso):

make sim EJ=07-actuadores-y-potencia/ej01

y después, en VS Code, Ctrl+Shift+PWokwi: Start Simulator. La extensión no compila: simula un firmware ya compilado, y de compilarlo se encarga ese make.

Cómo usarlo

Con placa: abre el .ino en el Arduino IDE, elige placa y puerto y pulsa Subir. Sin placa: simulalo en Wokwi con cualquiera de las dos vias de arriba. Antes de mirar la solucion, intenta completar tu el esqueleto: es la mejor forma de aprender.

Conexiones