WS2812 es un chip led encapsulado de tipo smd 5050 que internamente tiene un driver capaz de controlar 1 led RGB, ademas, chip WS2812 posee un estructura interna simple para poder controlar de manera practia un led RGB. El WS2812 dispone de 4 pines: Vdd (3,5 a 5.3VDC), GND, Din y Dout. A través de los pines Din y DOUT es donde sucede la magia. Los bits de datos que representan el brillo RGB son alimentados en serie en el pasador Din, y el chip de tiras a cabo los primeros 24 bits (8 bits cada uno de R, G, B) y envía los bits restantes a través del pin Dout. Mediante la conexión de los LED en una cadena, con el Dout de un LED debe ir a la Din de el siguiente LED, cada led solo necesita 24 bits, y envía el resto de la secuencia de datos afuera al siguiente LED. En teoría no hay límite para el número de LEDs que puede manejar con una sola línea de datos, la única limitación es que el tiempo que tarda en actualizar todos los LEDs.
DESCRIPCIÓN DEL CHIP LED WS2812
- Circuito de control y chip RGB integrado en un solo encapsulado.
- Intensidad de brillo programable de 8 bits.
- Frecuencia de trabajo de 400Hz.
- Transmisión serial de datos a 800Kbps.
- 1024 leds RGB en cascada de hasta 5 metros de distancia.
APLICACIONES
- Lamparas de luminosidad.
- Luces decorativas.
- Luces para acuarios.
- Iluminación.
- Luces Domótica.
VELOCIDAD DE TRANMISIÓN DE DATOS EN EL CHIP WS2812
Todos los protocolos de datos en serie requieren un reloj para volver a montar los datos recibidos. Este reloj puede ser una señal de reloj explícita como la línea SCK en un dispositivo SPI, o el reloj puede ser un reloj implícita, previamente acordados, tales como la configuración de velocidad de transmisión en un dispositivo UART (con el inicio y bits de parada que sirve para sincronizar los datos en el reloj acordado previamente), o el reloj pueden ser construidos en el flujo de datos en serie. El WS2812 utiliza una forma de este tercer método, mediante el cual cada bit consiste en un «1» seguido de un ‘0’, y el valor del bit se determina únicamente por si el ‘1’ intervalo es más largo o más corto que el intervalo del ‘0’ . Para el WS2812, cada bit se define así:
- Bit 0: HI 0.40us, 0.85us LO
- Bit 1: HI 0.80us, 0.45us LO
Cada uno de estos tiempos tiene una tolerancia de +/- 0.15us, por lo que hay una buena cantidad de margen de maniobra dado a la sincronización de datos en serie. Esto es común con datos en serie de auto-sincronizado, donde es sólo relaciones de «1» a «0» el caso, dentro de los límites de tiempo amplios.
Como se puede ver a partir de estos números, un solo bit de datos se demora 1.25us. Esto significa que un solo byte toma 10us, y los 3 bytes de datos RGB toma 30us. Es importante tener en cuenta estos tiempos cuando se añade mas led en cascada o serie. Además, tenga en cuenta que no hay ningún retraso o tiempo de descuento entre los bits o bytes. El único retardo de tiempo que cada vez se suman a la corriente de datos es el retardo de ‘reset’ de al menos 50us (pero puede ser cualquier duración más larga que eso). Así, un inactivo ‘0’ en la línea de salida de datos de al menos 50us Reinicia todos los chips para el siguiente lote de datos entrantes.
ESCOGER UN MICROCONTROLADOR
Entre las familias de microcontroladores que estamos usando en tutoriales anteriores, vamos a utilizar un PIC para conducir los chips WS2812. Una de las principales razones de esta elección es que el WS2812 es esencialmente un chip de 5V, y PIC se puede ejecutar a 5V, a diferencia de la mayoría ARM Cortex M3 u otros. Esto nos ahorra tener que derivar una tensión de 3,3 V de la tensión del controlador chip LED 5V, y de tener que suministrar un nivel de un 3,3 al controlador LED WS2812.
HACER LAS MATEMÁTICAS
Muchos PIC se pueden ejecutar con un oscilador interno de 8 MHz, o 0.125us de reloj. Esto significa que un bit de datos que dura 1.25us está a sólo 10 relojes del microcontrolador, resulta que eso no es mucho tiempo, pero escribir el código en ENSAMBLADOR se puede lograr controlar el WS2812 adecuadamente con un PIC de 8 MHz. Es un ajuste apretado, pero se puede hacer. No podemos obtener el tiempo exacto especificado anteriormente, pero podemos obtener el tiempo que le quede bien dentro de los límites de tiempo. Para ser más específicos, por cada bit=0 que se envié se relizará 3 pulsos para el «LO» y 7 pulsos para «HI», y por cada bit=1 que se envie sera 4 pulsos «LO» y 6 pulsos «HI». Además, tenemos que mantener a este momento a través de una serie de N bytes (o más bien, 3 * N N bytes para LEDs).
CIRCUITO CONEXIÓN CHIP LED WS2812 Y PIC16F1829
EJEMPLO LED WS2812 Y PIC16F1829
Se realizará un ejemplo para controlar 3 led rgb ws2812 a través del pin RC0, se desarrollará un juego de luces.
Código principal MAIN.
#define _XTAL_FREQ 32000000UL
#include "fuses.h"
#include
#include "ws2812.h"
void main(void) {
OSCCON = 0b11110000; // PLLEN=1(x4), IRCF=8Mhz, SCS=WORD1_FOSC_INTERNAL
ws2812_Init();
while (1) {
ws2812_setPixelColorLed(1, ws2812_Color(255, 0, 0));
ws2812_Show();
__delay_ms(1000);
ws2812_setPixelColorLed(2, ws2812_Color(0, 255, 0));
ws2812_Show();
__delay_ms(1000);
ws2812_setPixelColorLed(3, ws2812_Color(0, 0, 255));
ws2812_Show();
__delay_ms(1000);
ws2812_setPixelColorLed(1, ws2812_Color(127, 127, 127));
ws2812_Show();
__delay_ms(1000);
ws2812_setPixelColorLed(1, ws2812_Color(127, 0, 0));
ws2812_Show();
__delay_ms(1000);
ws2812_setPixelColorLed(2, ws2812_Color(0, 127, 0));
ws2812_Show();
__delay_ms(1000);
ws2812_setPixelColorLed(3, ws2812_Color(0, 0, 127));
ws2812_Show();
__delay_ms(1000);
}
return;
}
Código WS2812.
#ifndef WS2812_H
#define WS2812_H
#define STRIP_SIZE 3
#define pin_strip_led LATCbits.LATC0
volatile unsigned char Strip_RGBData[STRIP_SIZE][3] = {0};
//takes a 24bit color and stores it in the array split it in 3 8bit variables
void ws2812_setPixelColorLed(unsigned char pixel, unsigned long color) {
Strip_RGBData[pixel][0] = (char) (color >> 16);
Strip_RGBData[pixel][1] = (char) (color >> 8);
Strip_RGBData[pixel][2] = (char) (color);
}
//The same above, but does take separated values, "OVERLOADED FUNCTION"
void ws2812_setPixelColorRGB(unsigned char pixel, unsigned char r, unsigned char g, unsigned char b) {
Strip_RGBData[pixel][0] = r;
Strip_RGBData[pixel][1] = g;
Strip_RGBData[pixel][2] = b;
}
//Makes a 24bit color from 3 8bit color variables
unsigned long ws2812_Color(unsigned char r, unsigned char g, unsigned char b) {
return ((unsigned long) r << 16) | ((unsigned long) g << 8) | b;
}
//Output the Strip_RGBData array to the chips
void ws2812_Show() {
unsigned char x, y, z;
for (x = 0; x < STRIP_SIZE; x++) {
for (y = 0; y < 3; y++) {
for (z = 0; z < 8; z++) {
if (Strip_RGBData[x][y] & (1 << (7 - z))) {
pin_strip_led = 1;
} else {
pin_strip_led = 0;
}
}
}
}
__delay_us(40);
}
void ws2812_ClearAll() {
for (int i = 0; i < STRIP_SIZE; i++) {
for (int j = 0; j < 3; j++) {
Strip_RGBData[i][j] = 0;
}
}
ws2812_Show();
}
void ws2812_SetAll(unsigned char value) {
for (int i = 0; i < STRIP_SIZE; i++) {
for (int j = 0; j < 3; j++) {
Strip_RGBData[i][j] = value;
}
}
ws2812_Show();
}
void ws2812_Init() {
ws2812_Show();
}
#endif /* WS2812_H */
Código FUSES.
#ifndef FUSES_H
#define FUSES_H
// CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = ON // Flash Program Memory Code Protection (Program memory code protection is enabled)
#pragma config CPD = ON // Data Memory Code Protection (Data memory code protection is enabled)
#pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = ON // Internal/External Switchover (Internal/External Switchover mode is enabled)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = ON // PLL Enable (4x PLL enabled)
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = ON // Low-Voltage Programming Enable (Low-voltage programming enabled)
#endif /* FUSES_H */
Deja una respuesta
Lo siento, debes estar conectado para publicar un comentario.