Forum: Mikrocontroller und Digitale Elektronik WS2812B datenkompatibel zu WS2812?


von Peter Z. (Gast)


Angehängte Dateien:

Lesenswert?

Hi,

ich habe einen LED-Streifen mit 4 x WS2812 aufgebaut, funktioniert seit 
Monaten wunderbar am ATtiny.

Habe dann bei Amazon einen Streifen mit 60 Stück WS2812B gekauft. 
Betreibe beide Streifen parallel, bei dem im Internet gekauften Streifen 
ist nix zu sehen!!! Wie kann das sein?
Mit dem Oszilloskop sehe ich, wie die Datenpakete von LED zu LED 
weitergereicht werden und das jeweils erste Datenpacket wird 
einbehalten.

(Ist quasi wie in der Schule, wenn Zettel verteilt werden:
"Einen nehmen, Rest weitergeben")

Ist der bei Amazon gekauft Streifen Schrott, oder haben der WS2812 und 
der WS2812B unterschiedlichen Datenformate?
Die Zeiten für T0H, T1H, T0L unterscheiden sich laut den Datenblättern 
für den WS2812 und den WS2812B minimal um jeweils 0,05us während die 
Abweichung bei T1L 0,15us beträgt.
ich habe diese WS2812_send_array Routine, eine Änderung um 0,05us bzw. 
0,15us scheint recht schwierig zu sein, ein NOP sind bei 8MHz ja schon 
0,125us!
1
//*********************************************************************
2
#define ws2812_port 0x02 // Number of the data port register
3
#define ws2812_pin 2 // Number of the data out pin
4
void ws2812_sendarray_8Mhz(void)
5
{
6
  unsigned char *data = &color[0];
7
  unsigned char curbyte;
8
  unsigned char ctr;
9
  unsigned char datlen = 12;
10
  while (datlen--) {
11
    curbyte = *data++;
12
    asm volatile(
13
    " ldi %0,8    \n\t"
14
    "loop%=:    \n\t"
15
    " ROL %1    \n\t"
16
    " dec %0    \n\t"
17
    " sbi %2, %3  \n\t"
18
    " brcs .+2    \n\t"
19
    " cbi %2, %3  \n\t"
20
    " brcc .+2    \n\t"
21
    " cbi %2, %3  \n\t"
22
    " brne loop%=  \n\t"
23
    : "=&d" (ctr)
24
    : "r" (curbyte), "I" (ws2812_port), "I" (ws2812_pin)
25
    );
26
    // loop overhead including byte load is 6+1 cycles
27
  }
28
}
29
//*********************************************************************
SOS

von Conny G. (conny_g)


Lesenswert?

Die sind eigentlich Datenkompatibel, und die Toleranzen des Protokolls 
sind sehr hoch.
Hast auch Spannung und Masse richtig angeschlossen?
Liefert das Netzteil genug Strom?

von Peter Z. (Gast)


Lesenswert?

Conny G. schrieb:
> Hast auch Spannung und Masse richtig angeschlossen?

Ich denke mal ja, sonst könnte ich auf dem Oszilloskop ja nicht so schön 
sehen, wie die Datenpackete weitergereicht werden.

> Liefert das Netzteil genug Strom?
Der neue LED-Streifen braucht kaum Strom, es leuchtet ja überhaupt nix.
Nur der alte LED-Streifen blinkt munter vor sich hin.

von Conny G. (conny_g)


Lesenswert?

Du könntest mal versuchen die erste LED abzuschneiden. Ich habe schon 
öfter gelesen (mir noch nicht passiert), dass die gerne kaputt geht.
U.a. soll man nie das Datensignal anlegen, bevor die Spannung am 
Streifen ist, wenn ich mich richtig erinnere.

Was allerdings dagegen spricht, dass Du das weiterreichen des Signals am 
Oszi siehst. Das würde nicht geschehen, wenn die erste LED kaputt wäre.

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Peter Zz schrieb:
> Der neue LED-Streifen braucht kaum Strom, es leuchtet ja überhaupt nix.
> Nur der alte LED-Streifen blinkt munter vor sich hin.

 Dann hänge mal den alten LED-Streifen einfach hinter den neuen und
 prüfe ob es immer noch leuchtet.

von Peter Z. (Gast)


Angehängte Dateien:

Lesenswert?

Marc Vesely schrieb:
> Dann hänge mal den alten LED-Streifen einfach hinter den neuen und
> prüfe ob es immer noch leuchtet.

Genau das habe ich jetzt probiert und tatsächlich, nachdem das Signal 
durch einen WS2812B durch ist, enthält es nur noch "0" siehe Bild!
Der ATtiny10 sendet immer "0x0F"
Das gelbe Signal ist vor dem WS2812B, das blaue dahinter.
Habe das mit WS2812B aus verschiedenen Lieferungen probiert, immer das 
selbe!
Was tun?

von Peter Z. (Gast)


Angehängte Dateien:

Lesenswert?

Konnte den Bug jetzt fixen  :-)

