forkineye / ESPixelStick

Firmware for the ESPixelStick
http://forkineye.com/
542 stars 172 forks source link

ws2813/ws2818 support #29

Closed Strontium closed 7 years ago

Strontium commented 7 years ago

I was trailing this firmware with some new ws2813 strip and found it to be acting intermittently like it was having a data problem. After some research it seems while for the most part these new chips are similar to ws2811, the reset time between frames is longer (possibly to allow it to refactor the data and pass it though on the backup line) so while ws2811 supports minimum 50us reset time, the ws2813 chips require 300us as per these comments http://doityourselfchristmas.com/forums/showthread.php?44920-connect-2-kinds-of-pixels-after-each-other-possible-or-not&p=442708#post442708 All ws281x chips should work at 300us so it might be as simple a fix as changing line 73 in PixelDriver.h to 300L. Or split up the selection dialog and add in a new ws2813/ws2818 option.

If you don't beat me to it, at some point in the new year I will learn how to build from source and test this myself :) Thanks for the awesome firmware and making it open source.

rollercontainer commented 7 years ago

The external lib Adafruit_NeoPixel does not support WS2813 yet. Maybe the FastLED lib is a better choice as it already supports WS2813.

https://github.com/FastLED/FastLED

rollercontainer commented 7 years ago

Compiles, but I can not test it. `

include

include <E131.h>

include

define NUM_LEDS 60 / Number of pixels /

define UNIVERSE 1 / Universe to listen for /

define CHANNEL_START 1 / Channel to start listening at /

define DATA_PIN 0 / Pixel output - GPIO0 /

const char ssid[] = "........."; / Replace with your SSID / const char passphrase[] = "........"; / Replace with your WPA2 passphrase /

E131 e131;

CRGB leds[NUM_LEDS];

void setup() { // Uncomment/edit one of the following lines for your leds arrangement. // FastLED.addLeds<TM1803, DATA_PIN, RGB>(leds, NUM_LEDS); // FastLED.addLeds<TM1804, DATA_PIN, RGB>(leds, NUM_LEDS); // FastLED.addLeds<TM1809, DATA_PIN, RGB>(leds, NUM_LEDS); // FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS); // FastLED.addLeds<WS2812, DATA_PIN, RGB>(leds, NUM_LEDS); FastLED.addLeds<WS2813, DATA_PIN, RGB>(leds, NUM_LEDS); // FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS); //FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS); // FastLED.addLeds<APA104, DATA_PIN, RGB>(leds, NUM_LEDS); // FastLED.addLeds<UCS1903, DATA_PIN, RGB>(leds, NUM_LEDS); // FastLED.addLeds<UCS1903B, DATA_PIN, RGB>(leds, NUM_LEDS); // FastLED.addLeds<GW6205, DATA_PIN, RGB>(leds, NUM_LEDS); // FastLED.addLeds<GW6205_400, DATA_PIN, RGB>(leds, NUM_LEDS);

  // FastLED.addLeds<WS2801, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<SM16716, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<LPD8806, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<P9813, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<APA102, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<DOTSTAR, RGB>(leds, NUM_LEDS);

  // FastLED.addLeds<WS2801, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<SM16716, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<LPD8806, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<P9813, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<APA102, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<DOTSTAR, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);

Serial.begin(115200);
delay(10);

/* Choose one to begin listening for E1.31 data */
//e131.begin(ssid, passphrase);                       /* via Unicast on the default port */
e131.beginMulticast(ssid, passphrase, UNIVERSE);  /* via Multicast for Universe 1 */

/* Initialize output */
FastLED.show();

}

void loop() { / Parse a packet and update pixels / if(e131.parsePacket()) { if (e131.universe == UNIVERSE) { for (int i = 0; i < NUM_LEDS; i++) { int j = i * 3 + (CHANNEL_START - 1); leds[i].setRGB( e131.data[j], e131.data[j+1], e131.data[j+2]); } FastLED.show(); } } }`

bquesse commented 7 years ago

To add to this, using FastLED would also enable support of WS2801 pixels as well as a whole host of other chipsets. It's been ported to the ESP, so there should be no problems slotting it in in place of Adafruit's library.

forkineye commented 7 years ago

The ESPixelStick code uses a custom method I developed to generate the WS2811 pixel stream by offloading it to the UART. Both the NeoPixel libraries and FastLED bit-bang the stream which can lead to watchdog resets as it interrupts the wifi stack. If the only difference is the reset time as @Strontium noted, its a fairly quick and easy fix. I'll look into it when I get time, hoping to start working on some updates soon.

bquesse commented 7 years ago

Makes sense! Any chance WS2801 pixels would ever be supported? I've got a bunch kicking around I'd love to get on a PixelStick. Thanks for all the hard work you've put into this!

forkineye commented 7 years ago

I had WS2801 on my "todo" list for last year, but never got around to it. Most implementations just use SPI, but unfortunately the SPI interface isn't exposed on the ESP-01 module, which means it has to be done in software. I have some WS2801 pixels to test with, just have to get around to writing a "SPI-ish" driver for them and figure out how to handle timing without disrupting the wifi stack.

forkineye commented 7 years ago

Reset timing fixed as of 3.0-dev1