adafruit / Adafruit_CircuitPython_NeoPixel

CircuitPython drivers for neopixels.
MIT License
304 stars 99 forks source link

set_item will not accept input of type list like dotstar #12

Closed jerryneedell closed 6 years ago

jerryneedell commented 7 years ago

If the input to set_item is of type list then it gets ignored in this driver. If that is intentional, then it needs to be clearly documented. In contrast, the dotstar driver will accept a tuple or a list as input - it treats anything other than an int as a tuple and seems to work ok with a list.

An example of the problem is in this code example distributed with the trinket_m0 and gemma_m0 as main.py:

# Trinket IO demo
# Welcome to CircuitPython 2.0.0 :)

import board
from digitalio import DigitalInOut, Direction, Pull
from analogio import AnalogOut, AnalogIn
import touchio
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode
import adafruit_dotstar as dotstar
import time
import neopixel

# One pixel connected internally!
dot = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2)

# Built in red LED
led = DigitalInOut(board.D13)
led.direction = Direction.OUTPUT

# Analog input on D0
analog1in = AnalogIn(board.D0)

# Analog output on D1
aout = AnalogOut(board.D1)

# Digital input with pullup on D2
button = DigitalInOut(board.D2)
button.direction = Direction.INPUT
button.pull = Pull.UP

# Capacitive touch on D3
touch = touchio.TouchIn(board.D3)

# NeoPixel strip (of 16 LEDs) connected on D4
NUMPIXELS = 16
neopixels = neopixel.NeoPixel(board.D4, NUMPIXELS, brightness=0.2, auto_write=False)

# Used if we do HID output, see below
kbd = Keyboard()

######################### HELPERS ##############################

# Helper to convert analog input to voltage
def getVoltage(pin):
    return (pin.value * 3.3) / 65536

# Helper to give us a nice color swirl
def wheel(pos):
    # Input a value 0 to 255 to get a color value.
    # The colours are a transition r - g - b - back to r.
    if (pos < 0):
        return [0, 0, 0]
    if (pos > 255):
        return [0, 0, 0]
    if (pos < 85):
        return [int(pos * 3), int(255 - (pos*3)), 0]
    elif (pos < 170):
        pos -= 85
        return [int(255 - pos*3), 0, int(pos*3)]
    else:
        pos -= 170
        return [0, int(pos*3), int(255 - pos*3)]

######################### MAIN LOOP ##############################

i = 0
while True:
  # spin internal LED around! autoshow is on
  dot[0] = wheel(i & 255)

  # also make the neopixels swirl around
  for p in range(NUMPIXELS):
      idx = int ((p * 256 / NUMPIXELS) + i)
      neopixels[p] = wheel(idx & 255)
  neopixels.show()

  # set analog output to 0-3.3V (0-65535 in increments)
  aout.value = i * 256

  # Read analog voltage on D0
  print("D0: %0.2f" % getVoltage(analog1in))

  # use D3 as capacitive touch to turn on internal LED
  if touch.value:
      print("D3 touched!")
  led.value = touch.value

  if not button.value:
      print("Button on D2 pressed!")
      # optional! uncomment below & save to have it sent a keypress
      #kbd.press(Keycode.A)
      #kbd.release_all()

  i = (i+1) % 256  # run from 0 to 255
  #time.sleep(0.01) # make bigger to slow down

The function wheel returns its value as type list - using []. This will work for the dotstar driver but the me-pixel driver ignores the input since it is neither type int nor type tuple.

Modifying the code to return type tuple - use ()for the returns make it work for both.

jerryneedell commented 7 years ago

Would a fix be as simple as changing:

        if type(value) == tuple and len(value) == self.bpp:
            if self.bpp == 3:
                r, g, b = value
            else:
                r, g, b, w = value

to

        if ((type(value) == tuple) or (type(value) == list)) and len(value) == self.bpp:
            if self.bpp == 3:
                r, g, b = value
            else:
                r, g, b, w = value

Do we want list to be acceptable or force users to use tuples?

I have tested this change on a trinket_m0 with the Neopixel Jewel and it does work with the returned values from shell being type list. I'll generate pull request.

tannewt commented 7 years ago

Its not my intention to force tuples on everyone.

In fact, #5 was for me to fix it. I fixed it in DotStar when I redid it but haven't done that here. I'd suggest doing it the same way that I did in DotStar where we special case int and otherwise assume its a sequence like list or tuple. https://github.com/adafruit/Adafruit_CircuitPython_DotStar/blob/master/adafruit_dotstar.py#L122

jerryneedell commented 7 years ago

Sounds good. I’ll update it and resubmit a new pull request. I missed that it was already queued in #5.

Djsharma07 commented 6 years ago

Hello @jerryneedell, My device has 3 neopixel WS2812B RGB LEDs. I am using Pycom LoPy controller. I tried using this library I am getting an error: no module named "digitalio". I get the same error for "neopixel_write". Where can I find these libraries? Thank You.

jerryneedell commented 6 years ago

@Djsharma07 For the Pycom LoPy are you using micropython? I don't think circuitpython runs that board unless you have ported it. digitalio and these libraries are for circutpython ( https://github.com/adafruit/circuitpython ) and are not supported under MicroPython. If you are using circuitpython, please post your code. I'll be happy to give it a try.

Djsharma07 commented 6 years ago

@jerryneedell, Thanks a lot. It works on micropython. I'd try searching library accordingly. Do you have any idea of a good library for micropython?

jerryneedell commented 6 years ago

@Djsharma07 I thought neopixel support was included in micropython - see: https://docs.micropython.org/en/latest/esp8266/esp8266/tutorial/neopixel.html ah - that is for esp8266 - sorry - I am not familiar with LoPy

jerryneedell commented 6 years ago

@Djsharma07 you might find this useful - I have not tried it - just found it via "google lopy neopixel" good luck! https://github.com/aureleq/wipy-lopy-WS2812

Djsharma07 commented 6 years ago

@jerryneedell , Thanks for the help. I guess the latter one link would be more useful.

tannewt commented 6 years ago

This has been done.