abril 28, 2024

VARIOS – Tutorial de uso de matrices WS2812

Written by

Las cadenas de LED multicolor RGB WS2811 y WS2812 son muy versátiles y se pueden usar fácilmente en muchos proyectos caseros. Además su precio en distribuidores chinos como Aliexpress hace muy atractiva su compra. Recientemente se están vendiendo en estos distribuidores arreglos de estas cadenas en forma de matriz, que vienen muy bien para hacer proyectos bastante espectaculares. Son tan fáciles de usar como las matrices tradicionales de un solo color, pero además éstas son multicolor.

El presente tutorial explica cómo hacer funcionar fácilmente una de estas matrices, de 8×32 pixeles, aunque se pueden encontrar también de 8×8, 16×16 y hasta 16×32.

A continuación pongo un enlace típico de producto en Aliexpress. Aunque puede que esté caducado, se pueden encontrar similares simplemente buscando ‘panel ws2812‘. https://es.aliexpress.com/item/1005003901833984.html?spm=a2g0o.order_detail.order_detail_item.3.6ba639d3RtE1lm&gatewayAdapt=glo2esp

Matriz RGB WS2812
Vista frontal de la matriz RGB
Vista trasera de la matriz RGB

En la parte trasera se ven tres conexiones: una de ellas en el centro para conectar 5 V y negativo, aunque también se pueden conectar en las otras; y dos conexiones con conector para poder hacer una cascada de matrices.

Para hacer funcionar la matriz voy a usar un Arduino Mega, aunque cualquier otro microcontrolador puede servir. Y hay varias librerías disponibles para esta plataforma, pero la que más fácil me ha parecido para usar es: Adafruit NeoMatrix. Si no se tiene instalada en el IDE Arduino, se selecciona directamente en el gestor de librerías, y necesita también tener instalada Adafruit_GFX y Adafruit_NeoPixel, pero el gestor se encarga de instalar las dependencias.

La conexión de la matriz al microcontrolador es muy sencilla: sólo necesita 5V, negativo y una patilla, que puede ser casi cualquiera disponible. En mi caso, para este ejemplo, he usado la patilla 5 de la tarjeta Mega. (NOTA: cuidado al conectar el cable negativo pues en la matriz es el de color blanco)

Conexión Mega - matriz
Conexiones entre Arduino Mega y la matriz RGB

Para hacer esta prueba y ya que no se van a encender todos los LED de la matriz con su máxima intensidad, por simplificar el montaje, he conectado la patilla positiva 5V al Arduino, aunque en un montaje definitivo y con más uso de la matriz se debería usar una fuente de 5 voltios independiente, o de lo contrario se podría estropear la tarjeta microcontroladora.

Como hay varios modelos de matrices, lo primero que se necesita saber es cómo están conectados interiormente los LED y para ello he usado la librería de cadenas LED FastLED, que es más sencilla de usar y me permite ver la conexión interna con este sencillo ejemplo, derivado del Blink:

#include <FastLED.h>

// How many leds in your strip?
#define NUM_LEDS 256

// For led chips like WS2812, which have a data line, ground, and power, you just
// need to define DATA_PIN.  For led chipsets that are SPI based (four wires - data, clock,
// ground, and power), like the LPD8806 define both DATA_PIN and CLOCK_PIN
// Clock pin only needed for SPI based chipsets when not using hardware SPI
#define DATA_PIN 5
#define CLOCK_PIN 13

// Define the array of leds
CRGB leds[NUM_LEDS];
int nLed=0;         // Número de LED en la cadena

void setup() { 
    // Uncomment/edit one of the following lines for your leds arrangement.
    // ## Clockless types ##
    FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);  // GRB ordering is assumed
}

void loop() { 
  // Turn the LED on, then pause
  leds[nLed] = CRGB::Red;
  FastLED.show();
  delay(500);
  nLed++;
  if (nLed>=NUM_LEDS)
  {
    for(int ii=0;ii<NUM_LEDS;ii++)
      leds[nLed] = 0;  
    FastLED.show();
    nLed=0;
  }
}

Cargando el programa en Arduino se puede ver cómo se encienden los LED en el vídeo, que es desde la esquina inferior derecha y en sentido vertical:

Ahora voy a usar la librería Adafruit_NeoMatrix y en este caso voy a usar el ejemplo tiletest, que viene con la librería, haciendo los siguientes cambios:

  • Fila 12: Patilla de conexión 5 (define PIN 5)
  • Fila 56: Declaración de la matriz ( Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(32, 8, 1, 1, PIN, NEO_TILE_TOP + NEO_TILE_LEFT + NEO_TILE_ROWS + NEO_TILE_PROGRESSIVE + NEO_MATRIX_BOTTOM + NEO_MATRIX_RIGHT + NEO_MATRIX_COLUMNS + NEO_MATRIX_ZIGZAG, NEO_GRB + NEO_KHZ800); )

