DotStar en CircuitPython

Los DotStars utilizan dos cables, a diferencia de los NeoPixeles que usan un solo cable. Son muy similares, pero se les puede escribir a los DotStars mucho más rápido con SPI por hardware, y tienen ciclos de PWM mucho más rápidos, por lo que son mejores para pintar con luz.

Cualquiera de los pines puede ser usado pero si hay dos pines que puedan formar un puerto de SPI por hardware, la librería automáticamente se va a cambiar a SPI por hardware. Si usted utiliza SPI por hadware vas a tener una frecuencia de reloj de 4 MHz (eso significa actualizar una tira de 64 pixeles en por ahí de 500uS - o sea 0.0005 segundos). Si utilizas pines sin capacidad de SPI por hardware, nos baja la velocidad a 3 KHz, ¡mil veces mas lento!

Puedes manejar 300 LEDs DotStar con control de brillo (definiendo brightness=1.0 al crear el objeto) y 1000 LEDs sin control de brillo. Esto es porque al ajustar el brillo debemos recrear de forma dinámica la información con cada escritura.

¡Vas a necesitar la librería de adafruit_dotstar.mpy si no la tienes todavía en tu carpeta de /lib ! La puedes conseguir del Compilado de Librerías para CircuitPython. Si necesitas ayuda instalando la librería, puedes revisar la página de Librerías para CircuitPython.

Cableándolo

Primero vas a necesitar soldar tus DotStars. Verifica que tu conexión sea hacia la dirección de DATA INPUT o DI y CLOCK INPUT o CI. ¡Realizar la conexión hacia el lado de DATA OUT/DO o CLOCK OUT/CO es un error común! Los conectores están etiquetados y algunas versiones incluyen flechas para indicar la dirección que debe seguir el flujo de datos. Siempre realice una inspección visual, ¡ya que el orden de los conectores puede variar de tira a tira!

Para alimentar los pixeles desde la tarjeta, el regulador de salida  de 3.3V puede manejar picos de cerca de 500mA lo cual es como 50 pixeles de uso "promedio". Si deseas luces realmente brillantes o muchos pixeles, le recomendamos alimentar directamente de una fuente externa de alimentación.

  • En las Gemma M0 y las CircuitPlayground Express es con el pad de Vout - el pad tiene conexión directa de USB o de la batería, dependiendo de cual sea el voltaje mayor.
  • En las Trinket M0, Feather M0 Express, Feather M4 Express, ItsyBitsy M0 Express y ItsyBitsy M4 Express los pines de USB o BAT te van a dar alimentación directa del puerto USB o de la batería.
  • En las Metro M0 Express y las Metro M4 Express, utilice el pin de 5V sin importar si estás conectado por USB o por el conector de barril para DC.

Si la alimentación a los DotStars es mayor a 5.5V vas a tener dificultar con algunas tiras, en cuyo caso puede que sea necesario que bajes el voltaje a 4.5V-5V o utilizar un level shifter.

¡No utilice el pin VIN de forma directa en las Metro M0 Express o Metro M4 Express! ¡El voltaje puede alcanzar los 9V y esto va a destruir tus DotStars!
Tome nota que el orden de los cables en tu tira de DotStars o su forma no sean exactamente igual al diagrama. Revise la tira por marcas que ayuden a verificar cual pin corresponde para DIN, 5V y GND.

El Código

Este ejemplo incluye múltiples efectos visuales. Copie y pegue el código en code.py utilizando tu editor favorito, y salve el archivo.

# CircuitPython demo - Dotstar
import time
import adafruit_dotstar
import board

num_pixels = 30
pixels = adafruit_dotstar.DotStar(board.A1, board.A2, num_pixels, brightness=0.1, auto_write=False)


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 or pos > 255:
        return (0, 0, 0)
    if pos < 85:
        return (255 - pos * 3, pos * 3, 0)
    if pos < 170:
        pos -= 85
        return (0, 255 - pos * 3, pos * 3)
    pos -= 170
    return (pos * 3, 0, 255 - pos * 3)


def color_fill(color, wait):
    pixels.fill(color)
    pixels.show()
    time.sleep(wait)


