Materias · 🏛️ Universidad y trabajo

Arduino

Ejercicios resueltos de Arduino paso a paso, con el error que más se comete en cada uno: Lectura analógica (ADC), millis() frente a delay() y más. Gratis y en español.

Preguntarle al tutor de Arduino

Sin instalar nada. Puedes probar antes de crear cuenta.

Ejercicios resueltos de Arduino

Resueltos paso a paso, como te los explicaría el tutor, y con el error que más se comete.

Lectura analógica (ADC)

Un LM35 está conectado a A0 de un Arduino UNO, que trabaja con referencia de 5 V y conversor de 10 bits. La función analogRead(A0) devuelve 49. ¿Qué temperatura está midiendo y con qué resolución?

Cómo se resuelve

  1. 1El conversor de 10 bits entrega 1024 valores distintos, numerados de 0 a 1023, y la lectura 1023 corresponde a los 5 V de la referencia. Para pasar de cuenta a voltaje se divide entre 1023, no entre 1024: cada paso vale 5 V / 1023 = 4,8876 mV.
  2. 2El voltaje que llegó al pin es entonces V = 49 × 4,8876 mV = 239,49 mV, o sea 0,2395 V.
  3. 3El LM35 entrega 10 mV por grado centígrado, con 0 mV en 0 °C. Así que la temperatura es T = 239,49 mV / 10 mV por °C = 23,95 °C, unos 24 °C: un día normal en Medellín.
  4. 4La resolución sale de la misma cuenta: como cada paso del conversor son 4,8876 mV y el sensor da 10 mV por grado, un paso equivale a 0,49 °C. El Arduino no puede distinguir cambios menores a medio grado con esta configuración.
  5. 5Para mejorar eso se usa analogReference(INTERNAL), que baja la referencia a 1,1 V: cada paso pasa a valer 1,1/1023 = 1,075 mV, o sea 0,107 °C, cuatro veces y media mejor, a cambio de que el rango máximo medible baje a 110 °C.

Respuesta: La temperatura es 23,95 °C (≈ 24 °C), con una resolución de 0,49 °C por cada paso del conversor.

El error de siempre: Escribir la conversión con enteros: `int t = lectura * 5 / 1023 * 100;`. En C, 49 × 5 = 245 y 245 / 1023 da 0 porque la división entera descarta los decimales; el resultado es 0 °C siempre, sin que el compilador avise nada. Hay que forzar coma flotante desde el principio: `float t = lectura * (5.0 / 1023.0) * 100.0;`. Y si se prefiere seguir en enteros para ahorrar memoria, hay que multiplicar ANTES de dividir y cuidar el tamaño del tipo: en un Arduino UNO `int` es de 16 bits y llega hasta 32.767, así que `lectura * 1100` (la cuenta habitual con la referencia interna de 1,1 V) desborda en silencio apenas la lectura pasa de 29. Se escribe `(long)lectura * 1100 / 1023`.

millis() frente a delay()

Este sketch debe parpadear un LED cada segundo y, al mismo tiempo, encender un zumbador cuando se pulse un botón. El LED parpadea bien, pero el botón solo responde si uno lo deja pulsado un rato largo. ¿Por qué pasa y cómo se arregla? void loop() { digitalWrite(LED, HIGH); delay(1000); digitalWrite(LED, LOW); delay(1000); if (digitalRead(BOTON) == HIGH) digitalWrite(ZUMBADOR, HIGH); }

Cómo se resuelve

  1. 1delay() no es una pausa del LED: es una pausa del procesador entero. Durante ese tiempo el micro está atrapado en un bucle contando, sin ejecutar ninguna otra línea.
  2. 2En cada vuelta del loop hay dos delay(1000), o sea 2 segundos completos en los que no se ejecuta el digitalRead del botón.
  3. 3El digitalRead solo corre una vez cada 2 segundos y ve el botón en ese instante exacto. Si el pulso duró menos que eso, la pulsación se pierde: por eso hay que mantenerlo apretado hasta que el programa «llegue» a mirarlo.
  4. 4La solución es no detener el programa, sino preguntar qué hora es. millis() devuelve los milisegundos desde que arrancó la placa y no bloquea nada.
  5. 5Se guarda el instante del último cambio del LED y en cada vuelta se compara: si ya pasaron 1.000 ms, se cambia el LED y se actualiza la marca. Si no, no se hace nada y se sigue de largo.
  6. 6Así queda: unsigned long ultimo = 0; bool encendido = false; void loop() { if (millis() - ultimo >= 1000) { ultimo = millis(); encendido = !encendido; digitalWrite(LED, encendido); } if (digitalRead(BOTON) == HIGH) digitalWrite(ZUMBADOR, HIGH); }
  7. 7Ahora el loop da miles de vueltas por segundo y el botón se revisa en todas ellas: responde al instante.

Respuesta: Porque delay() bloquea el programa completo: el botón solo se lee una vez cada 2 segundos. Se reemplaza por una comparación con millis(), que deja el loop corriendo libre y revisa el botón miles de veces por segundo.

El error de siempre: Declarar la variable del tiempo como `int` o como `long` con signo en vez de `unsigned long`. millis() pasa de 32.767 en 33 segundos y de 2.147.483.647 en 25 días; guardado en un tipo más pequeño o con signo, el valor se desborda a negativo y la comparación empieza a fallar. Con `unsigned long` en ambos lados, la resta `millis() - ultimo` sigue dando el intervalo correcto incluso en el momento en que el contador da la vuelta (a los 49,7 días), y por eso se escribe restando y no como `millis() >= ultimo + 1000`.

¿Y si tu ejercicio no es ninguno de estos?

No hace falta buscar el ejercicio exacto en internet. Trae el tuyo, o pide los que te falten.

Todo esto es gratis y sin instalar nada. Puedes probar antes de crear cuenta.

Lo que cubre

  • Lectura analógica (ADC)
  • millis() frente a delay()

Preguntas que le puedes hacer

  • Lectura analógica (AD…Explícame «Lectura analógica (ADC)» con un ejemplo práctico y dime en qué suele equivocarse la gente.
  • millis() frente a del…Explícame «millis() frente a delay()» con un ejemplo práctico y dime en qué suele equivocarse la gente.

Cómo enseña este tutor

Es riguroso y completo: justifica cada paso y nombra el teorema, la norma o la buena práctica que está aplicando, para que puedas citarla en tu trabajo o en el parcial.

  • · Te muestra el camino completo, no solo el resultado.
  • · Si algo no te cuadra, te lo explica otra vez de otra manera.
  • · Comprueba las cuentas con matemática simbólica antes de dártelas.
  • · Con una foto de tu cuaderno te dice dónde está el error.
  • · Te arma quizzes de lo que acabas de ver para saber si de verdad quedó.

Otras materias de Universidad y trabajo