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.
    • Chipsa82undefined
      Chipsa82
      last edited by

      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
      • dc42undefined
        dc42 administrators
        last edited by

        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
        • fmaundefined
          fma
          last edited by

          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
          • T3P3Tonyundefined
            T3P3Tony administrators
            last edited by

            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
            • First post
              Last post
            Unless otherwise noted, all forum content is licensed under CC-BY-SA