The led_cube library is a graphic library for led cubes.

led_cube.cpp

Committer:
Fiuba
Date:
2010-10-23
Revision:
0:bd6527c8f5f3

File content as of revision 0:bd6527c8f5f3:

#include "led_cube.h"
#include "mbed.h"

// Constructor, inicializamos las variables
led_cube::led_cube (void) {
    int ind[] = {6, 5, 7, 4, 8, 1, 10, 2, 9, 3, 17, 15, 18, 14, 19, 11, 21, 12, 20, 13, 22, 23, 24, 25, 26};
    int col_esp[] = {0, 0, 0, 0, 0, 1, 2, 3, 4, 4, 4, 4, 4, 3, 2, 1, 1, 1, 1, 2, 3, 3, 3, 2, 2};
    int fil_esp[] = {0, 1, 2, 3, 4, 4, 4, 4, 4, 3, 2, 1, 0, 0, 0, 0, 1, 2, 3, 3, 3, 2, 1, 1, 2};

    // Inicializamos las variables
    for (int i=0; i<25; i++) {
        indices[i] = ind[i];
        col_espiral[i] = col_esp[i];
        fil_espiral[i] = fil_esp[i];
    }
    vibora_viva = false;
    ind_demo = 0;

    // Apagamos todos los leds
    apagar_leds();
}


inline void led_cube::apagar_leds (void) {
    memset(&GS_data, 0, 5*32*sizeof(int));
}

inline void led_cube::prender_leds (void) {
    memset(&GS_data, 0xFF, 5*32*sizeof(int));
}

void led_cube::prender_un_led (int piso, int fila, int columna) {
    GS_data[piso][indices[5*fila+columna]] = 0xFF;
}

void led_cube::apagar_un_led (int piso, int fila, int columna) {
    GS_data[piso][indices[5*fila+columna]] = 0x00;
}

void led_cube::next_led (void) {
    static int p = 0;
    static int f = 0;
    static int c = 0;

    prender_un_led(p, f, c);
    if ( ++c > 4 ) {
        c = 0;
        if ( ++f > 4 ) {
            f = 0;
            if ( ++p > 4 ) p = 0;
        }
    }
}

void led_cube::prender_alto (int fila, int col) {
    for (int i=0; i<5; i++)
        GS_data[i][indices[5*fila+col]] = 0xFF;
}


void led_cube::apagar_alto (int fila, int col) {
    for (int i=0; i<5; i++)
        GS_data[i][indices[5*fila+col]] = 0x00;
}

void led_cube::next_alto (void) {
    static int f = 0;
    static int c = 0;
    static bool prender = true;

    if (prender) prender_alto(f, c);
    else apagar_alto(f, c);

    if ( ++c > 4 ) {
        c = 0;
        if ( ++f > 4 ) {
            f = 0;
            prender = not prender;
        }
    }
}

void led_cube::next_alto_espiral (void) {
    static int ind = 0;
    static bool prender = true;

    if (prender) prender_alto(fil_espiral[ind], col_espiral[ind]);
    else apagar_alto(fil_espiral[ind], col_espiral[ind]);

    if ( ++ind > 25 ) {
        ind = 0;
        prender = not prender;
    }
}

void led_cube::prender_largo (int piso, int fila) {
    for (int i=0; i<5; i++)
        GS_data[piso][indices[5*fila+i]] = 0xFF;
}


void led_cube::apagar_largo (int piso, int fila) {
    for (int i=0; i<5; i++)
        GS_data[piso][indices[5*fila+i]] = 0x00;
}

void led_cube::next_largo_espiral (void) {
    static int ind = 0;
    static bool prender = true;

    if (prender) prender_largo(fil_espiral[ind], col_espiral[ind]);
    else apagar_largo(fil_espiral[ind], col_espiral[ind]);

    if ( ++ind > 25 ) {
        ind = 0;
        prender = not prender;
    }
}

void led_cube::prender_ancho (int piso, int col) {
    for (int i=0; i<5; i++)
        GS_data[piso][indices[5*i+col]] = 0xFF;
}


void led_cube::apagar_ancho (int piso, int col) {
    for (int i=0; i<5; i++)
        GS_data[piso][indices[5*i+col]] = 0x00;
}


void led_cube::next_ancho_espiral (void) {
    static int ind = 0;
    static bool prender = true;

    if (prender) prender_ancho(fil_espiral[ind], col_espiral[ind]);
    else apagar_ancho(fil_espiral[ind], col_espiral[ind]);

    if ( ++ind > 25 ) {
        ind = 0;
        prender = not prender;
    }
}

void led_cube::uba_gode (void) {
    prender_leds();

    apagar_ancho(1,1);
    apagar_ancho(1,2);
    apagar_ancho(1,3);
    apagar_ancho(2,1);
    apagar_ancho(2,2);
    apagar_ancho(2,3);
    apagar_ancho(3,1);
    apagar_ancho(3,2);
    apagar_ancho(3,3);
    apagar_ancho(4,1);
    apagar_ancho(4,2);
    apagar_ancho(4,3);

    apagar_largo(4,0);
    apagar_largo(1,1);
    apagar_largo(2,1);
    apagar_largo(3,1);
    apagar_largo(4,2);
    apagar_largo(1,3);
    apagar_largo(2,3);
    apagar_largo(3,3);
    apagar_largo(4,4);

    apagar_alto(0,1);
    apagar_alto(0,2);
    apagar_alto(0,3);
    apagar_alto(1,1);
    apagar_alto(1,2);
    apagar_alto(1,3);
    apagar_alto(3,1);
    apagar_alto(3,2);
    apagar_alto(3,3);
}

