Pantalla LED con tiras led WS2812

Hola a todos, perdonar si no lo hago todo correctamente ya que soy nuevo.

Estoy desarrollando una pantalla hecha a partir de tiras LED ws2812b, en primer lugar compre un rollo de 5 metros de estas tiras con una densidad de led de 30led/metro en total tenia 150 led.
Los iba a controlar mediante un software llamado Glediator y con un arduino mega cuando termine el montaje todo iba perfectamente tanto con el arduino mega como con el uno. Entonces decidi comprar los rollos de 60 led/metro para ganar un poco de resolucíon, pero cual es mi sorpresa que con estos nuevos rollos no funciona siendo de la misma marca y todo, solo cambia la cantidad de LED.

Alguien sabe por que pasa esto y si tiene solución???

Un saludo y gracias a todos.

El código que estoy usando es el siguiente que es para el arduino mega:

//##############################################################################
//##############################################################################
//                                                                             #
// Glediator to WS2812 pixel converter                                         #
// by R. Heller                                                                #
// V 1.0 - 07.01.2014                                                          #            
// wwww.SolderLab.de                                                           #
//                                                                             #
// Receives serial data in Glediator protocol format @ 1 MBit/s                #
// and distributes it to a connectect chain of WS2812 pixels                   #
//                                                                             #
// Adjust the correct DATA PIN and the correct NUMBER OF PIXELS you are using  # 
// in the definitions section below before uploading this sketch to your       #
// Arduino device.                                                             #
//                                                                             #
// Maxiumim number of supported pixeles is 512 !!!                             #
//                                                                             #
// In the Glediator software set output mode to "Glediator_Protocol",          #
// color order to "GRB" and baud rate to "1000000"                             #
//                                                                             #
//##############################################################################
//##############################################################################


//##############################################################################
//                                                                             #
// Definitions --> Make changes ONLY HERE                                      #
//                                                                             #
// To find out the correct port, ddr and pin name when you just know the       #
// Arduino's digital pin number just google for "Arduino pin mapping".         #
// In the present example digital Pin 6 is used which corresponds to "PORTD",  #
// "DDRD" and "6", respectively.                                               #
//                                                                             #
//##############################################################################

#define DATA_PORT          PORTA
#define DATA_DDR           DDRA
#define DATA_PIN           0 //This relates to PDA0 (PIN 22 on the Mega 2560)
#define NUMBER_OF_PIXELS   900


//##############################################################################
//                                                                             #
// Variables                                                                   #
//                                                                             #
//##############################################################################

unsigned char display_buffer[NUMBER_OF_PIXELS * 3];
static unsigned char *ptr;
static unsigned int pos = 0;

boolean go = 0;


//##############################################################################
//                                                                             #
// Setup                                                                       #
//                                                                             #
//##############################################################################

void setup()
{
  // Set data pin as output
  DATA_DDR |= (1<<DATA_PIN);

  
  // Initialize UART
  UCSR0A |= (1<<U2X0);                                
  UCSR0B |= (1<<RXEN0)  | (1<<TXEN0) | (1<<RXCIE0);   
  UCSR0C |= (1<<UCSZ01) | (1<<UCSZ00)             ; 
  UBRR0H = 0;
  UBRR0L = 1; //Baud Rate 1 MBit (at F_CPU = 16MHz)
  
  ptr=display_buffer;
  
  //Enable global interrupts
  sei();
}


//##############################################################################
//                                                                             #
// Main loop                                                                   #
//                                                                             #
//##############################################################################

void loop()
{   
  if (go==1) 
  {
    cli();
    ws2812_sendarray(display_buffer, NUMBER_OF_PIXELS * 3); 
    sei();
    go=0;
  }
}


//##############################################################################
//                                                                             #
// UART-Interrupt-Prozedur (called every time one byte is compeltely received) #
//                                                                             #
//##############################################################################

