terça-feira, setembro 03, 2013

LEDCube Kit v2: Programação

Neste post veremos a biblioteca padrão do LEDCube v2 para uso com a IDE do Arduino. Esta biblioteca permite gerar animações controlando individualmente os LEDs.


Coloquei LEDcubeLib.zip nos arquivos do blog com a biblitoteca padrão, desenvolvida por Rolf van Widenfelt e Mitch Altman. Para usar com a IDE do Arduino, os arquivos LEDcube.h, LEDcube.cpp e ledcube_iodefs.h devem ser colocados em uma pasta LEDcube criada dentro da pasta onde ficam os sketches.

A biblioteca define (em LEDcube.h) uma classe para interação com o cubo. Dando uma pequena simplificada, a declaração desta classe é:
class LEDcube{
  public:
 LEDcube(void);
 void Begin(void);
 void SetColor(uint8_t);
 void Clear(void);
 void DrawPixel(uint8_t x, uint8_t y, uint8_t z);
 uint8_t GetButton(uint8_t);
};
Para usar esta classe é necessário instanciá-la uma única vez (tipicamente declarando uma instância global) e chamar o método Begin (normalmente na função setup() do sketch Arduino). O método Clear apaga todos os LEDs. O método DrawPixel altera o estado de um LED, usando a "cor" (aceso ou apagado) escolhida através de SetColor. Por último, o método GetButton permite ler o estado do botão presente na placa. Esta interface é relativamente genérica, podendo suportar cubos de vários tamanhos e com mais opções de cores.

O programa abaixo acende sequencialmente os LEDs:
#include <LEDcube.h>

// objeto para manipulação dos LEDs
LEDcube cube;

// iniciação
void setup() 
{
  cube.Begin();
}

// Loop principal
void loop() 
{
  for (int z = 0; z < 3; z++)
    for (int y = 0; y < 3; y++)
      for (int x = 0; x < 3; x++)
      {
        cube.SetColor (COLOR_ON);
        cube.DrawPixel (x, y, z);
        delay (1000);
        cube.SetColor (COLOR_OFF);
        cube.DrawPixel (x, y, z);
      }
}
Como mencionei quando expliquei o funcionamento do hardware, o LEDcube utiliza multiplexação, não permitindo acender simultaneamente uma combinação qualquer de LEDs. Como a biblioteca esconde isto? Vamos examinar o seu fonte (LEDcube.cpp).

Um vetor, de nome fb, possui 27 posições, uma para cada LED. Os métodos Clear e DrawPixel afetam apenas este vetor em memória. A mágica toda é comandada pelo Timer1. O método Begin chama a rotina start_timer1 que programa o Timer1 para gerar uma interrupção a cada milisegundo.A cada interrupção um nível (ou plano) do cubo é desenhado. Para maior velocidade, isto é feito manipulando diretamente os registradores do ATmega conforme o conteúdo do vetor fb. O olho humano não é capaz de registrar mudanças tão rápidas, portanto enxergamos como se os três níveis estivessem acesos simultaneamente.

Num próximo post veremos uma biblioteca que eu escrevi que oferece uma interface de programação diferente para controle dos LEDs.

Nenhum comentário: