La séptima vida

...o el gato así lo espera/teme

Lámpara de luciérnagas: Primer paso

Cuando era niño pasábamos los fines de semana en familia, en Santa Isabel, donde hay un pequeño río. La tierra era muy fértil y mis papás sembraban hortalizas todos los años. Con el verano llegaban los pepinos, las zanahorias, las acelgas, los pimientos. El cielo se llenaba de estrellas cada noche; algunas de ellas bajaban hasta las plantas de tomate, sus preferidas, y volaban entre ellas encendiéndose y apagándose con ritmo musical. Debían sonar como campanitas.

Así que voy a poner un poco de estos recuerdos en un frasco lleno de canicas para convertirlos en una lámpara para el buró de Emilio. Va a ser una lámpara de luciérnagas. Un botón va a permitir encenderla, y se va a apagar automáticamente después de una media hora.

En este primer paso voy a utilizar un Arduino para hacer un programa que imitará la luminosidad de las luciérnagas con LEDs. Cada uno de los seis LED se iluminará rápidamente y luego su intensidad disminuirá despacio, hasta apagarse. Cada vez tardarán más tiempo en volver a encenderse, y al cabo de una media hora ya no lo harán.

Para encender el LED elegí una función cuadrática para que la intensidad suba rápida y gradualmente :

y = imax(t/tao)²

para 0 <= t < tao

Esta función pasa de 0 a imax en tao segundos, y aumenta de manera parabólica. Elegí que tao sea igual a 0.1 segundos, así que tal vez no se note ninguna diferencia contra una función lineal.

Para la disminución de intensidad, elegí una función exponencial decreciente:

y = imax e-(t-tao)/tao

para t >= tao

Esto hace que la luz haya disminuido al 36% en tao segundos, y al 13.5% después de 2 veces tao segundos.

Este es el programa para Arduino, para probar la iluminación de las luciérnagas:

#define TIME_MAX (30*60)
#define TAO1      0.1
#define TAO2      0.6
#define DELTA    10.0

// This array represents the LEDs. The first element is the pin number;
// the second, the time when it was last set to ON.
// A zero in the second element means the LED is OFF.
int leds [6][2] = {
  {  3, 0},
  {  5, 0},
  {  6, 0},
  {  9, 0},
  { 10, 0},
  { 11, 0},
};

void setup() {
    // Do nothing
}


void loop() {
    for (float time = 0;  time < TIME_MAX;  time += DELTA/1000) {

        // If a random number is greater than this limit, turnon the LED
        float limit = RAND_MAX * (0.02*time/TIME_MAX + 0.98);

        // Time to update the intensity of the LED: between 6 and 12 tao2
        float duration = 6/TIME_MAX * time + 6;

        // Iterate over each LED
        for (int i=0; i<6; i++) {
            // If this LED is off, see if it wants to turn on
            if (leds[i][1] == 0) {
                if (rand() > limit) {
                    leds[i][1] = time;
                }
            }
            // but if it has been on for a long time, turn it off
            else if (time - leds[i][1] > TAO1 + duration*TAO2) {
                leds[i][1] = 0;
            }

            // Calculate the intensity of the given LED if it is on
            if (leds[i][1] > 0) {
                analogWrite(leds[i][0], intensity(time, leds[i][1]));
            }
        }
        delay(DELTA);
    }
}

/* Given the present time and the time when the firefly began its cycle,
    calculate the present intensity. */
int intensity (float time, float t_ini) {
    float i_max = 255; 
    float t   = time - t_ini;
    float intensity;
    if (t < TAO1) {
        intensity = i_max * pow(t/TAO1, 2);
    }
    else {
        intensity = i_max * exp(-(t-TAO1)/TAO2);
    }

    return intensity;
}

Los LED están conectados en los pines 3, 5, 6, 9, 10 y 11 pues son los que son capaces de trabajar en PWM y así variar la intensidad de las luciérnagas.

El siguiente paso es aprender a utilizar los timers del ATmega168 para pasar del Arduino a un circuito independiente. Lo que quiero es pegar el circuito en la tapa del frasco y alimentarlo con una pila de 9 voltios. Pienso utilizar un relevador para que, cuando haya pasado la media hora, éste desconecte la pila y desenergice el circuito. Para encenderlo de nuevo, tengo contemplado un botón que va a estar expuesto por la tapadera del frasco.

Más adelante pondré algunas fotos.