ISR(USART0_RX_vect) 
{
  unsigned char b;
  b=UDR0;
  
  if (b == 1)  {pos=0; ptr=display_buffer; return;}    
  if (pos == (NUMBER_OF_PIXELS*3)) {} else {*ptr=b; ptr++; pos++;}  
  if (pos == ((NUMBER_OF_PIXELS*3)-1)) {go=1;}
}


//##############################################################################
//                                                                             #
// WS2812 output routine                                                       #
// Extracted from a ligh weight WS2812 lib by Tim (cpldcpu@gmail.com)          #
// Found on wwww.microcontroller.net                                           #
// Requires F_CPU = 16MHz                                                      #
//                                                                             #
//##############################################################################

void ws2812_sendarray(uint8_t *data,uint16_t datlen)
{
  uint8_t curbyte,ctr,masklo;
  uint8_t maskhi = _BV(DATA_PIN);
  masklo =~ maskhi & DATA_PORT;
  maskhi |= DATA_PORT;

  while (datlen--) 
  {
    curbyte = *data++;

    asm volatile
    (
      " ldi %0,8 \n\t" // 0
      "loop%=:out %2, %3 \n\t" // 1
      "lsl %1 \n\t" // 2
      "dec %0 \n\t" // 3
      " rjmp .+0 \n\t" // 5
      " brcs .+2 \n\t" // 6l / 7h
      " out %2,%4 \n\t" // 7l / -
      " rjmp .+0 \n\t" // 9
      " nop \n\t" // 10
      " out %2,%4 \n\t" // 11
      " breq end%= \n\t" // 12      nt. 13 taken
      " rjmp .+0 \n\t" // 14
      " rjmp .+0 \n\t" // 16
      " rjmp .+0 \n\t" // 18
      " rjmp loop%= \n\t" // 20
      "end%=: \n\t" 
      : "=&d" (ctr)
      : "r" (curbyte), "I" (_SFR_IO_ADDR(DATA_PORT)), "r" (maskhi), "r" (masklo)
    );
  }

}


//##############################################################################
//                                                                             #
// End of program                                                              #
//                                                                             #
//##############################################################################

Podría ser cuestión de protocolo o algo. ¿Difieren los pines de datos uno de otro?

Una vez había visto que para controlar un clon del WS2812 en forma DIP (de cabeza redondeada, la forma de LED que todos conocemos), había que incluir la librería FastLED.

No, las dos usan 3 pines y utilizan el mismo chip ws2812 por eso me resulta raro que no funcione una y la otra si.

Gracias por tu respuesta

¿Has visto esto?

// Maxiumim number of supported pixeles is 512 !!!

Posiblemente no sea del todo limitación del código; sino del microprocesador.

Deberías buscar si hay forma de manejar más que eso...

Edito: ese código es para los Arduinos basados en ATmega328P; hay una versión del programa para Arduino Mega, que dice que soporta hasta 1024 LEDs.
En otras palabras, sí había solución.

Edito de nuevo: ese otro código es para WS2801; así que retiro lo antes dicho... ::slight_smile:

Con arduino mega se pueden manejar hssta 2500 led eso de 512 hace referencia al Uno.

1 Like

En vez de 900 LEDs prueba colocando 512 para ver sí es cierto que es una limitante del microprocesador más que del programa.
Prácticamente no comprendo nada de código ensamblador, pero mi teoría es que se trata de emular el protocolo de estos LED, alternado el estado del pin especificado en intervalos muy precisos para así generar los 8 bits por color de cada LED.

El punto al que quiero llegar es que quizá trasferir 1536 bytes cada 40 milisegundos con ese protocolo serial sea el límite, porque ya más puede que un microprocesador a 16 MHz no dé la talla.

Dark_zopi:
Con arduino mega se pueden manejar hssta 2500 led eso de 512 hace referencia al Uno.