Ein kleines nop verändert das Timing so,
das WS2812 und WS2812B das Signal verstehen.
1
//*********************************************************************
2
#define ws2812_port 0x02 // Number of the data port register
3
#define ws2812_pin 2 // Number of the data out pin
4
void ws2812_sendarray_8Mhz(void)
5
{
6
  unsigned char *data = &color[0];
7
  unsigned char curbyte;
8
  unsigned char ctr;
9
  unsigned char datlen = 12;
10
  while (datlen--) {
11
    curbyte = *data++;
12
    asm volatile(
13
    " ldi %0,8    \n\t"
14
    "loop%=:    \n\t"
15
    " ROL %1    \n\t"
16
    " dec %0    \n\t"
17
    " sbi %2, %3  \n\t"
18
    " brcs .+2    \n\t" 
19
    " cbi %2, %3  \n\t"
20
    " brcc .+2    \n\t"
21
    " nop         \n\t" // dieses kleine nop macht Daten auch für WS2812B verständlich!!!
22
    " cbi %2, %3  \n\t"
23
    " brne loop%=  \n\t"
24
    : "=&d" (ctr)
25
    : "r" (curbyte), "I" (ws2812_port), "I" (ws2812_pin)
26
    );
27
  }
28
}
29
//*********************************************************************
YO

von Conny G. (conny_g)


Lesenswert?

Spannend. Dann war das Timing vorher genau an der Grenze.

von Simon K. (simon) Benutzerseite


Lesenswert?

Warum auch immer man dort Assembler braucht... Angst, dass C zu langsam 
ist? ;-)

von Conny G. (conny_g)


Lesenswert?

Simon K. schrieb:
> Warum auch immer man dort Assembler braucht... Angst, dass C zu langsam
> ist? ;-)

Bisschen Woodoo muss immer sein :-)

von H.Joachim S. (crazyhorse)


Lesenswert?

Ist sowas nicht besser mit nem Timer erledigt? Toggle on compare + 
OCR-Interrupt, der nen nächsten OCR-Wert schreibt?

von holger (Gast)


Lesenswert?

>Ist sowas nicht besser mit nem Timer erledigt? Toggle on compare +
>OCR-Interrupt, der nen nächsten OCR-Wert schreibt?

Damit bekommt man kein ausreichend genaues Timing hin.
Alleine der Aufruf des Interrupts hängt doch schon davon ab
welcher OP Code mit wievielen Takten noch zuende geführt wird.

Am besten ist eine Hardware die das ganze komplett selbst
erledigen kann. Z.B. per DMA. Hat der AVR ja nun aber nicht.

Ich bevorzuge LED Stripes mit LPD8806. Die sind zwar teuer,
aber um Timings braucht man sich da nicht die Bohne Gedanken machen.
Einfach per SPI die Daten reinprügeln. Da ist es auch völlig
Wurst ob da noch ein Timer oder UART massiv mit Interrupts reinhaut.

von H.Joachim S. (crazyhorse)


Lesenswert?

Ok, hatte auf dem Foto 100µs als Zeitbasis gesehen, sind aber 1µs.
Bei ca. 0,3µs Pulslänge macht das mit nem AVR-Timer natürlich keinen 
Sinn.

von Peter Z. (Gast)


Lesenswert?

Simon K. schrieb:
> Warum auch immer man dort Assembler braucht... Angst, dass C zu langsam
> ist? ;-)
1
//*********************************************************************
2
#define ws2812_pin 2 // Number of the data out pin
3
void ws2812_sendarray_8Mhz(uint8_t curbyte)
4
{
5
  for(uint8_t bit_counter = 8;bit_counter;bit_counter--)
6
  {
7
    PORTB |= (1 << ws2812_pin);
8
    if((curbyte & 0x80) == 0)
9
    {
10
      PORTB &= ~(1 << ws2812_pin);
11
    }
12
    else
13
    {
14
      asm volatile("NOP");
15
      asm volatile("NOP");
16
      PORTB &= ~(1 << ws2812_pin);
17
    }
18
    curbyte <<= 1;
19
  }
20
}
21
//*********************************************************************
dies funktioniert jetzt auch ohne Assembler Voodoo sehr schön.
Nur hat man im Hinterkopf die Angst, das der Compiler das anders 
compilieren könnte und schon ist das exakte Timing futsch.

von Conny G. (conny_g)


Lesenswert?

Da kann ein Compiler nicht besonders viel variieren würde ich sagen.

Wieso eigentlich nicht so?
1
//*********************************************************************
2
#define ws2812_pin 2 // Number of the data out pin
3
void ws2812_sendarray_8Mhz(uint8_t curbyte)
4
{
5
  for(uint8_t bit_counter = 8;bit_counter;bit_counter--)
6
  {
7
    PORTB |= (1 << ws2812_pin);
8
    if((curbyte & 0x80) != 0)
9
    {
10
      asm volatile("NOP");
11
      asm volatile("NOP");
12
    }
13
    PORTB &= ~(1 << ws2812_pin);
14
    curbyte <<= 1;
15
  }
16
}
17
//*********************************************************************

: Bearbeitet durch User
von Peter Z. (Gast)


Lesenswert?

Conny G. schrieb:
> Wieso eigentlich nicht so?

Doch sieht gut aus,
kann es nur jetzt im Moment nicht mehr testen
da ich gerade alles weggeräumt habe...

von Ales D. (testus)


Lesenswert?

Das Timing kann man anscheinend auch entspannter angehen...

http://wp.josh.com/2014/05/13/ws2812-neopixels-are-not-so-finicky-once-you-get-to-know-them/

habe es selber aber nicht ausprobiert

Grüße
Ales

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.