Ejercicio 04 — Variar la velocidad de un motor DC con PWM, a través de un transistor
Dificultad: rojo · Módulo 07 (Actuadores y potencia)
Enunciado
Variar la velocidad de un motor DC con PWM, a través de un transistor.
Cómo se resuelve
El reto del módulo, y el ejercicio donde el código es casi anecdótico frente al montaje. Es opcional porque necesita componentes que no todos los kits traen, pero conviene leerlo aunque no lo montes: aquí está la idea que justifica el módulo entero.
Empecemos por lo que parece:
const int PIN_MOTOR = 6;
void setup() {
pinMode(PIN_MOTOR, OUTPUT);
}
void loop() {
analogWrite(PIN_MOTOR, 128);
delay(2000);
analogWrite(PIN_MOTOR, 255);
delay(2000);
analogWrite(PIN_MOTOR, 0);
delay(2000);
}Es el analogWrite del módulo 03, con tres consignas de dos segundos cada una: 128 es un ciclo de trabajo del 50 % (media velocidad), 255 es el 100 % (velocidad máxima) y 0 es parado. Seis segundos de ciclo y vuelta a empezar.
Ahora, el nombre de la constante lleva una advertencia dentro, y el comentario del fichero la hace explícita: PIN_MOTOR es el pin que va a la base del transistor, no al motor. Esa distinción es todo el ejercicio.
Un pin del UNO entrega del orden de 20 mA, con un máximo absoluto de unos 40 mA. Un motor DC pequeño arrancando pide fácilmente 300 mA o más. Hay una o dos órdenes de magnitud de diferencia. Conectar el motor al pin no hace que gire despacio: hunde la tensión, resetea la placa y degrada el pin de forma permanente. El pin no es una fuente de energía, es un interruptor lógico diminuto: sirve para decir cosas, no para empujar cosas.
De ahí sale el montaje, un NPN (2N2222 o BC547) como interruptor de lado bajo. El pin 6 va a través de una resistencia de 1 kΩ a la base del transistor; el emisor a GND; el colector a un terminal del motor; el otro terminal del motor al + de la fuente externa; y el GND de la fuente externa al GND de la placa. Ese último cable es el que se olvida siempre y el que hace que todo “funcione a ratos”.
Cada pieza tiene su porqué:
La resistencia de 1 kΩ limita la corriente que entra por la base. La unión base-emisor de un transistor conduce como un diodo: sin resistencia, el pin intentaría alimentarla sin freno y superaría su límite de corriente. Con 1 kΩ entran unos pocos miliamperios, más que suficiente para saturar el transistor y perfectamente asumibles para el pin.
El transistor es el interruptor de potencia. Una corriente pequeña por la base permite que pase una corriente mucho mayor entre colector y emisor. El pin controla, la fuente empuja: esa división del trabajo es el patrón que se repite en todos los actuadores de potencia, cambie el componente que cambie.
La masa común es imprescindible por una razón conceptual, no por costumbre. Una tensión siempre es una diferencia respecto a una referencia. Cuando el pin pone 5 V, son 5 V respecto al GND de la placa. Si el emisor del transistor está en el GND de la fuente y esas dos masas no están unidas, no existe una referencia compartida: la señal flota y el transistor no interpreta nada de forma fiable.
El diodo flyback (un 1N4007) va en paralelo con el motor, montado al revés respecto a la alimentación: el cátodo, la patilla con la raya, hacia el positivo. Un motor es una carga inductiva y almacena energía en su campo magnético; cuando el transistor corta la corriente de golpe, la bobina responde con un pico de tensión inverso que puede ser de decenas o cientos de voltios durante un instante. Ese pico va directo al transistor que acaba de abrir y lo perfora, o se cuela como ruido por la alimentación y cuelga el microcontrolador. Mientras el motor gira normalmente el diodo no conduce, es como si no estuviera; en el instante del corte la tensión se invierte, el diodo conduce y le ofrece a esa corriente un camino cerrado por el que extinguirse suavemente. Es un componente de céntimos que evita averías raras y difíciles de diagnosticar.
Sobre por qué el PWM regula la velocidad: analogWrite(PIN_MOTOR, 128) no pone “medio voltaje” en la base. Conmuta el pin muy deprisa entre encendido y apagado con un ciclo de trabajo del 50 %, el transistor abre y cierra a esa misma cadencia, y el motor —que por inercia mecánica no puede seguir cambios tan rápidos— promedia y se comporta como si recibiera la mitad de la energía. Gira a media velocidad.
Una advertencia práctica que se nota al montarlo: con valores bajos de PWM un motor a menudo no arranca, solo zumba. Vencer el rozamiento estático exige más par que mantener el giro ya iniciado. Por eso 128 puede bastar para mantenerlo girando pero no para arrancarlo desde parado, y notarás que la secuencia se comporta distinto según venga de 0 o de 255. Si necesitas velocidades bajas de verdad, la técnica habitual es dar un pulso corto a 255 y bajar enseguida al valor deseado.
Y una limitación que este circuito tiene por construcción: con un solo transistor el motor gira siempre en el mismo sentido. Un interruptor solo abre y cierra. Para invertir el giro hace falta un puente en H, que es lo que traen los drivers L298N o DRV8833, con cuatro interruptores en lugar de uno. Con un driver así el código se parece mucho a este —un analogWrite para la velocidad más un par de pines digitales para el sentido— y además ya lleva los diodos de protección integrados, así que no tienes que añadirlos. La idea de fondo no cambia en absoluto: el pin manda, el driver empuja, la fuente alimenta y las masas van unidas.
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 04 (OPCIONAL) — PRÁCTICA (rellena los TODO)
* Enunciado: Variar la velocidad de un motor DC con PWM, a través de un transistor.
* Dificultad: rojo
* Placa: Arduino UNO
* Montaje: pin 6 -> 1 kohm -> base NPN; emisor a GND; colector al motor;
* motor a fuente externa; diodo flyback; masa común.
*
* IMPORTANTE: el motor NUNCA va al pin. El pin controla la base del transistor;
* el motor lo alimenta una fuente aparte. Diodo flyback siempre.
* Correr: Arduino IDE / Wokwi (wokwi/ej04) / arduino-cli (ver README)
*/
const int PIN_MOTOR = 6;
void setup() {
// TODO: configura PIN_MOTOR como salida
}
void loop() {
// TODO: analogWrite(PIN_MOTOR, 128) -> media velocidad; delay(2000)
// TODO: analogWrite(PIN_MOTOR, 255) -> máxima; delay(2000)
// TODO: analogWrite(PIN_MOTOR, 0) -> parado; delay(2000)
}Solución — cópiala y ejecútala
/*
* Curso de Arduino — Módulo 07: Actuadores y potencia
* Ejercicio 04 (OPCIONAL) — MODELO (resuelto)
* Enunciado: Variar la velocidad de un motor DC con PWM, a través de un transistor.
* Dificultad: rojo
* Placa: Arduino UNO
*
* Montaje (NPN como interruptor de lado bajo):
* - pin 6 (PWM) -> resistencia 1 kohm -> BASE del transistor (p.ej. 2N2222 / BC547)
* - EMISOR -> GND (común con el de la placa)
* - COLECTOR -> un terminal del motor
* - otro terminal del motor -> + de la FUENTE EXTERNA del motor
* - GND de la fuente externa -> GND de la placa (MASA COMÚN)
* - DIODO FLYBACK en paralelo con el motor (cátodo, raya, al +) para
* absorber el pico de tensión al apagar la bobina.
*
* IMPORTANTE (lo más importante del módulo):
* - El motor NUNCA se alimenta del pin del Arduino: un pin da ~20 mA y un motor
* pide cientos de mA o amperios. Lo quemarías al instante.
* - El pin solo controla la BASE del transistor (poca corriente).
* - El motor toma su corriente de una FUENTE APARTE; el transistor (o un driver
* tipo L298N / DRV8833) abre y cierra ese paso.
* - Diodo de protección (flyback) SIEMPRE con cargas inductivas.
* Correr: Arduino IDE / Wokwi (wokwi/ej04) / arduino-cli (ver README)
*/
const int PIN_MOTOR = 6; // PWM hacia la base del transistor (NO directo al motor)
void setup() {
pinMode(PIN_MOTOR, OUTPUT);
}
void loop() {
analogWrite(PIN_MOTOR, 128); // ~media velocidad (duty 50%)
delay(2000);
analogWrite(PIN_MOTOR, 255); // velocidad máxima (duty 100%)
delay(2000);
analogWrite(PIN_MOTOR, 0); // parado
delay(2000);
}Cómo ejecutar la simulación
Sin instalar nada, en el navegador
- Abre wokwi.com y crea un proyecto nuevo de la placa que pide el ejercicio.
- Pega la solución (o tu intento) en la pestaña
sketch.ino. - Abre la pestaña
diagram.json, borra lo que haya y pega el circuito de aquí abajo. - Dale al play. Verás el circuito funcionando: LEDs, pantallas y monitor serie.
Circuito del ejercicio (diagram.json)
{
"version": 1,
"author": "ESIBot",
"editor": "wokwi",
"comment": "Simplificacion: motor DC accionado por NPN de lado bajo. En real, el motor lleva fuente externa con masa comun y diodo flyback (ver ej04_modelo.ino).",
"parts": [
{ "type": "wokwi-arduino-uno", "id": "uno", "top": 0, "left": 0, "attrs": {} },
{ "type": "wokwi-dc-motor", "id": "motor1", "top": -120, "left": 200, "attrs": {} },
{ "type": "wokwi-transistor-npn", "id": "q1", "top": 60, "left": 160, "attrs": {} },
{ "type": "wokwi-resistor", "id": "rb", "top": 60, "left": 80, "attrs": { "value": "1000" } }
],
"connections": [
[ "uno:6", "rb:1", "green", [] ],
[ "rb:2", "q1:B", "green", [] ],
[ "q1:E", "uno:GND.1", "black", [] ],
[ "q1:C", "motor1:2", "blue", [] ],
[ "motor1:1", "uno:5V", "red", [] ]
],
"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/ej04/. Con la extensión Wokwi instalada y la licencia activada (lo cuenta el onboarding del curso):
make sim EJ=07-actuadores-y-potencia/ej04y después, en VS Code, Ctrl+Shift+P → Wokwi: 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.