• Tags
  • Documentation
  • Order
  • Register
  • Login
Duet3D Logo Duet3D
  • Tags
  • Documentation
  • Order
  • Register
  • Login

WS2812B LED support?

Scheduled Pinned Locked Moved
Duet Hardware and wiring
4
4
1.1k
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • undefined
    Chipsa82
    last edited by 11 Feb 2018, 13:25

    Hi

    im thinking of using the WS2812B individually addressable LEDs in my printer for both lighting the printbed as well as signalizing individual printer states by chaning color (running, error…)

    Is there a way to address the data pin on these leds from Duet?

    thanks!

    Chipsa

    1 Reply Last reply Reply Quote 0
    • undefined
      dc42 administrators
      last edited by 11 Feb 2018, 13:49

      Those LEDs don't use a standard protocol, and are currently not supported in firmware.

      Duet WiFi hardware designer and firmware engineer
      Please do not ask me for Duet support via PM or email, use the forum
      http://www.escher3d.com, https://miscsolutions.wordpress.com

      1 Reply Last reply Reply Quote 0
      • undefined
        fma
        last edited by 12 Feb 2018, 10:08

        It is possible to drive them from a SPI bus. Here is an example in micropython:

        [[python]]
        # -*- coding: utf-8 -*-
        import gc
        import pyb
        class WS2812:
        """ Driver for WS2812 RGB LEDs. May be used for controlling single LED or chain of LEDs.
        """
        buf_bytes = (0x11, 0x13, 0x31, 0x33)
        def __init__(self, spi_bus=1, led_count=1, intensity=1):
        """
        """
        self.led_count = led_count
        self.intensity = intensity
        self.disable_irq = True
        # prepare SPI data buffer (4 bytes for each color)
        self.buf_length = self.led_count * 3 * 4
        self.buf = bytearray(self.buf_length)
        # SPI init
        self.spi = pyb.SPI(spi_bus, pyb.SPI.MASTER, baudrate=3200000, polarity=0, phase=1)
        # turn LEDs off
        self.show([])
        def show(self, data):
        """ Show RGB data on LEDs.
        Expected data = [(R, G, B), ...] where R, G and B are intensities of colors in range from 0 to 255.
        One RGB tuple for each LED.
        Count of tuples may be less than count of connected LEDs.
        """
        self.fill_buf(data)
        self.send_buf()
        def send_buf(self):
        """ Send buffer over SPI.
        """
        if self.disable_irq:
        pyb.disable_irq()
        self.spi.send(self.buf)
        pyb.enable_irq()
        else:
        self.spi.send(self.buf)
        gc.collect()
        def fill_buf(self, data):
        """ Fill buffer with bytes.
        """
        i = 0
        for byte in self.data_to_bytes(data):
        self.buf[i] = byte
        i += 1
        # turn off the rest of the LEDs
        while i < self.buf_length:
        self.buf[i] = self.buf_bytes[0]
        i += 1
        def data_to_bytes(self, data):
        """ Convert data to bytes.
        Note: Order of colors is changed from RGB to GRB because WS2812 LED has GRB order of colors.
        """
        for red, green, blue in data:
        for byte in self.color_to_bytes(green):
        yield byte
        for byte in self.color_to_bytes(red):
        yield byte
        for byte in self.color_to_bytes(blue):
        yield byte
        def color_to_bytes(self, color):
        """ Yields 4 buffer bytes representing color value (1 byte for each 2 bits).
        """
        color = int(color * self.intensity)
        for i in range(4):
        yield self.buf_bytes[(color & 0xC0) >> 6]
        color <<= 2
        def main():
        ring = WS2812(spi_bus=1, led_count=16)
        data = [
        (24, 0, 0),
        (0, 24, 0),
        (0, 0, 24),
        (12, 12, 0),
        (0, 12, 12),
        (12, 0, 12),
        (24, 0, 0),
        (21, 3, 0),
        (18, 6, 0),
        (15, 9, 0),
        (12, 12, 0),
        (9, 15, 0),
        (6, 18, 0),
        (3, 21, 0),
        (0, 24, 0),
        (8, 8, 8),
        ]
        ring.show(data)
        if __name__ == "__main__":
        main()
        [/i][/i]

        Frédéric

        1 Reply Last reply Reply Quote 0
        • undefined
          T3P3Tony administrators
          last edited by 12 Feb 2018, 16:33

          As in the oled thread, the easiest approach would be to use a little Arduino or equivalent to switch between the display chip and the Duet.

          www.duet3d.com

          1 Reply Last reply Reply Quote 0
          2 out of 4
          • First post
            2/4
            Last post
          Unless otherwise noted, all forum content is licensed under CC-BY-SA