Leer y decodificar archivo .led

3

Estoy trabajando en una pantalla LED flexible de 20 metros de tira LED RGB digital con WS2811 IC para cada LED.

Quiero controlar esto usando Arduino, que no es un problema usando FastSPI. Mi problema es que quiero crear diferentes programas LED (por ejemplo, utilizando LedEdit 2013 ) que luego se puede exportar a archivos * .led.

Esto en sí mismo no es un problema, ya que ya he generado estos archivos. ¿El problema es cómo leer y decodificar el archivo * .led? Por lo que he podido leer en Internet (buscando un par de horas), los archivos consisten en un tipo de encabezado seguido de información codificada en base64 sobre las posiciones x e y de los LED que deberían estar encendidos y de qué color deberían be (RGB 0-255 valor supongo). No estoy completamente seguro de cómo exactamente descodificaré esta señal y obtendré algo realmente útil de ella.

Si solo puedo obtener información útil, seguramente puedo programar mi salida si la implemento con la biblioteca FastSPI para Arduino.

EDITAR:

He creado dos archivos de ejemplo simples que quizás podrían ser más fáciles de ver para ustedes.

Ambos se componen de una sencilla configuración de 10 x 10 LED, ambos solo una escena; uno todo negro y uno todo blanco.

Black: enlace y White: enlace

    
pregunta Simon

1 respuesta

1

También tuve problemas para interpretar la estructura del archivo .LED, sin embargo, otro método sería crear sus propios mapas de bits. Creé una imagen LED con Microsoft Paint, en File | Properties establecí el ancho y el alto en 10 píxeles seguidos de un File | Save As y seleccionando 24-bit Bitmap como el tipo. Si te acercas al máximo, es fácil seleccionar píxeles individualmente y Linux y Mac OSX tienen muchas aplicaciones que pueden escribir mapas de bits de Windows si estás usando un O / S diferente.

Luego creé la siguiente aplicación de línea de comandos de Visual C ++ para leer el mapa de bits y crear una definición de matriz constante. Escribe el código en la salida estándar para que, por ejemplo, pueda invocarlo utilizando bitmapconvert test.bmp > test.h . Tenga en cuenta que hace varias suposiciones con respecto al tamaño del mapa de bits y la profundidad de bits, por lo que de ninguna manera lo es el "código de producción", por lo que en algún momento es posible que desee seguir analizando el formato del archivo de mapa de bits.

#include "stdafx.h"
#include <stdio.h>
#include <stdint.h>

#define BITMAP_WIDTH 10
#define BITMAP_HEIGHT 10

#pragma pack (1)
struct PIXEL_DEF {
    uint8_t B, G, R;
} pixels[BITMAP_HEIGHT][BITMAP_WIDTH];

void read_bitmap_data(FILE *bmp)
{
    uint32_t data_offset, curx = 0, cury = 0;

    fseek(bmp, 10, SEEK_SET); // Skip to offset to bitmap bits
    fread(&data_offset, sizeof(data_offset), 1, bmp);
    fseek(bmp, data_offset, SEEK_SET); // Move to start of bits
    while (fread(&pixels[cury][curx], sizeof(PIXEL_DEF), 1, bmp))
    {
        curx++;
        if (curx >= BITMAP_WIDTH)
        {
            // Rows padded to 4 bytes, so we may need to skip some data
            fseek(bmp, 32 - curx * sizeof(PIXEL_DEF) % 32, SEEK_CUR);
            curx = 0;
            cury++;
        }
    }
    fclose(bmp);
}

// Following assumes top-left to bottom-right order, you may need to change
void dump_bitmap()
{
    int x, y;

    printf("const uint8_t bitmap_data[] = {\n");
    for (y=0; y < BITMAP_HEIGHT; y++)
    {
        for (x=0; x < BITMAP_WIDTH; x++)
        {
            if (x == 0)
                printf("\t");
            else
                printf(",");
            printf("0x%02X,0x%02X,0x%02X", pixels[y][x].R, pixels[y][x].G, pixels[y][x].B);
        }
        if (y < BITMAP_HEIGHT)
            printf(",");
        printf("\n");
    }
    printf("};\n");
}

int _tmain(int argc, TCHAR* argv[])
{
    FILE *bmp;

    if (argc != 2)
        printf("Usage: BitMapConvert infile.bmp");
    else {
        if (bmp = _wfopen(argv[1], _T("rb")))
        {
            read_bitmap_data(bmp);
            dump_bitmap();
        }
    }
    return 0;
}

El mapa de bits de 10 x 10 que usé para las pruebas tiene el siguiente patrón.

La salida generada desde el programa anterior se incluyó al comienzo del siguiente pseudocódigo que es mi interpretación de la hoja de datos de cómo deben enviarse los datos al dispositivo. Los siguientes retrasos son en el modo de baja velocidad, use la mitad de los valores para alta velocidad (aunque el reinicio puede permanecer igual). El pin 7 está conectado a VDD para baja velocidad y se deja desconectado para alta velocidad, por lo que deberá verificar cómo está configurado su hardware. Si es posible, la velocidad baja será más fácil.

const uint8_t bitmap_data[] = {
    0x00,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0xFF,0xFF,
    0xFF,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0xFF,
    0xFF,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,
    0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,
    0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,
    0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,
    0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,
    0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0xFF,
    0xFF,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,
    0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,
};

void send_zero()
{
    set_DI_high();
    delay_us(0.5);
    set_DI_low();
    delay_us(2);
}

void send_one()
{
    set_DI_high();
    delay_us(1.2);
    set_DI_low();
    delay_us(1.3);
}

void send_reset()
{
    set_DI_low();
    delay_us(50);
    set_DI_high();
}

void send_image()
{
    uint8_t i;

    send_reset();
    for (i=0; i < sizeof(bitmap_data); i++)
    {
        if (bitmap_data[i] & 0x80) send_one() else send_zero();
        if (bitmap_data[i] & 0x40) send_one() else send_zero();
        if (bitmap_data[i] & 0x20) send_one() else send_zero();
        if (bitmap_data[i] & 0x10) send_one() else send_zero();
        if (bitmap_data[i] & 0x08) send_one() else send_zero();
        if (bitmap_data[i] & 0x04) send_one() else send_zero();
        if (bitmap_data[i] & 0x02) send_one() else send_zero();
        if (bitmap_data[i] & 0x01) send_one() else send_zero();
    }
}

Como puede ver, el protocolo no es SPI y uno de los desafíos será obtener el tiempo correcto dentro de +/- 150nS especificado en la hoja de datos, que es aproximadamente 1 ciclo a 8MHz. En lugar de utilizar cualquier forma de delay_us , es probable que tenga que usar las instrucciones de nop y tener en cuenta los retrasos de tiempo causados por la configuración de los puertos y las llamadas de función, etc. A veces, examinar la salida del compilador del compilador puede ser útil a ese respecto Y un alcance siempre es útil para verificarlo. La hoja de datos parece mostrar el mismo valor de 150 nS para los modos de velocidad alta y baja. Puede que esté en modo de baja velocidad, pero es un poco menos crítico en la práctica.

Habiendo dicho que acabo de ver la biblioteca FastSPI que mencionaste y menciona el soporte para ese dispositivo. Parece que usa el canal SPI de una manera no estándar (no es que haya ningún problema con eso) para ayudar a aliviar las restricciones de tiempo. Por lo tanto, un buen punto de partida sería intentar usarlo en combinación con la tabla de mapa de bits anterior.

    
respondido por el PeterJ

Lea otras preguntas en las etiquetas