5 consejos a la hora de programar en Arduino 5/5 (2)

Aquí te traemos algunos consejos que creemos interesantes para los programadores de Arduino. Teneis consejo para el ahorro de RAM almacenando texto en la memoria de programas, facilitando la lectura de los programas, una técnica para evitar retrasos, el operador ternario C++ y el watchdog timer.

Colocando cadenas de texto en la memoria del programa para ahorrar ram

Escribir Serial.println(F("Hello World!")); en vez de Serial.println("Hello World");

Cuando escribes: Serial.println("Hello World!");

el texto `Hola Mundo” se almacena en dos lugares:

  • Memoria de programas
  • Memoria de acceso aleatorio (RAM)

El contenido de la RAM se pierde cada vez que se reinicia el Arduino, o se pierde la energía. La memoria del programa se retiene mediante un reset y la pérdida de energía, de modo que al inicio de cada programa, las cadenas normales se copian de la memoria del programa a la memoria RAM para que puedan ser utilizadas por el programa.

Muchas placas Arduino no tienen mucha RAM: sólo hay 2 kb en el chip 328 usado en la Arduino Uno, por ejemplo. Así que es fácil quedarse sin RAM si tu programa utiliza muchas cadenas u otras variables.

Cuando escribes: Serial.println(F("Hello World!"));

la función println obtiene el texto de la memoria del programa directamente, usando un buffer temporal que no consume mucha RAM.

Las constantes hacen que los programas sean más fáciles de leer

Digamos que quieres molestar a alguien: conecta un zumbador a una de las salidas digitales de tu Arduino y hazlo sonar cada pocos segundos. Si el zumbador está conectado al puerto 6, tendrás que introducir el 6 en tres lugares:

  • configurar el modo pin como una salida,
  • encender el zumbador, y
  • apagando el zumbador.

En su lugar, define una constante en la parte superior de tu programa: const int BuzzerPort = 6;

/*
Beeper
Makes a noise every few seconds.
*/
// A constant for the port that the buzzer is connected to.
const int BuzzerPort = 6;

// These constants define how often the beeper sounds, and how long it sounds for.
const int BuzzerPeriod = 5000; // [milliseconds]
const int BuzzerOnTime = 100; // [milliseconds]
void setup()
{
pinMode(BuzzerPort, OUTPUT);
}

// the loop routine runs over and over again forever:
void loop()
{
digitalWrite(BuzzerPort, HIGH);
delay(BuzzerPeriod);
digitalWrite(BuzzerPort, LOW);
delay(BuzzerOnTime);
}

Ahora, cuando vuelvas a conectar el zumbador al puerto 7, sólo tienes que cambiar el puerto en un lugar.

Mejor aún, el código es más claro. De inmediato sabemos que digitalWrite(BuzzerPort, HIGH) debe activar un zumbador; con digitalWrite(6, HIGH), necesitamos recordar lo que está conectado al puerto 6.

Entonces, ¿por qué usar una constante en lugar de sólo una variable? ¿No funcionaría iint BuzzerPort=6; funciona igual de bien?

Más o menos: sólo tienes un número para cambiar cuando el puerto cambia. Pero cuando la’variable’ es declarada como una constante, el compilador, la herramienta que convierte tu programa en algo que el Arduino puede usar, no te permitirá cambiarlo accidentalmente. Así que si tienes const int BuzzerPort=6 y tratas de cambiar su valor:

void setup()
{
BuzzerPort = 7;
pinMode(BuzzerPort, OUTPUT);
}

El compilador reportará un error. Por lo tanto, con las constantes, puedes confiar en que el valor nunca se cambie después de que se haya establecido.

Los retrasos aburren

La función delay detiene el programa. Por ejemplo el clásico programa blink pasa la mayor parte del tiempo sin hacer absolutamente nada:

void loop()
{
digitalWrite(LedPin, HIGH);
delay(1000); // yawn. Nothing is happening here.
digitalWrite(LedPin, LOW);
delay(1000); // zzz. Or here!
}

Piensa en todas las cosas que podrías hacer en ese tiempo muerto: leer los sensores, hacer ruido, conducir los motores. Los delays pueden ser útiles, pero a menudo no son más que una pérdida de tiempo.

Hay una manera fácil de evitarlo, pero necesitaremos algunas variables:

// Time stamp when the LED was last turned on or off.
unsigned long LastLEDToggleTime = 0;

// Current state of the LED; true => on; false => off.
bool IsLEDOn = false;

// Time between turning the LED on or off
const int LEDTogglePeriod = 1000; // [milliseconds]

// The pin the LED is connected to
const int LEDPin = 13;

Y el bucle o loop se vuelve:

void loop()
{
// This will toggle the LED on and off every second, with no waseful delays
if ((millis() - LastLEDToggleTime) > LEDTogglePeriod)
{
LastLEDToggleTime = millis();
if (IsLEDOn)
{
IsLEDOn = false;
digitalWrite(LEDPin, LOW);
}
else
{
IsLEDOn = true;
digitalWrite(LEDPin, HIGH);
}
}

// Do something else here.
}

Ternary Tricks

C++, el lenguaje que utiliza la plataforma Arduino, incluye una práctica expresión para seleccionar entre dos valores: (expression) ? (true-value) : (false-value)

Esto se llama un operador ternario porque tiene 3 argumentos:

  • (expression), una prueba que es verdadera o falsa
  • (true-value), el resultado si (expresión) es verdadera
  • (false-value), el resultado si (expresión) es falsa

Te permite escribir cosas como:

IsLEDOn = !IsLEDOn; // toggle value of IsLEDOn
digitalWrite(LEDPin, IsLEDOn ? HIGH : LOW)

En lugar de:

if (IsLEDOn)
{
IsLEDOn = false;
digitalWrite(LEDPin, LOW);
}
else
{
IsLEDOn = true;
digitalWrite(LEDPin, HIGH);
}

Es fácil crear código que es difícil de seguir usando este consejo.

Controlar programas fuera de control con el temporizador del watch-dog

El microprocesador del Arduino incluye un temporizador watchdog. El watchdog timer es una especie de interruptor de hombre muerto: si tu programa no sigue diciéndole al temporizador que todo está bien, volará tu placa Arduino.

En realidad, sólo resetea el micro: lo que tu haces al resetear es tu propia responsabilidad.

Para usar el watchdog timer, tendrás que hacerlo de la siguiente manera:

  • incluir una biblioteca
  • habilitar el watchdog timer
  • dile al watchdog timer que todo está bien

Este ejemplo debería funcionar en cualquier Arduino que utilice un microcontrolador de Atmel, incluyendo Arduino Uno, Mini y Mega. Debes tener en cuenta que los Arduino Megas más antiguos tienen un problema en su gestor de arranque. Si configuras el tiempo de espera de watchdog demasiado bajo, no podrás reprogramar el Arduino usando el cargador de arranque serie. Actualiza al último cargador de arranque Mega para arreglar eso.

// Include the watch-dog library functions
#include
unsigned CountDown = 10;
void setup()
{
Serial.begin(9600);
// enable the watchdog timer and set a timeout.
// if we don’t call wdt_reset() before the time is up, the program will reset automatically.
wdt_enable(WDTO_1S); // WDTO_1S => 1 second timeout.
}

void loop()
{
// the program is alive...for now.
wdt_reset();

while (CountDown >= 0)
{
Serial.println(CountDown);
CountDown = CountDown - 1;
delay(30);
}

Serial.println(F("Kaboom!"));
}

Este programa contiene un error que significa que la cuenta atrás nunca terminará. ¿Puedes reconocerlo?

El programa se atascará en el bucle while. Debido a que esto significa que wdt_reset() sólo se llama a la primera vez en el bucle, el watchdog timer eventualmente se apagará y el programa se reiniciará.

 

Califique esto

También te puede interesar

Deja un comentario

Tu dirección de correo electrónico no será publicada.

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Pin It on Pinterest

Shares