La explicación de los distintos parámetros viene en el código, pero voy a aclarar los que tengo puestos en mi caso:

  • Como sólo tengo una matriz, no hay más conectadas en cascada, los parámetros NEO_TILE_XXX no hacen falta.
  • NEO_MATRIX_BOTTOM + NEO_MATRIX_RIGHT – porque el primer LED de la matriz está en la esquina inferior derecha, tal como se vio en el vídeo anterior.
  • NEO_MATRIX_COLUMNS – porque los LED de la matriz están organizados en columnas, en lugar de filas.
  • NEO_MATRIX_ZIGZAG – porque las columnas van alternadas, como en zig-zag, es decir, la primera columna se enciende de abajo a arriba, la siguiente se enciende de arriba a abajo, etc.
  • NEO_GRB + NEO_KHZ800 – es la forma más común de encontrar las matrices, con orden de colores GRB y frecuencia de trabajo a 800 KHz.

El código final con los cambios es:

// Adafruit_NeoMatrix example for tiled NeoPixel matrices.  Scrolls
// 'Howdy' across three 10x8 NeoPixel grids that were created using
// NeoPixel 60 LEDs per meter flex strip.

#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>
#ifndef PSTR
 #define PSTR // Make Arduino Due happy
#endif

#define PIN 5

// MATRIX DECLARATION:
// Parameter 1 = width of EACH NEOPIXEL MATRIX (not total display)
// Parameter 2 = height of each matrix
// Parameter 3 = number of matrices arranged horizontally
// Parameter 4 = number of matrices arranged vertically
// Parameter 5 = pin number (most are valid)
// Parameter 6 = matrix layout flags, add together as needed:
//   NEO_MATRIX_TOP, NEO_MATRIX_BOTTOM, NEO_MATRIX_LEFT, NEO_MATRIX_RIGHT:
//     Position of the FIRST LED in the FIRST MATRIX; pick two, e.g.
//     NEO_MATRIX_TOP + NEO_MATRIX_LEFT for the top-left corner.
//   NEO_MATRIX_ROWS, NEO_MATRIX_COLUMNS: LEDs WITHIN EACH MATRIX are
//     arranged in horizontal rows or in vertical columns, respectively;
//     pick one or the other.
//   NEO_MATRIX_PROGRESSIVE, NEO_MATRIX_ZIGZAG: all rows/columns WITHIN
//     EACH MATRIX proceed in the same order, or alternate lines reverse
//     direction; pick one.
//   NEO_TILE_TOP, NEO_TILE_BOTTOM, NEO_TILE_LEFT, NEO_TILE_RIGHT:
//     Position of the FIRST MATRIX (tile) in the OVERALL DISPLAY; pick
//     two, e.g. NEO_TILE_TOP + NEO_TILE_LEFT for the top-left corner.
//   NEO_TILE_ROWS, NEO_TILE_COLUMNS: the matrices in the OVERALL DISPLAY
//     are arranged in horizontal rows or in vertical columns, respectively;
//     pick one or the other.
//   NEO_TILE_PROGRESSIVE, NEO_TILE_ZIGZAG: the ROWS/COLUMS OF MATRICES
//     (tiles) in the OVERALL DISPLAY proceed in the same order for every
//     line, or alternate lines reverse direction; pick one.  When using
//     zig-zag order, the orientation of the matrices in alternate rows
//     will be rotated 180 degrees (this is normal -- simplifies wiring).
//   See example below for these values in action.
// Parameter 7 = pixel type flags, add together as needed:
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 pixels)
//   NEO_GRB     Pixels are wired for GRB bitstream (v2 pixels)
//   NEO_KHZ400  400 KHz bitstream (e.g. FLORA v1 pixels)
//   NEO_KHZ800  800 KHz bitstream (e.g. High Density LED strip)

// Example with three 10x8 matrices (created using NeoPixel flex strip --
// these grids are not a ready-made product).  In this application we'd
// like to arrange the three matrices side-by-side in a wide display.
// The first matrix (tile) will be at the left, and the first pixel within
// that matrix is at the top left.  The matrices use zig-zag line ordering.
// There's only one row here, so it doesn't matter if we declare it in row
// or column order.  The matrices use 800 KHz (v2) pixels that expect GRB
// color data.
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(32, 8, 1, 1, PIN,
  NEO_TILE_TOP   + NEO_TILE_LEFT   + NEO_TILE_ROWS   + NEO_TILE_PROGRESSIVE +
  NEO_MATRIX_BOTTOM + NEO_MATRIX_RIGHT + NEO_MATRIX_COLUMNS + NEO_MATRIX_ZIGZAG,
  NEO_GRB + NEO_KHZ800);

const uint16_t colors[] = {
  matrix.Color(255, 0, 0), matrix.Color(0, 255, 0), matrix.Color(0, 0, 255) };

void setup() {
  matrix.begin();
  matrix.setTextWrap(false);
  matrix.setBrightness(40);
  matrix.setTextColor(colors[0]);
}

int x    = matrix.width();
int pass = 0;

void loop() {
  matrix.fillScreen(0);
  matrix.setCursor(x, 0);
  matrix.print(F("Howdy"));
  if(--x < -36) {
    x = matrix.width();
    if(++pass >= 3) pass = 0;
    matrix.setTextColor(colors[pass]);
  }
  matrix.show();
  delay(100);
}

Y tras cargar el programa en el Arduino, el resultado es el que sigue:

Category : VARIOS

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Proudly powered by WordPress and Sweet Tech Theme