// Prende y apaga leds de manera aleatoria
void led_cube::aleatorio (void) {
    int x, y, z, on;

    x = rand()%5;
    y = rand()%5;
    z = rand()%5;
    on = rand()%2;

    if (on == 1)
        prender_un_led(x, y, z);
    else
        apagar_un_led(x, y, z);
}

// Prende un solo led en todo el cubo
void led_cube::un_led_aleatorio (void) {
    static int x, y, z;

    apagar_un_led(x, y, z);

    x = rand()%5;
    y = rand()%5;
    z = rand()%5;

    prender_un_led(x, y, z);
}

// Un led camina aleatoriamente
void led_cube::un_led_caminando (void) {
    static int x, y, z;

    apagar_un_led(x, y, z);

    x += rand()%3-1;
    y += rand()%3-1;
    z += rand()%3-1;

    x = (x<0)? 0: (x>4)?4:x ;
    y = (y<0)? 0: (y>4)?4:y ;
    z = (z<0)? 0: (z>4)?4:z ;

    prender_un_led(x, y, z);
}

// Rutina de generacion de la vibora
void led_cube::vibora_inicia (void) {
    int vibora_tmp[5][3] = {{0,0,0},{0,0,1},{0,0,2},{0,0,3},{0,0,4}};
    for (int i=0; i<5; i++) {
        for (int j=0; j<3; j++) vibora_leds[i][j] = vibora_tmp[i][j];
        prender_un_led(vibora_leds[i][0], vibora_leds[i][1], vibora_leds[i][2]);
    }
}

// Rutina de la vibora caminando
void led_cube::vibora_camina (void) {
    int x, y, z;
    bool seguir_tirando = true;

    if ( !vibora_viva ) {
        vibora_inicia();
        vibora_viva = true;
    } else {
        // Eliminamos el ultimo led
        apagar_un_led(vibora_leds[4][0], vibora_leds[4][1], vibora_leds[4][2]);
        // Caminamos un paso
        while (seguir_tirando) {
            x = vibora_leds[0][0] + rand()%3-1;
            y = vibora_leds[0][1] + rand()%3-1;
            z = vibora_leds[0][2] + rand()%3-1;

            x = (x<0)? 0: (x>4)?4:x ;
            y = (y<0)? 0: (y>4)?4:y ;
            z = (z<0)? 0: (z>4)?4:z ;

            if (GS_data[x][indices[5*y+z]] == 0x00) seguir_tirando = false;
        }
        for (int i=4; i>=0; i--) {
            for (int j=0; j<3; j++) {
                vibora_leds[i+1][j] = vibora_leds[i][j];
            }
        }
        vibora_leds[0][0] = x;
        vibora_leds[0][1] = y;
        vibora_leds[0][2] = z;

        prender_un_led(x, y, z);
    }
}

void led_cube::prender_piso (int piso) {
    for (int i=0; i<5; i++)
        prender_ancho(piso, i);
}

void led_cube::sube_ola_vert (int piso) {
    switch (piso) {
        case 0:
            prender_piso(0);
            break;
        case 5:
            prender_piso(4);
            break;
        default:
            for (int i=1; i<4; i++) {
                for (int j=1; j<4; j++) prender_un_led(piso, i, j);
            }
            prender_largo(piso-1, 0);
            prender_largo(piso-1, 4);
            prender_ancho(piso-1, 0);
            prender_ancho(piso-1, 4);
    }
}

void led_cube::baja_ola_vert (int piso) {
    switch (piso) {
        case 0:
            prender_piso(0);
            break;
        case 5:
            prender_piso(4);
            break;
        default:
            for (int i=1; i<4; i++) {
                for (int j=1; j<4; j++) prender_un_led(piso-1, i, j);
            }
            prender_largo(piso, 0);
            prender_largo(piso, 4);
            prender_ancho(piso, 0);
            prender_ancho(piso, 4);
    }
}

void led_cube::mueve_ola (void) {
    static int p = 0;
    static bool sube = true;

    apagar_leds();
    if ( sube ) {
        sube_ola_vert(p);
        if ( ++p > 4 ) sube = false;
    } else {
        baja_ola_vert(p);
        if ( --p < 1 ) sube = true;
    }
}

// Cambia el demo que muestra
void led_cube::demo_inc (void) {
    apagar_leds();
    if (++ind_demo > 7) {
        ind_demo = 0;
        vibora_viva = false;
    }
}

// Rutina que muestra el demo segun el indice
void led_cube::demo_show (void) {
    switch (ind_demo) {
        case 0:
            prender_leds();
            break;
        case 1:
            uba_gode();
            break;
        case 2:
            next_alto();
            break;
        case 3:
            next_alto_espiral();
            break;
        case 4:
            un_led_caminando();
            break;
        case 5:
            //vibora_camina();
            //break;
        case 6:
            mueve_ola();
            break;
        default:
            un_led_aleatorio();
    }
}