ESP8266 und WS2812-Streifen

OP #4417662
Lesenswert?
• ▲
▼
Liebes Forum,

ich krieg das einfach nich gebacken. Hab einen ESP8266 (WROOM-02 und 
AIThinker ESP-12e), der mit Arduino (1.6.7) in "Native-C" Arduino SDK 
Version 2.0.0 einen WS2812-Streifen (60 LEDs) füttern soll.

Dazu hab ich ein popeliges Programm geschustert, das einfach seriell 180 
Bytes entgegennimmt und diese mit der folgenden Routine auf den GPIO 
schreibt:
1
static inline uint32_t _getCycleCount(void) {
2
  uint32_t cycles;
3
  __asm__ __volatile__("rsr %0,ccount":"=a" (cycles));
4
  return cycles;
5
}
6
static void ICACHE_RAM_ATTR ws2812_write(uint8_t *pixels, uint32_t len) {
7
  uint8_t *p, *end, pixel, mask;
8
  uint32_t t, t0h, t1h, ttot, c, start_time, pin_mask;
9
  pin_mask = 1 << LEDOUT_PIN;
10
  p =  pixels;
11
  end =  p + len;
12
  pixel = *p++;
13
  mask = 0x80;
14
  start_time = 0;
15
  t0h  = (1000 * system_get_cpu_freq()) / 3022;  // 0.35us (spec=0.35 +- 0.15)
16
  t1h  = (1000 * system_get_cpu_freq()) / 1477;  // 0.70us (spec=0.70 +- 0.15)
17
  ttot = (1000 * system_get_cpu_freq()) /  800;  // 1.25us (MUST be >= 1.25)
18
  while (true) {
19
    if (pixel & mask) {
20
        t = t1h;
21
    } else {
22
        t = t0h;
23
    }
24
    while (((c = _getCycleCount()) - start_time) < ttot); // Wait for the previous bit to finish
25
    GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, pin_mask);      // Set pin high
26
    start_time = c;                                       // Save the start time
27
    while (((c = _getCycleCount()) - start_time) < t);    // Wait for high time to finish
28
    GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, pin_mask);      // Set pin low
29
    if (!(mask >>= 1)) {                                  // Next bit/byte
30
      if (p >= end) {
31
        break;
32
      }
33
      pixel= *p++;
34
      mask = 0x80;
35
    }
36
  }
37
}

Die Funktion rufe ich wie folgt auf:
1
uint8_t ledBuf[180];
2
//...
3
noInterrupts();
4
ws2812_write( ledBuf, sizeof(ledBuf) );
5
interrupts();

Das funktioniert meistens. Leider kommen treten sporadisch LED-Glitches 
auf, bei denen Farbwerte teilweise in die Farbe der nächsten LED 
rutschen (also blau 1->grün2 usw.), insbesondere (aber nicht nur) bei 
den mittleren bis hinteren LEDs. Und gefühlt tritt es beim schnellen 
Senden häufiger auf.

Es liegt wohl nicht an Fehlern an der seriellen (PC->ESP) Übertragung, 
das ganze passiert auch, wenn ich einfach einen statischen Buffer mit 
100Hz sende, Hardcore-Test mit:
1
memset(ledBuf, 0xAA, sizeof(ledBuf));
2
noInterrupts(); ws2812_write( ledBuf, sizeof(ledBuf) ); interrupts();
3
memset(ledBuf, 0x55, sizeof(ledBuf));
4
noInterrupts(); ws2812_write( ledBuf, sizeof(ledBuf) ); interrupts();

Ich kann das mangels Logic-Analyser nicht elektrisch in ganzer Länge 
debuggen. Am Oszi schaut das Timing mit 330ns kurz,  680ns lang und 
insgesamt 1,2µs gut (siehe 1.jpg) aus, ich habe aber viel Ringing (siehe 
2.jpg).

Mit 50 Ohm in Reihe ist das Ringing weg, das Signal schaut "perfekt" 
aus, nur der Streifen tut nichts mehr.

Deswegen die Frage: Hat schon mal jemand diese Kombination erfolgreich 
und "langzeitstabil" am Laufen und könnte sagen, wie das elektrisch und 
wie in Software gelöst ist?

Danke, Christoph
Angehängte Dateien:
Gast #4417675
Lesenswert?
• ▲
▼
Hallo,

mal eine ganz doofe Frage, mit welcher Spannung betreibst du die WS2812? 
Laut Datenblatt brauchen die 5V, damit ergibt sich für den High-Pegel 
eine Mindest-Spannung von 0.7 * 5V = 3,5V. Im Oszi sieht es aber so aus, 
als wenn dein Steuersignal nur einen Pegel von 3,3V hat.

Gruß
Specki

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.