¿Dónde lo leíste? Porque en la página oficial de Solderlab no veo que digan algo al respecto.

Son calculos que ha echo la gente y e leido por foros. Pero de todas formas ya e probado con 50, 100, 300 led y el resultado sigue siendo el mismo. Se encienden los led pero con colores aleatorios.

Gracias por tu ayuda

A nadie se le ocurre nada. Empiezo a estar desesperado.

Dark_zopi:
el resultado sigue siendo el mismo. Se encienden los led pero con colores aleatorios.

¿Conexión defectuosa con tierra?

Cuando el voltaje de la fuente cae o la referencia a tierra no es estable; se suele corromper la señal de control.

La tierra esta bien ya que uso una fuente externa y las soldaduras estan revisadas. Ademas el polimetro de mala voltaje estable.

Dark_zopi:
Ademas el polimetro de mala voltaje estable.

Una cosa es "estable" y otra es "constante".

¿Seguro que a medida que vas subiendo la intensidad de cada color de cada LED, el voltaje de la fuente se mantiene constante?

No, eso es imposible ya que cada led va consumiendo un poco el voltaje, pero para unos 150 led si que deberia ser suficiente, de todas formas tiene varias entradas de corriente pars suplir la bajada de l tension.

No, eso es imposible ya que cada led va consumiendo un poco el voltaje,

No es semántica lo que corregiré sino algo conceptual.
Un led no consume tensión o voltage sino corriente.
Tu fuente debe ser capaz de entregar la corriente para todos los leds pero eso lo descarto.

Hace tiempo entre 1 o 2 años alguien estuvo consultando un problema similar. Hace poco trabajando con WS2812 y una Raspi experimenté el mismo problema pero en mi caso el Raspi entrega salidas HIGH en 3.3V y el WS2812 no funcionaba bien asi que armé una interfaz que levantó el nivel a 5V usando un par de transistores (en mi caso) y luego se comportó bien.

La salida del Raspi (en mi caso) era con una R de 470 ohms para proteger la salida conectada a la entrada DIN del WS2812

Bueno yo las alimento con una fuente externa ya que tengo 1200 leds y el arduino no da para tanto. Pero gracias por la info.

Creo que el problema viene por la sincronización de las tiras led ya que con las de 30 va y con las de 60 no. Ahora estoy probando a unir la tira de 30 con la de 60 y parece que quiere funcionar. Esta tarde seguiré trabajando en ellas.

Yo hablo de la salida del Arduino conectada a la entrada DIN.

No me lo tomes a mal, pero debes leer mucho mas y asegurarte que la primer tira de leds funcione.

Es cierto que MEGA puede con hasta 2400 leds, pero has mencionado que quieres una pantalla: el MCU debe tener memoria extra para que lo que vayas a animar con los neopixeles, se mueva con tasas de refresco decentes.

Es mucha corriente la que demandas.

Acá hay una buen base por la que deberías empezar y no desesperar, a veces es bueno ver las cosas desde lejos para refrescar las ideas:

Überguide-Neopixel

Uno mas con diagramas de alimentación

1000 neopixeles en arduino

PD: ten en cuenta que opinamos en función de lo que tú mismo nos dejas saber de tu proyecto, sería bueno ver que fuente estas usando, y como está el cableado, sería muy útil conocer la parte del sketch que controla los WS2812.

hola yo tengo un mega 2560 y no he podido hacer andar unos 50 leds ws2812 en arduino uno anda lo mas bien , erpo cuando lo hago en mega no andan, y he probado el codigo que tu pusiste y no anda tampoco, hay q hacer algo mas, yo tengo la rita conectafçda a 5v y el gnd conectado tambien con el arduino, y este codigo usa el pin 22. uso el jinx laplaca palpadea cuando prendo el jinx pero no hace nada,

suport para arduino mega :

http://solderlab.de/index.php/software/glediator/80-news/114-ws2801-glediator-arduino-mega