def slice_alternating(wait):
    pixels[::2] = [RED] * (num_pixels // 2)
    pixels.show()
    time.sleep(wait)
    pixels[1::2] = [ORANGE] * (num_pixels // 2)
    pixels.show()
    time.sleep(wait)
    pixels[::2] = [YELLOW] * (num_pixels // 2)
    pixels.show()
    time.sleep(wait)
    pixels[1::2] = [GREEN] * (num_pixels // 2)
    pixels.show()
    time.sleep(wait)
    pixels[::2] = [TEAL] * (num_pixels // 2)
    pixels.show()
    time.sleep(wait)
    pixels[1::2] = [CYAN] * (num_pixels // 2)
    pixels.show()
    time.sleep(wait)
    pixels[::2] = [BLUE] * (num_pixels // 2)
    pixels.show()
    time.sleep(wait)
    pixels[1::2] = [PURPLE] * (num_pixels // 2)
    pixels.show()
    time.sleep(wait)
    pixels[::2] = [MAGENTA] * (num_pixels // 2)
    pixels.show()
    time.sleep(wait)
    pixels[1::2] = [WHITE] * (num_pixels // 2)
    pixels.show()
    time.sleep(wait)


def slice_rainbow(wait):
    pixels[::6] = [RED] * (num_pixels // 6)
    pixels.show()
    time.sleep(wait)
    pixels[1::6] = [ORANGE] * (num_pixels // 6)
    pixels.show()
    time.sleep(wait)
    pixels[2::6] = [YELLOW] * (num_pixels // 6)
    pixels.show()
    time.sleep(wait)
    pixels[3::6] = [GREEN] * (num_pixels // 6)
    pixels.show()
    time.sleep(wait)
    pixels[4::6] = [BLUE] * (num_pixels // 6)
    pixels.show()
    time.sleep(wait)
    pixels[5::6] = [PURPLE] * (num_pixels // 6)
    pixels.show()
    time.sleep(wait)


def rainbow_cycle(wait):
    for j in range(255):
        for i in range(num_pixels):
            rc_index = (i * 256 // num_pixels) + j
            pixels[i] = wheel(rc_index & 255)
        pixels.show()
        time.sleep(wait)


RED = (255, 0, 0)
YELLOW = (255, 150, 0)
ORANGE = (255, 40, 0)
GREEN = (0, 255, 0)
TEAL = (0, 255, 120)
CYAN = (0, 255, 255)
BLUE = (0, 0, 255)
PURPLE = (180, 0, 255)
MAGENTA = (255, 0, 20)
WHITE = (255, 255, 255)

while True:
    # Change this number to change how long it stays on each solid color.
    color_fill(RED, 0.5)
    color_fill(YELLOW, 0.5)
    color_fill(ORANGE, 0.5)
    color_fill(GREEN, 0.5)
    color_fill(TEAL, 0.5)
    color_fill(CYAN, 0.5)
    color_fill(BLUE, 0.5)
    color_fill(PURPLE, 0.5)
    color_fill(MAGENTA, 0.5)
    color_fill(WHITE, 0.5)

    # Increase or decrease this to speed up or slow down the animation.
    slice_alternating(0.1)

    color_fill(WHITE, 0.5)

    # Increase or decrease this to speed up or slow down the animation.
    slice_rainbow(0.1)

    time.sleep(0.5)

    # Increase this number to slow down the rainbow animation.
    rainbow_cycle(0)
Hemos escogido usar los pines A1 y A2, pero estos no son pines para SPI en todas las tarjetas. ¡Los DotStar responden más rápido cuando usan SPI por hardware!

Create the LED

Lo primero que tenemos que hacer es instanciar al objeto LED. El objeto para DotStars tiene dos parámetros que son requeridos y dos más que son opcionales. Vas a tener que indicarle cual es el pin que estás utilizando para enviar datos a tus DotStars y cual para el reloj, así como también decirle el número de pixeles que vas a utilizar en la tira. De forma opcional puedes definirle brightness y auto_write.

Los NeoPixeles se pueden manejar con cualquieras dos pines. Hemos escogido A1 para reloj y A2 para datos. Para configurar los pines, incluya el nombre de los pines en la creación del objeto, al inicio, en este caso board.A1 y board.A2.

Para definir la cantidad de pixeles en la tira, asigne a la variable num_pixelsel número de pixeles que desea utilizar, en nuestro ejemplo una tira de72.

Hemos escogido definir el brillo en un 10% con brightness=0.1.

Para omisión, auto_write=True, que quiere decir que cualquier cambio que realices a los pixeles, se envía de forma automática. Como True es el valor por omisión, si quieres que sea de esta forma, no debes agregarle nada a tu objeto LED. Hemos escogido el definir auto_write=False. Si usted define auto_write=False, debe incluir pixels.show() cada vez que deseas enviar datos a tus pixeles. Esto hace que el código sea más complicado, ¡pero puede hacer que las animaciones sean más rápidas!

Utilitarios para DotStar

Hemos incluído algunas funciones utilitarias para crear efectos visuales muy divertidos, que puedes encontrar en este código.

El primero es wheel() del cual acabamos de aprender en la LED RGB Integrado. Luego tenemos llenado de color (color_fill()) el cual solicita que se le pase un color y la cantidad de tiempo que desea que se despliegue. Luego tenemos parte alternado (slice_alternating()), parte en arcoiris (slice_rainbow()), y ciclo en arcoiris (rainbow_cycle()) las cuales solicitan la cantidad de tiempo que deben esperar entre cada paso de la animación.

Por último, hemos incluído una lista de variables para nuestros colores. Esto hace mucho más sencillo reutilizar colores en cualquier lado del código, así como agregar más colores para usar en múltiples lugares. El asignar colores RGB ha sido explicado en esta sección sobre el LED RGB Integrado en CircuitPython.

Dos de los utilitarios utilizan una bonita característica de la librería de DotStar que permite utilizar matemática para prender los LEDs en patrones repetidos. slice_alternating() primero prende los LEDs que son número par, y luego los LEDs que son número impar, y lo repite una y otra vez. slice_rainbow() prende cada sexto LED con uno de los seis colores del arcoiris hasta que se llena la tira. Ambos permite usar nuestros útiles nombres de color. Este código para partir solo funciona si la cantidad de LEDs se puede dividir por el tamaño de la partición, en nuestro caso 2 y 6. Los DotStars vienen en tiras de 30, 60, 72 y 144, lo cuales son todos divisibles tanto por 2 como por 6. Si necesitas cortar las tiras para tener una tira resultante de diferente tamaño, el código en este ejemplo te va a ayudar pero podría no funcionar sin modificación. Sin embargo, siempre y cuando le envíes un número de LEDs que sea divisible por el tamaño de partición, el código va a funcionar.

Ciclo Principal

Nuestro ciclo principal comienza llamando a color_fill() una vez por cada color en nuestra lista y se espera 0.5 segundos. Usted puede cambiar este número para cambiar que tan rápido se despliega cada color. Luego, llamamos a slice_alternating(0.1), que quiere decir que tiene una pausa de 0.1 segundos entre los cambios de la animación. Luego, llenamos la tira de blanco para tener un fondo limpio para que se despliegue el arcoirirs. Luego llamamos a slice_rainbow(0.1), con una pausa de 0.1 segundos en la animación. Luego llamaos a rainbow_cycle(0), que quiere decir que la va a ejecutar tan rápido como sea posible. ¡Aumente o baje este valor de cualquiera de estos números, para ver como sube o baja la velocidad de las animaciones!

Tome nota que si utiliza una tira con más LEDs, va a tomar más tiempo para que las animaciones completen.

Tenemos mucho más conocimiento de propósito general sobre DotStar en nuestra guía DotStar UberGuide https://learn.adafruit.com/adafruit-dotstar-leds

¿Es SPI?

Explicamos al principio de esta sección que los LEDs van a responder más rápido si está utilizando un SPI por hardware. En algunas de las tarjetas, hay pines de SPI por HW (hardware) directamente disponibles en forma de MOSI y SCK. Sin embargo, el hardware por SPI está disponible en muchos más puertos que estos. ¿Pero como saber cuales? ¡Fácil! Hemos escrito un utilitario sencillo.

Escogemos a los pines A1 y A2 para nuestro código de ejemplo. Para ver si estos pines con SPI por hardware en la tarjeta que estás utilizando, copia y pega el código dentro de code.py utilizando tu editor favorito, y salva el archivo. Luego conéctese a la consola serial para ver el resultado.

Para revisar si otras combinaciones de pines tienen SPI por hardware, cambia los nombres de los pines en la línea que dice: if is_hardware_SPI(board.A1, board.A2): por los pines que desea usar. Luego revise el resultado en la consola serial. ¡Muy simple!

import board
import busio


def is_hardware_spi(clock_pin, data_pin):
    try:
        p = busio.SPI(clock_pin, data_pin)
        p.deinit()
        return True
    except ValueError:
        return False


# Provide the two pins you intend to use.
if is_hardware_spi(board.A1, board.A2):
    print("This pin combination is hardware SPI!")
else:
    print("This pin combination isn't hardware SPI.")

Lea la Documentación

Para un vistazo a mayor profundidad de lo que dotstar puede hacer, revise DotStar en "Read the Docs".

This guide was first published on Jun 24, 2020. It was last updated on Jun 24, 2020.
This page (DotStar en CircuitPython ) was last updated on Jun 24, 2020.