Esenciales para CircuitPython

Ya has pasado por la guía de Bienvenido a CircuitPython. Ya tienes todo listo y CircuitPython corriendo. Excelente. ¿Y ahora que? ¿Los Escenciales para CircuitPython?

Hay una cantidad disponible de módulos núcleo integrados a CircuitPython y librerías comunes. Esta guía te va a introducir a ellos y te va a enseñar con ejemplos como usar cada una.

Cada sección te va a presentar con un pedazo de código diseñado para trabajar con diferentes tarjetas, y a explicar como usar el código con cada tarjeta. Estos ejemplos están diseñados para cualquier tarjeta hecha para correr CircuitPython, incluyendo las Circuit Playground Express, Trinket M0, Gemma M0ItsyBitsy M0 Express, ItsyBitsy M4 Express, Feather M0 Express, Feather M4 Express, Metro M4 Express,  Metro M0 Express, Trellis M4 Express, y Grand Central M4 Express.

Algunos ejemplos requieren componentes externos, como switches o sensores. Vas a encontrar diagramas de cableado donde sea necesario, para mostrarte como conectar los componentes necesarios para trabajar con cada ejemplo.

¡Comencemos a aprender los Esenciales para CircuitPython!

Integrados a CircuitPython

CircuitPython viene 'con de todo' - muchas de las cosas que conoces y amas del clásico Python 3 (algunas veces llamado CPython) ya funcionan.

Hay algunas que todavía no, pero ¡vamos a tratar de seguir actualizando esta lista mientras agregamos funcionalidad!

¡Esta no es una lista completa! Es simplemente algunas de las capacidades que puedes usar.

Cosas Integradas que Funcionan

Control de Flujo

Los usuales  if, elif, else, for, while trabajan como se espera.

Math

import math te va a dar un rango de funciones matemáticas.

>>> dir(math)
['__name__', 'e', 'pi', 'sqrt', 'pow', 'exp', 'log', 'cos', 'sin', 'tan', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'copysign', 'fabs', 'floor', 'fmod', 'frexp', 'ldexp', 'modf', 'isfinite', 'isinf', 'isnan', 'trunc', 'radians', 'degrees']

CircuitPython trabaja con valores de punto flotante de 30-bits, así que puedes usar int y float cuando los necesites.

Tuplas, Listas, Arreglos y Diccionarios

Puedes organizar datos en ()[], y {} incluyendo hileras, objetos, flotantes, etc.

Clases, Objetos y Funciones

Podemos usar objetos y funciones extensivamente en nuestras librerías, así que prueba uno de los muchos ejemplos como los ejemplos de clases en la libería MCP9808.

Lambdas

¡Sí! Puedes crear funciones con lambda en la forma que conoces:

>>> g = lambda x: x**2
>>> g(8)
64

Números al Azar

Para obetner números al azar:

import random

random.random() trae un número de punto flotante entre 0 y 1.0.

random.randint(min, max) te trae un número entero entre min y max.

Entradas y Salidas Digitales en CircuitPython

Lo primero al interactuar con hardware es poder manipular entradas y salidas digitales. Con CircuitPython, ¡es super sencillo!

Este ejemplo muestra como utilizar tanto la salida como la entrada digital. Puedes utilizar un switch de entrada con una resistencia en pullup (viene integrado en la tarjeta) para controlar una salida digital - el LED integrado.

Realiza una copiar y pegar del código en code.py utilizando tu editor preferido, y salva el archivo para ejecutar la demostración.

# CircuitPython IO demo #1 - General Purpose I/O
import time
import board
from digitalio import DigitalInOut, Direction, Pull

led = DigitalInOut(board.D13)
led.direction = Direction.OUTPUT

# For Gemma M0, Trinket M0, Metro M0 Express, ItsyBitsy M0 Express, Itsy M4 Express
switch = DigitalInOut(board.D2)
# switch = DigitalInOut(board.D5)  # For Feather M0 Express, Feather M4 Express
# switch = DigitalInOut(board.D7)  # For Circuit Playground Express
switch.direction = Direction.INPUT
switch.pull = Pull.UP

while True:
    # We could also do "led.value = not switch.value"!
    if switch.value:
        led.value = False
    else:
        led.value = True

    time.sleep(0.01)  # debounce delay

Note como hicimos el código un poco menos "Pithónico" de lo necesario. El bloque if/else se puede reemplazar con un simple led.value = not switch.value pero queremos dejar claro como se evalúan las entradas. El interprete va a leer la entrada digital cuando evalúa switch.value.

Para Gemma M0, Trinket M0, Metro M0 Express, Metro M4 Express, ItsyBitsy M0 Express, ItsyBitsy M4 Express, no se requieren cambios al ejemplo inicial.

Note: To "comment out" a line, put a # and a space before it. To "uncomment" a line, remove the # + space from the beginning of the line.

Para Feather M0 Express and Feather M4 Express, comente switch = DigitalInOut(board.D2) (y/o switch = DigitalInOut(board.D7) dependiendo de cambios que hayas realizado), y descomenta switch = DigitalInOut(board.D5).

Para Circuit Playground Express, necesitas comentar switch = DigitalInOut(board.D2) (y/o switch = DigitalInOut(board.D5) dependiendo de cambios que hayas realizado), y descomenta switch = DigitalInOut(board.D7).

Para encontrar el pin o pad sugerido en el código, vea la lista abajo. Para tarjetas que requieren cableado, conecte un switch (también conocido como un switch táctil, botón o botón momentáneo), siguiendo el diagrama para ayuda. Presione o mueva el switch, y la luz roja LED se va a prender y a apagar.

Note que en tarjetas M0/SAMD basadas en CircuitPython, al menos, tienes pulldowns internos con Pull.DOWN y si quieres apagar el pull up/pull down sólo asigna switch.pull = None.

¡Encuentra los pines!

La lista abajo muestra cada tarjeta, explica dónde se encuentran los pines Digitales sugeridos para entrada, y dónde se encuentra el LED D13.

Circuit Playground Express

Vamos a utilizar el switch, el cual es pin D7, y está situado entre el conector de batería y el switch de reset de la tarjeta. D13 está etiquetado como D13 y se encuentra a la par del puerto micro USB.

Para utilizar D7, comente la línea actual de uso de Pin,  y desconecte la línea etiquetada para la Circuit playground Express, ¡vea detalles arriba!

Trinket M0

D2 está conectado al cable azul, etiquetado como "2", y está situado entre "3V" y "1" en la tarjeta. D13 está etiquetado como "13" y está situado a la part del puerto micro USB.

Gemma M0

D2 es un pad amigable a clips de lagarto, etiquetado tanto "D2" como "A1", se muestra conectado con el cable azul, y está a la par del puerto micro USB. D13 se sitúa a la par de la etiqueta "GND" en la tarjeta, y arriba del switch "On/Off".

¡Utilice clips de lagarto para conectar tu switch a la Gemma M0!

 

Feather M0 Express y Feather M4 Express

D5 se etiqueta "5" y está conectado al cable azul en la tarjeta. D13 está etiquetado como "#13" y se sitúa a la par del puerto micro USB.

Para usar D5, comente la línea de uso de pin, y descomente la línea marcada para Feather M0 Express. ¡Vea los detalles arriba!

ItsyBitsy M0 Express y ItsyBitsy M4 Express

D2 se etiqueta "2", situado entre las etiquetas de "MISO" y "EN", y está conectado al cable azul en la tarjeta. D13 está situado a la par del botón de reset, entre las etiquetas "3" y "4" de la tarjeta.

Metro M0 Express y Metro M4 Express

D2 está situado cerca de la esquina superior izquierda, y conectado al cable azul. D13 está etiquetado "L" y está situado a la par del puerto micro USB.

Lea la Documentación

Para mayor profundidad sobre lo que puede hacer digitalio, lea  la página sobre DigitalInOut en Read the Docs.

Entradas Analógicas en CircuitPython

Este ejemplo muestra como puedes leer el voltaje analógico en el pin A1 de tu tarjeta.

Copia y pega el código hacia code.py utilizando tu editor favorito, y salvando para ejecutar el código de demostración.

# CircuitPython AnalogIn Demo
import time
import board
from analogio import AnalogIn

analog_in = AnalogIn(board.A1)


def get_voltage(pin):
    return (pin.value * 3.3) / 65536


while True:
    print((get_voltage(analog_in),))
    time.sleep(0.1)
¡Asegúrate de estar corriendo la última versión de CircuitPython! Si no, puede que recibas un error de "AttributeError: 'module' object has no attribute 'A1'". ¡Si recibes este error, primero actualiza a la última versión de CircuitPython!

Creando la entrada analógica

analog1in = AnalogIn(board.A1)

Crea un objeto, y conecta el objeto hacia A1 como una entrada analógica.

Utilitario get_voltage

getVoltage(pin) es nuestro pequeño programa utilitario. Por omisión, sus lecturas analógicas van a tener un rango de 0 (mínimo) a 65535 (máximo). Este utilitario convierte la lectura de 0-65535 de pin.value y lo convierte en una lectura de voltaje de 0-3.3V.

Bucle principal

El bucle principal es sencillo. Imprime (prints) el voltaje como valores de punto flotante, llamando get_voltage sobre nuestro objeto analógico. Conéctese a la consola serial para observar los resultados.

Realizando algunos cambios

Por omisión los pines están flotando así que los voltajes van a variar. Mientras estamos conectados a la consola serial, trata de tocar el cable de A1 hacia el pin GND o a el pin 3Vo para ver el voltaje cambiar.

También puedes agregar un potenciómetro para controlar como cambia el voltaje. Del potenciómetro a la tarjeta, conecta el pin izquierdo hacia tierra (GND), el pin del medio hacia A1, y el pin derecho hacia 3V. Si estás utilizando el editor de Mu, ¡puedes ver los cambios mientras rotas el potenciómetro, en el plotter como en la imagen que se observa arriba! (Has click en el ícono de Plotter en la parte superior de la ventana para abrir el plotter).

Cuando rotas la perilla del potenciómetro, la escobilla rota hacia izquierda y derecha, subiendo o bajando la resistencia. Eso, a su vez, cambia el nivel del voltaje analógico que lees en el pin A1 de tu tarjeta.

Cableándolo

La lista que sigue a continuación muestra los diagramas de cableado que te van a ayudar a encontrar los pines correctos y a conectar el potenciómetro, y ¡provee más información sobre los pines analógicos de tu tarjeta!

Circuit Playground Express

A1 está situado a la derecha de la tarjeta. Hay múltiples pads o pines de tierra (GND) y 3V.

Tu tarjeta tiene 7 pines analógicos que pueden ser utilizados para este propósito. Para una lista completa, puedes ver la página con el pinout en la guía principal.

Trinket M0

¡A1 está etiquetado como 2! Está situado entre "1~" y "3V" en el mismo lado de la tarjeta que el pequeño LED rojo. Tierra (GND) está situado al lado opuesto de la tarjeta. 3V está situado a la par del 2, del mismo lado de la tarjeta que el botón de reset.

Tienes 5 pines analógicos que puedes utilizar. Para ver la lista completa, puedes ver la página con el pinout en la guía principal.

Gemma M0

A1 está situado cerca de la parte superior de la tarjeta, del lado izquierdo del puerto Micro USB. Tierra (GND) está del lado opuesto del puerto USB de A1. 3V está situado del lado izquierdo del conector de batería en la parte inferior de la tarjeta.

Tu tarjeta tiene 3 pines analógicos. Para ver la lista completa, puedes ver la página con el pinout en la guía principal.

Feather M0 Express y Feather M4 Express

A1 está situado en el borde opuesto al conector de batería. Hay múltiples pines de tierra (GND). 3V está situado en el mismo borde que A1, a la par del botón de reset.

Tu tarjeta tiene 6 pines analógicos que puedes usar. Para ver la lista completa, puedes ver la página con el pinout en la guía principal.

ItsyBitsy M0 Express y ItsyBitsy M4 Express

A1 está situado en la mitad de la tarjeta, cerca de la "A" de "Adafruit". La tierra está etiquetado como "G" a la par de "BAT", cerca del puerto Micro USB. 3V está situado en el lado opuesto del puerto USB de la tierra, a la par de "RST".

Tienes 6 pines analógicos para utilizar. Para ver la lista completa, puedes ver la página con el pinout en la guía principal.

Metro M0 Express y Metro M4 Express

A1 está situado del mismo lado de la tarjeta que conector de barril. Hay múltiples pines de tierra disponibles. 3V está etiquetado como "3.3" y está situado al centro de la tarjeta, del mismo lado que el conector de barril y de A1.

Tu tarjeta Metro M0 Express tiene 6 pines analógicos que puedes utilizar. Para ver la lista completa, puedes ver la página con el pinout en la guía principal.

Tu tarjeta Metro M4 Express tiene 6 pines analógicos que puedes utilizar. Para ver la lista completa, puedes ver la página con el pinout en la guía principal.

Leyendo Valores de Pines Analógicos

El utilitario get_voltage() utilizado en el ejemplo anterior del potenciómetro, lee el valor en crudo y lo convierte a un nivel de voltaje. También puedes leer un pin analógico de forma directa en tu código utilizando pin.value. Por ejemplo, para simplemente leer el valor analógico del pin, puedes ejecutar el siguiente código:

Download: file
import time
import board
from analogio import AnalogIn

analog_in = AnalogIn(board.A1)

while True:
    print(analog_in.value)
    time.sleep(0.1)

Esto funciona para cualquier pin o entrada analógica. Utiliza el .value para leer el valor en crudo y utilizarlo en tu código.

Salidas Analógicas en CircuitPython

Este ejemplo muestra como puedes configuarar el DAC (salida analógica verdadera) en el pin A0.

A0 is el único pin de salida analógica en las tarjeta M0. ¡Ningún otro pin realiza verdadera salida analógica!

Copia y pega el código hacia code.py utilizando tu editor favorito, y salva el archivo.

# CircuitPython IO demo - analog output
import board
from analogio import AnalogOut

analog_out = AnalogOut(board.A0)

while True:
    # Count up from 0 to 65535, with 64 increment
    # which ends up corresponding to the DAC's 10-bit range
    for i in range(0, 65535, 64):
        analog_out.value = i

Creando una salida analógica

analog_out = AnalogOut(A0)

Esta línea crea un objeto analog_out y conecta el objeto con A0, el único pin con DAC disponible tanto en tarjeta M0 como M4. (Las M4 tienen dos, A0 y A1)

Configurando la salida analógica

El DAC en la SAMD21 es una salida de 10-bits, de 0 a 3.3V. Así que en teoría tenemos una resolución de 0.0032 voltios por bit. Para permitirle a CircuitPython que sea lo suficientemente de propósito general para que pueda ser utilizado con DAC de 8 hasta 16 bits, se lee un valor de 16-bits y luego se divide de forma interna.

Por ejemplo, escribiendo 0 es lo mismo que configurando para una salida de 0 voltios.

Escribirle 5000 es lo mismo que configurar una salida para 5000 / 64 = 78, y 78 / 1024 * 3.3V es 0.25V de salida.

Escribir 65535 es lo mismo que 1023 por lo que es la parte superior del rango y vas a recibir una salida de 3.3V.

Bucle Principal

El bucle principal es relativamente sencillo, pasa por el rango completo del DAC, desde 0 a 65535, pero con incrementos de 64 a la vez, así que termina subiendo un bit por cada uno de los 10 bits disponibles en el rango.

CircuitPython no es terriblemente rápido, así que el ciclo más rápido que puedes obtener va a ser de 4 Hz. El DAC no es bueno para usar como salida de audio a como viene.

Tarjetas Express como la CircuitPlayground Express, la Metro M0 Express, la ItsyBitsy M0 Express, la ItsyBitsy M4 Express, la Metro M4 Express, la Feather M4 Express, o la Feather M0 Express tienen más espacio para código y pueden realizar operaciones de salida de audio vía el DAC. ¡La Gemma M0, la Trinket M0 no lo pueden hacer!

¡Revisa la sección de Salida de Audio de esta guía para ejemplos!

Encuentra el pin

¡Utilice los diagramas a continuación para encontrar el pin A0, marcado con una flecha magenta!

Circuit Playground Express

A0 está situado entre VOUT y A1 cerca del puerto de batería

 

Trinket M0

¡A0 está etiquetado como "1~" en la Trinket! A0 está situado entre "0" y "2" cerca del medio de la tarjeta en el mismo lado del LED rojo.

Gemma M0

A0 está situado en el medio del lado derecho de la tarjeta, a la par del switch On/Off.

 

Feather M0 Express

A0 está situado entre GND y A1 del lado opuesto de la tarjeta al conector de batería, cerca del botón de Reset.

 

Feather M4 Express

A0 está situado entre GND y A1 en el lado opuesto al conector de batería, cerca del botón de Reset, y agujero del pin está marcado con paréntesis izquierdos y derechos.

ItsyBitsy M0 Express

A0 está situado entre VHI y A1, cerca de la "A" en "Adafruit", y el agujero del pin está marcado con paréntesis izquierdos y derechos.

ItsyBitsy M4 Express

A0 está situado entre VHI y A1, y el agujero del pin está marcado con paréntesis izquierdos y derechos.

Metro M0 Express

A0 está situado entre VHI y A1, del mismo lado en la tarjeta que el conector de barril, como en la mitad de los headers, y el agujero del pin está marcado con paréntesis izquierdos y derechos.

Metro M4 Express

A0 está situado entre VHI y A1, del mismo lado en la tarjeta que el conector de barril, como en la mitad de los headers.

En la Metro M4 Express, hay DOS salida analógicas verdaderas, A0 y A1.

Salida de Audio con CircuitPython

CircuitPython 3.0 y posteriores, vienen con una versión actualizada de audioio, la cual provee capacidades de salida de audio. Puedes tocar tonos generados. También puedes tocar, pausar y quitar la pausa de archivos tipo wave. Puedes tener 3V de pico-a-pico de salida analógica o una salida digital I2S. En esta página te vamos a mostrar como usar salida analógica.

Esto es excelente para todo tipo de proyectos que requieren sonido, ¡como un piano de tonos o cualquier cosa a la que desees agregar efectos de sonido!

¡Las ESP8266, las Trinket M0 y las Gemma M0 no tienen capacidades de audioio! Debes usar una tarjeta M0 Express o M4 Express para esto.

El primer ejemplo que vamos a mostrarte es como generar un tono y que suene al usar un botón. El segundo ejemplo te va a mostrar como tocar, poner en pausa y quitar la pausa de un archivo tipo wave, utilizando un botón para quitar la pausa. Ambos van a tocar el sonido por medio de un conector de audio. El volumen por omisión de ambos ejemplo va a ser dolorosamente alto para tocar con audífonos. Así que hemos agregado un potenciómetro  e incluido código en el ejemplo de generación de tono, para controlar el volumen.

En nuestro código, vamos a utilizar el pin A0 para la salida de audio, dado que es el único pin con DAC disponible en todas las tarjetas Express. Las tarjetas M0 Express tienen la salida de audio en A0. Las tarjetas M4 Express tienen dos pines para salida de audio, A0 y A1, sin embargo solo vamos a utilizar A0 en esta guía.

Tocar un Tono

Copie y pegue el siguiente código dentro de code.py utilizando tu editor favorito, y salva el archivo.

import time
import array
import math
import board
import digitalio

try:
    from audiocore import RawSample
except ImportError:
    from audioio import RawSample

try:
    from audioio import AudioOut
except ImportError:
    try:
        from audiopwmio import PWMAudioOut as AudioOut
    except ImportError:
        pass  # not always supported by every board!

button = digitalio.DigitalInOut(board.A1)
button.switch_to_input(pull=digitalio.Pull.UP)

tone_volume = 0.1  # Increase this to increase the volume of the tone.
frequency = 440  # Set this to the Hz of the tone you want to generate.
length = 8000 // frequency
sine_wave = array.array("H", [0] * length)
for i in range(length):
    sine_wave[i] = int((1 + math.sin(math.pi * 2 * i / length)) * tone_volume * (2 ** 15 - 1))

audio = AudioOut(board.A0)
sine_wave_sample = RawSample(sine_wave)

while True:
    if not button.value:
        audio.play(sine_wave_sample, loop=True)
        time.sleep(1)
        audio.stop()

Primero, creamos un objeto botón y lo asignamos al pin A1, y lo configuramos como entrada y con un pull-up. Aunque el switch de botón involucra digitalio,estamos utilizando un pin-A por lo que el código va a funcionar para todas las tarjetas.

Ya que el volumen por omisión es muy alto, hemos incluido una variable llamada tone_volume en el código de onda sinusoide. Usted puede utilizar el código para controlar el volumen aumentando o reduciendo este número para aumentar o reducir el volumen. También puede controlar el volumen, rotando la perilla del potenciómetro.

Para configurar la frecuencia del tono generado, cambie el número asignado en la variable frequency para definir la frecuencia en Hz del tono que deseas generar.

Luego, generamos un período de la onda sinusoide con la función math.sin, y se lo asignamos a sine_wave.

Luego, creamos el objeto de audio, y lo asignamos al pin A0.

Creamos un sample de la onda sinusoide utilizando RawSample y dándole el sine_wave que creamos.

Dentro de nuestro bucle, revisamos si el botón ha sido presionado. El botón tiene dos estados de  True y False(verdadero y falso). Encontramos el valor del botón en button.value el cual por omisión retorna el estado True cuando no está presionado. Así que para revisar si ha sido presionado, revisamos si está presente el estado de False. Entonces, el chequeo que hacemos para ver  if not button.value es un equivalente de not True, o False.

Una vez que el botón es presionado, hacemos play (o "tocar") con el sample que hemos creado y hacemos un bucle. El comando time.sleep(1) le dice que se cicle por un segundo para tocar el sonido. Cuando el segundo se ha cumplido, nos detenemos con stop. Puedes aumentar o reducir la duración del tiempo que se toca el sonido, aumentando o bajando la cantidad de segundos que se le piden que haga pausa a time.sleep(). Trata de cambiarlo de 1 a 0.5. Ahora trata de cambiarlo a 2. ¡Lo puedes cambiar a tu conveniencia!

¡Eso es todo!

Tocar un Archivo Wave

Puede utilizar cualquier archivo tipo wave que esté soportado. CircuitPython trabaja con formato WAV mono o estéreo, a una taza de sample de 22 KHz (o menor) y 16-bits. Las tarjetas M0 SOLO trabajan en MONO. ¡La razón sobre mono es que solo hay una salida analógica en estas tarjetas! Las tarjetas M4 soportan estéreo porque tienen dos salidas. Lo de 22 KHz o menor es porque CircuitPython no puede manejar más datos que eso (y además no va a sonar mucho mejor) y la salida del DAC es de 10-bits por lo cual cualquier cosa por arriba de 16-bits simplemente va a tomar mayor espacio sin mejor calidad.

Dado que el archivo WAV debe caber en el sistema de archivos de CircuitPython, debe ser menor a 2MB.

CircuitPython no trabaja con OGG o MP3. ¡Solo WAV!

Hemos creado una guía detallada de como generar archivos WAV aquí.

Hemos incluido la que usamos aquí. La puedes descargar y copiar a tu tarjeta.

Vamos a tocar el archivo wave por 6 segundos, ponerlo en pausa, esperar a que un botón sea presionado, y luego quitar la pausa al archivo y dejarlo que toque hasta el final. ¡Luego comienza de nuevo desde el principio! Vamos a mirar.

Copia y pega el siguiente código en code.py utilizando tu editor favorito, y salva el archivo.

import time
import board
import digitalio

try:
    from audiocore import WaveFile
except ImportError:
    from audioio import WaveFile

try:
    from audioio import AudioOut
except ImportError:
    try:
        from audiopwmio import PWMAudioOut as AudioOut
    except ImportError:
        pass  # not always supported by every board!

button = digitalio.DigitalInOut(board.A1)
button.switch_to_input(pull=digitalio.Pull.UP)

wave_file = open("StreetChicken.wav", "rb")
wave = WaveFile(wave_file)
audio = AudioOut(board.A0)

while True:
    audio.play(wave)

    # This allows you to do other things while the audio plays!
    t = time.monotonic()
    while time.monotonic() - t < 6:
        pass

    audio.pause()
    print("Waiting for button press to continue!")
    while button.value:
        pass
    audio.resume()
    while audio.playing:
        pass
    print("Done!")

Primero creamos el objeto botón, y lo asignamos al pin A1,y lo configuramos para entrada con un pull-up.

Luego abrimos el archivo, StreetChicken.wav como un binario para lectura (readable binary) y guardamos el objeto archivo en wave_file lo cual es lo que usamos para leer el audio de: wave_file = open("StreetChicken.wav", "rb").

Ahora, le pedimos al sistema de audio que cargue los datos del wave del archivo wave = audioio.WaveFile(wave_file) y finalmente solicitamos que el audio sea tocar por medio del pin de salida analógica A0 audio = audioio.AudioOut(board.A0).

¡El archivo de audio ya está listo, y se puede tocar en cualquier momento con audio.play(wave)!

Dentro del ciclo, comenzamos por tocar el archivo.

Luego tenemos el bloque que le dice al código que se espere 6 segundo antes de poner el archivo en pausa. Decidimos utilizar time.monotonic() dado que es non-blocking que significa que puedes realizar otras cosas mientras el archivo está siendo tocado, ¡como controlar servos o NeoPixeles! En un momento dado, time.monotonic() va a ser igual a la cantidad de segundos desde que prendiste tu tarjeta. (El reiniciado-suave que ocurre con el auto cargado cuando salvas archivos en CircuitPython, or al entrar y salir del REPL, no comienza desde cero). Cuando es llamado, retorna un número con un decimal. Cuando le asignas time.monotonic() a la variable, la variable es igual al número de segundos a la cantidad de segundos que tuvo time.monotonic() al momento de asignar la variable. Lo puedes llamar una y otra vez y restarle la variable a time.monotonic() para saber cuanto tiempo ha transcurrido. Para más detalles, puedes ver este ejemplo.

Así que asignamos t = time.monotonic() para tener un punto de inicio. Luego decimospass, o "no haga nada", hasta que la diferencia entre  t y time.monotonic() sea mayor a 6 segundos. Dicho de otra forma, continuamos tocando hasta que hayan pasado 6 segundos. Recueda, puedes agregar otro código aquí para hacer otras cosas mientras cosas audio por 6 segundos.

Luego ponemos el audio en pausa (pause) e imprimimos (print) a la consola serial, "Waiting for button press to continue!" (o "¡Esperando a que un botón sea presionado para continuar!")

Ahora, vamos a esperar a que un botón presione de la misma forma que lo hicimos cuando tocamos un tono generado. Estamos diciendo while button.value, o mientras el botón retorne True, pass. Una vez que el botón es presionado, el retorna False, y esto le dice al código que continúe.

Una vez que el botón es presionado, quitamos la pausa (resume) y seguimos tocando el archivo. Le decimos que termine de tocar el archivo con while audio.playing: pass.

Finalmente, imprimimos (print) a la consola serial, "Done!" (o "¡Listo!)

Puedes realizar esto con cualquier archivo wave soportado, y puedes agregarle todo tipo de cosas al código de tu proyecto, mientras el archivo está tocando. ¡Pruébalo!

Cableándolo

Además de tu placa microncontroladora, vamos a requerir:

Breadboard-Friendly 3.5mm Stereo Headphone Jack

PRODUCT ID: 1699
Pipe audio in or out of your project with this very handy breadboard-friendly audio jack. It's a stereo jack with disconnect-switches on Left and Right channels as well as a center...
$0.95
IN STOCK

Tactile Switch Buttons (12mm square, 6mm tall) x 10 pack

PRODUCT ID: 1119
Medium-sized clicky momentary switches are standard input "buttons" on electronic projects. These work best in a PCB but
$2.50
IN STOCK

Panel Mount 10K potentiometer (Breadboard Friendly)

PRODUCT ID: 562
This potentiometer is a two-in-one, good in a breadboard or with a panel. It's a fairly standard linear taper 10K ohm potentiometer, with a grippy shaft. It's smooth and easy...
$0.95
IN STOCK

100uF 16V Electrolytic Capacitors - Pack of 10

PRODUCT ID: 2193
We like capacitors so much we made a kids show about them. ...
OUT OF STOCK

Full sized breadboard

PRODUCT ID: 239
This is a 'full-size' breadboard, 830 tie points. Good for small and medium projects. It's 2.2" x 7" (5.5 cm x 17 cm) with a standard double-strip in the middle...
$5.95
IN STOCK

Premium Male/Male Jumper Wires - 20 x 6" (150mm)

PRODUCT ID: 1957
These Male/Male Jumper Wires are handy for making wire harnesses or jumpering between headers on PCB's. These premium jumper wires are 6" (150mm) long and come in a 'strip' of 20...
OUT OF STOCK

Y para que sea más sencillo el cablearlo con la CircuitPlayground Express:

Small Alligator Clip to Male Jumper Wire Bundle - 6 Pieces

PRODUCT ID: 3448
When working with unusual non-header-friendly surfaces, these handy cables will be your best friends! No longer will you have long, cumbersome strands of alligator clips. These...
$3.95
IN STOCK

Cuando los interruptores de botón tienen cuatro pines, realmente son solo dos pines. Cuando se cablea un interruptor de botón con cuatro pines, lo más sencillo es verificar que estás cableando los pines correctos, es conectando esquinas opuestas del interruptor de botón. Así no hay chance de que accidentalmente conectes el cable al mismo pin dos veces.

Estos son los pasos que hay que seguir para cablear estos componentes:

  • Conecte el pin de tierra de su tarjeta a el riel de tierra en la breadboard porque vamos a conectar los tres componentes a tierra.
  • Conect un pin del interruptor de botón al pin A1 de tu tarjeta, y el pin opuesto del interruptor de botón al riel de tierra de la breadboard.
  • Conecte los pines izquiero y derecho de la entrada de audio entre ellos.
  • Conecte el pin central de la entrada de audio al riel de tierra de la breadboard.
  • Conecte el pin izquierdo al lado negativo del capacitor de 100mF.
  • Conecte el lado positivo del capacitor al pin central del potenciómetro.
  • Conecte el lado derecho del potenciómetro al pin A0 de tu tarjeta.
  • Conecte el pin izquierdo del potenciómetro al riel de tierra de la breadboard.

La siguiente lista muestra diagramas de cableado para ayudar a encontrar los pines correctos y el cableado con diferentes componentes. Los cables para tierra son negros. El cable para el interruptor de botón es amarillo. Los cables involucrados con audio de color azul.

El cableado es el mismo para las tarjetas versión M4 que para las versión M0. Siga la imagen para ambas.

 

¡Utilice un breadboard para que el cableado quede limpio y ordenado!

La Circuit Playground Express está cableada eléctricamente igual que el ejemplo arriba para una tarjeta tipo ItsyBitsy/Feather/Metro, pero utilizamos cables con clip de lagarto como cables de conexión en lugar de cables tipo jumper.

PWM con CircuitPython

Tu tarjeta tiene soporte de pulseio, lo que significa que puedes controlar la intensidad de un LED por medio de PWM, puedes controlar servo motores, hacer sonar bocinas sencillas, y controlar dispositivos de tipo "pulse train" como DHT22 e infrarojos.

¡Casi todos los pines tienen capacidades de PWM! Por ejemplo, todas las tarjetas con ATSAMD21 tiene un pin A0 el cual es una salida analógica 'verdadera' y no tiene capacidades de PWM.

PWM con Frecuencia Fija

Este ejemplo va a demostrar como utilizar PWM para cambiar la intensidad del LED rojo de tu tarjeta.

Copia y pega el código dentro de code.py utilizando tu editor favorito, y salva el archivo.

import time
import board
import pulseio

led = pulseio.PWMOut(board.D13, frequency=5000, duty_cycle=0)

while True:
    for i in range(100):
        # PWM LED up and down
        if i < 50:
            led.duty_cycle = int(i * 2 * 65535 / 100)  # Up
        else:
            led.duty_cycle = 65535 - int((i - 50) * 2 * 65535 / 100)  # Down
        time.sleep(0.01)

Creando una Salida PWM

led = pulseio.PWMOut(board.D13, frequency=5000, duty_cycle=0)

Como estamos usando el LED que trae la tarjeta, llamamos al objeto led, usamos pulseio.PWMOut para crear la salida y pasarle el pin D13 para que use el LED.

Ciclo Principal

El ciclo principal utiliza range() para recorrer el ciclio. Cuando el rango está en menos de 50, le aumenta el brillo al LED vía PWM, y cuando el rango está por arriba de 50, le baja el brillo por medio de PWM. ¡Así es como transiciona el LED entre brillante y oscuro!

El time.sleep() es necesario para permitirle al proceso de PWM que ocurra en cierta cantidad de tiempo. ¡De otra forma sucedería muy rápido para poderlo observar!

Salida de PWM con Frecuencia Variable

La salida con frecuencias fijas está bien para pulsar LEDs o controlar servos. Pero si quieres realizar sonidos con un parlante tipo piezo, debes variar la frecuencia.

El siguiente ejemplo utiliza pulseio para realizar una serie de tonos sobre un parlante tipo piezo.

Para utilizar con cualquier de las tarjetas con M0, no se necesita realizar cambios al código.

Para utilizar con las Metro M4 Express, ItsyBitsy M4 Express o la Feather M4 Express, debes comentar  piezo = pulseio.PWMOut(board.A2, duty_cycle=0, frequency=440, variable_frequency=True) y descomentar piezo = pulseio.PWMOut(board.A1, duty_cycle=0, frequency=440, variable_frequency=True) . ¡A2 no es un pin con capacidades de PWM en las tarjetas con chips M4!

Recuerda: Para "comentar" una línea, le pones # y un espacio al inicio. Para "descomentar" una línea, le remueves el # y el espacio al inicio de la línea.
import time
import board
import pulseio

# For the M0 boards:
piezo = pulseio.PWMOut(board.A2, duty_cycle=0, frequency=440, variable_frequency=True)

# For the M4 boards:
# piezo = pulseio.PWMOut(board.A1, duty_cycle=0, frequency=440, variable_frequency=True)

while True:
    for f in (262, 294, 330, 349, 392, 440, 494, 523):
        piezo.frequency = f
        piezo.duty_cycle = 65535 // 2  # On 50%
        time.sleep(0.25)  # On for 1/4 second
        piezo.duty_cycle = 0  # Off
        time.sleep(0.05)  # Pause between notes
    time.sleep(0.5)

Si tienes la librería de simpleio cargada en tu tarjeta, tenemos un bonito utilitario para realizar un tono en el parlante de tipo piezo con un solo comando.

Para utilizar tarjetas M0, no es necesario realizar cambios al código.

Para utilizar las Metro M4 Express, ItsyBitsy M4 Express o la Feather M4 Express, debes comentar simpleio.tone(board.A2, f, 0.25) y descomentar simpleio.tone(board.A1, f, 0.25) . ¡A2 no es un pin con capadades PWM en las tarjetas con chipsM4!

import time
import board
import simpleio

while True:
    for f in (262, 294, 330, 349, 392, 440, 494, 523):
        # For the M0 boards:
        simpleio.tone(board.A2, f, 0.25)  # on for 1/4 second
        # For the M4 boards:
        # simpleio.tone(board.A1, f, 0.25)  # on for 1/4 second
        time.sleep(0.05)  # pause between notes
    time.sleep(0.5)

Como puedes observar, ¡es mucho más sencillo!

Cableándolo

Utilice los diagramas a continuación como base para cablear tu parlante de tipo piezo. Conecte una pata del piezo al pin A2 de las tarjetas M0 o A1 para las tarjetas con M4, y la otra pata a tierra. No importa cual pata se conecte al pin. ¡Son intercambiables!

Circuit Playground Express

Utilice clips de lagarto para conectar A2 y uno de las tierras (GND) a diferentes patas del parlante tipo piezo.

CPX tiene PWM en los siguientes pines: A1, A2, A3, A6, RX, LIGHT, A8, TEMPERATURE, A9, BUTTON_B, D5, SLIDE_SWITCH, D7, D13, REMOTEIN, IR_RX, REMOTEOUT, IR_TX, IR_PROXIMITY, MICROPHONE_CLOCK, MICROPHONE_DATA, ACCELEROMETER_INTERRUPT, ACCELEROMETER_SDA, ACCELEROMETER_SCL, SPEAKER_ENABLE.

NO hay NO PWM en: A0, SPEAKER, A4, SCL, A5, SDA, A7, TX, BUTTON_A, D4, NEOPIXEL, D8, SCK, MOSI, MISO, FLASH_CS.

Trinket M0

Nota: ¡A2 en la Trinket está etiquetado como Digital "0"!

Utilice cables para conectar GND y D0 a diferentes patas del parlante tipo piezo.

Las Trinket tienen PWM disponible en los siguientes pines: D0, A2, SDA, D2, A1, SCL, MISO, D4, A4, TX, MOSI, D3, A3, RX, SCK, D13, APA102_MOSI, APA102_SCK.

NO hay PWM en: A0, D1.

Gemma M0

Utilice cables para conectar GND y A2 a diferentes patas del parlante tipo piezo.

Las Gemma tienen PWM disponible en los siguientes pines: A1, D2, RX, SCL, A2, D0, TX, SDA, L, D13, APA102_MOSI, APA102_SCK.

NO hay PWM en: A0, D1.

Feather M0 Express

Utilice cables para conectar GND y A2 a diferentes patas del parlante tipo piezo.

Las Feather M0 Express tienen PWM disponible en los siguientes pines: A2, A3, A4, SCK, MOSI, MISO, D0, RX, D1, TX, SDA, SCL, D5, D6, D9, D10, D11, D12, D13, NEOPIXEL.

NO hay PWM en: A0, A1, A5.

Feather M4 Express

Utilice cables para conectar GND y A1 a diferentes patas del parlante tipo piezo.

Para utilizar A1, descomente la línea que configura el pin, y descomente la línea que etiquetada para las tarjetas M4. ¡Vea los detalles arriba!

Las Feather M4 Express tienen PWM disponible en los siguientes pines: A1, A3, SCK, D0, RX, D1, TX, SDA, SCL, D4, D5, D6, D9, D10, D11, D12, D13.

NO hay PWM en: A0, A2, A4, A5, MOSI, MISO.

ItsyBitsy M0 Express

Utilice cables para conectar G y A2 a diferentes patas del parlante tipo piezo.

Las ItsyBitsy M0 Express tienen PWM disponible en los siguientes pines: D0, RX, D1, TX, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, L, A2, A3, A4, MOSI, MISO, SCK, SCL, SDA, APA102_MOSI, APA102_SCK.

NO hay PWM en: A0, A1, A5.

ItsyBitsy M4 Express

Utilice cables para conectar G y A1 a diferentes patas del parlante tipo piezo.

Para utilizar A1, descomente la línea que configura el pin, y descomente la línea que etiquetada para las tarjetas M4. ¡Vea los detalles arriba!

Las ItsyBitsy M4 Express tienen PWM disponible en los siguientes pines: A1, D0, RX, D1, TX, D2, D4, D5, D7, D9, D10, D11, D12, D13, SDA, SCL.

NO hay PWM en: A2, A3, A4, A5, D3, SCK, MOSI, MISO.

Metro M0 Express

Utilice cables para conectar GND y A2 a diferentes patas del parlante tipo piezo.

Las Metro M0 Express tienen PWM disponible en los siguientes pines: A2, A3, A4, D0, RX, D1, TX, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, SDA, SCL, NEOPIXEL, SCK, MOSI, MISO.

NO hay PWM en: A0, A1, A5, FLASH_CS.

Metro M4 Express

Utilice cables para conectar GND y A1 a diferentes patas del parlante tipo piezo.

Para utilizar A1, descomente la línea que configura el pin, y descomente la línea que etiquetada para las tarjetas M4. ¡Vea los detalles arriba!

Las Metro M4 Express tienen PWM en: A1, A5, D0, RX, D1, TX, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, SDA, SCK, MOSI, MISO

NO hay PWM en: A0, A2, A3, A4, SCL, AREF, NEOPIXEL, LED_RX, LED_TX.

¿Donde si tengo PWM?

¿Quiere revisar cuales pines tienen PWM por ud mismo? ¡Hemos escrito este útil script! Intenta configurar PWM en cualquier pin disponible, y te hace saber en cuales funciona y en cuales no. ¡Pruébalo!

import board
import pulseio

for pin_name in dir(board):
    pin = getattr(board, pin_name)
    try:
        p = pulseio.PWMOut(pin)
        p.deinit()
        print("PWM on:", pin_name)  # Prints the valid, PWM-capable pins!
    except ValueError:  # This is the error returned when the pin is invalid.
        print("No PWM on:", pin_name)  # Prints the invalid pins.
    except RuntimeError:  # Timer conflict error.
        print("Timers in use:", pin_name)  # Prints the timer conflict pins.
    except TypeError:  # Error returned when checking a non-pin object in dir(board).
        pass  # Passes over non-pin objects in dir(board).

Motores Servo con CircuitPython

Para poder utilizar motores tipo servo, vamos a utilizar pulseio. En teoría uno puede realizar llamadas directas a pulseio para definir una frecuencia de 50 Hz y con eso definir el ancho de los pulsos. ¡Pero preferimos hacerlo un poco más elegante y sencillo!

Así que en cambio, ¡vamos a utilizar adafruit_motor la cual te maneja los motores tipo servo de buena manera! adafruit_motor es una librería, ¡así que asegúrate de obtenerla del compilado de liberías si no lo has hecho! Si necesitas ayuda con la instalación puedes revisar la página de Librerías de CircuitPython.

Los servos vienen en dos tipos: 

  • Un servo estándar para hobbies - el puntero se mueve 180 grados (90 grados en cada dirección desde cero grados).
  • Un servo de rotación continua - el puntero se mueve una rotación completa como un motor DC. En lugar de indicarse un ángulo, se define una velocidad de movimiento donde 1.0 es toda velocidad hacia adelante, 0.5 la mitad de la velocidad hacia adelante, 0 detenido, -1 es toda velovidad en reversa con sus valores intermedios.

Cableando los Servos

¡Los servos solo funcionan en pines con capacidad de PWM! Revisar los detalles de tu tarjeta para verificar cuales pines tienen salida de PWM.

Las conecciones para un servo son igual para cualquiera de los dos tipos.

Conecte el cable de tierra café o negro hacia la tierra de la tarjeta CircuitPython.

Conecte el cable rojo del servo hacia alimentación de 5V, donde un alimentado por USB es suficiente para uno o dos servos. Para más de eso, necesitas baterías externas. ¡No utilice 3.3V para alimentar un servo!

Conecte el cable amarillo o blanco del servo hacia el pin de control/datos, en este caso A1 o A2, pero puedes usar cualquier pin con capacidades de PWM.

Por ejemplo, para cablear un servo a una Trinket, conecte el cable de tira a GND y el de poder a USB, y el de señal a 0.

Recuerde, en las Trinket, A2 está etiquetado como "0".

Para las Gemma, utilice cables de lagarto para conectar el cable de tierra a GND, el de alimentación a VOUT, y el de señal a A2.

Para las Circuit Playground Express y Circuit Playground Bluefruit, utilice cables de lagarto para conectar el cable de tierra a GND, el de alimentación a VOUT y el de señal hacia A2.

Para tarjetas como las Feather M0 Express, ItsyBitsy M0 Express y Metro M0 Express, conecte el cable de tierra a GND, el de alimentación hacia USB o 5V, y el de señal hacia A2.

Para las  Metro M4 Express, ItsyBitsy M4 Express y las Feather M4 Express, conecte el cable de tierra hacia cualquier  G o GND, el de alimentación hacia USB or 5V, y el cable de señal hacia A1.

Código para Servos Estándar

Con este ejemplo el servo va a mover el puntero conectado al pin A2 desde 0 grados hasta 180 grados (-90 a 90 grados) y de regreso:

import time
import board
import pulseio
from adafruit_motor import servo

# create a PWMOut object on Pin A2.
pwm = pulseio.PWMOut(board.A2, duty_cycle=2 ** 15, frequency=50)

# Create a servo object, my_servo.
my_servo = servo.Servo(pwm)

while True:
    for angle in range(0, 180, 5):  # 0 - 180 degrees, 5 degrees at a time.
        my_servo.angle = angle
        time.sleep(0.05)
    for angle in range(180, 0, -5): # 180 - 0 degrees, 5 degrees at a time.
        my_servo.angle = angle
        time.sleep(0.05)

Servo de Rotación Continua

Hay dos diferencias entre los servos de Rotación Continua y los servos Estándar:

  1. El objeto servo se crea de forma my_servo = servo.ContinuousServo(pwm) en lugar de my_servo = servo.Servo(pwm)
  2. En lugar de usar myservo.angle, se usa my_servo.throttle con un valor de velocidad de 1.0 (toda velocidad) a 0.0 (detenido) y hasta  -1.0 (toda velocidad en reversa). Cualquier número intermedio sería la velocidad parcial hacia adelante (valor positivo) o en reversa (valor negativo). Esto es muy similar al uso típico de un motor DC controlado con la librería de adafruit_motor.

Este ejemplo se mueve con toda velocidad hacia adelante durante dos segundos, se detiene por dos segundos, luego en toda velocidad en reversa por dos segundos, y luego se detiene por 4 segundos.

# Continuous Servo Test Program for CircuitPython
import time
import board
import pulseio
from adafruit_motor import servo

# create a PWMOut object on Pin A2.
pwm = pulseio.PWMOut(board.A2, frequency=50)

# Create a servo object, my_servo.
my_servo = servo.ContinuousServo(pwm)

while True:
    print("forward")
    my_servo.throttle = 1.0
    time.sleep(2.0)
    print("stop")
    my_servo.throttle = 0.0
    time.sleep(2.0)
    print("reverse")
    my_servo.throttle = -1.0
    time.sleep(2.0)
    print("stop")
    my_servo.throttle = 0.0
    time.sleep(4.0)

¡Muy sencillo!

Ahora asumamos que 0 grados es 0.5ms y 180 es un multo de 2.5ms. Esto es más amplio que el valor oficial de 1ms a 2ms de ancho de pulsos. Si tienes un servo que utilice un rango diferente, puedes inicializar el valor en el objeto servo con un diferente mínimo (min_pulse) y máximo (max_pulse). Por ejemplo:

servo = adafruit_motor.servo.Servo(pwm, min_pulse = 500, max_pulse = 2500) 

Para información más detallada sobre utilizar servos con CircuitPython, ¡puedes visitar la sección de CircuitPython en la guía de Servos!

Tacto Capacitivo con CircuitPython

Cada tarjeta CircuitPython designada como M0, tiene capacidades de tacto capacitivo. ¡Esto significa que cada tarjeta tiene al menos un pin que funciona como una entrada cuando lo tocas! La función de toque capacitivo se realiza completamente en hardware, por lo que no hacen falta resistencias externas, capacitores o circuitos integrados. ¡Lo cual está muy bien!

El toque capacitivo no está soportado en las tarjetas M4 Express.

Este ejemplo te va a mostrar como utilizar un pin de toque capacitivo de tu tarjeta.

Copia y pega el código dentro de code.py utilizando tu editor favorito, y salva el archivo.

import time

import board
import touchio

touch_pad = board.A0  # Will not work for Circuit Playground Express!
# touch_pad = board.A1  # For Circuit Playground Express

touch = touchio.TouchIn(touch_pad)

while True:
    if touch.value:
        print("Touched!")
    time.sleep(0.05)

Creando la Entrada Táctil

Primero, asignamos la variable touch_pad hacia un pin. Este ejemplo utiliza A0, así que asignamos touch_pad = board.A0. Usted puede elegir cualquier pin con capacidades táctiles de la lista a continuación si usted desea utilizar otro pin. Luego creamos un objeto táctil, lo nombramos touch y lo conectamos a touch_pad.

Para utilizar con la Circuit Playground Express, comente  touch_pad = board.A0 y descomente touch_pad = board.A1.

Ciclo Principal

Ahora, creamos un ciclo que revisa si el pin ha sido tocado. Si es así, imprime (print) hacia la consola serial. ¡Conéctese a la consola serial para ver impresos el resultado cuando tocas el pin!

Recuerde: Para "comentar" una linea, ponga un # un espacio en blanco al inicio. Para "descomentar" una línea, remueva el # más el espacio en blanco al inicio.

No se requiere hardware adicional, porque puedes tocar el pin directamente. Sin embargo, es posible que quiera conectarles cables de lagarto o cinta de cobre a objetos metálicos o conductivos. ¡Puedes probar con cubiertos metálicos, frutas y otras comidas, líquidos, papel aluminio y otros materiales que tengas a mano!

Es posible que sea necesario recargar tu código o reiniciar tu tarjeta luego de cambiar un objeto conectado, porque el toque capacitivo se "calibra" basado en lo que observa el arranque. Así que si tienes muy poquitas respuestas o demasiadas, ¡recarga tu código desde la consola serial o expulsa la tarjeta y presiona el botón de reset!

Encuentre el pin o pines

Es posible que tu tarjeta tenga pines con capacidades táctiles además de A0. Hemos incluído un alista que ayuda a encontrar A0 (o A1 en el caso de la CPX) para este ejemplo, identificado con una flecha magenta. ¡La lista también incluye información sobre otros pines que podrían funcionar en cada tarjeta!

Para utilizar otros pines, simplemente cambie el número en A0 al pin que desea utilizar. Por ejemplo si desea utilizar A3, su código debería inciar con touch_pad = board.A3.

Si desea utilizar más de un pin a la vez, su código va a ser similar al a continuación. Si lo necesita, puede modificar este código para incluir los pines que funcionen para tu tarjeta.

# CircuitPython Demo - Cap Touch Multiple Pins
# Example does NOT work with Trinket M0!

import time

import board
import touchio

touch_A1 = touchio.TouchIn(board.A1)  # Not a touch pin on Trinket M0!
touch_A2 = touchio.TouchIn(board.A2)  # Not a touch pin on Trinket M0!

while True:
    if touch_A1.value:
        print("Touched A1!")
    if touch_A2.value:
        print("Touched A2!")
    time.sleep(0.05)
¡Este ejemplo NO funciona con la Trinket M0! Debe cambiar los pines a utilizar en esta tarjeta. Este ejemplo solo funciona para las Gemma, Circuit Playground Express, Feather M0 Express, Metro M0 Express y las ItsyBitsy M0 Express.

Utilice la lista a continuación para conocer cuales pines puede utilizar con su tarjeta. ¡Luego, trate de agregarlos a su código y diviértase!

Trinket M0

Hay tres pines con capacitades táctiles en la Trinket: A0, A3, y A4.

Recuerde, A0 está etiquetado como "1~" en las Trinket M0!

Gemma M0

Hay tres pines en las Gemma, con forma de pads amigables con clips de lagarto, que funcionan para entrada táctil: A0, A1 y A2.

Feather M0 Express

Hay seis pines en las Feather con capacidades táctiles: A0 - A5.

ItsyBitsy M0 Express

Hay seis pines en las ItsyBitsy con capacidades táctiles: A0 - A5.

Metro M0 Express

Hay seis pines en las Metro con capacidades táctiles: A0 - A5.

Circuit Playground Express

¡Las Circuit Playground Express tienen siete pines con capacidad táctil!  Tienes A1 - A7 disponibles, con forma de pads amigables a clips de lagarto. Puedes ver la guía de CPX en la sección de Toque Capacitivo para más información de como utilizar estos pads para toque!

Recuerde: A0 NO tiene capacidades táctiles en las CPX.

RGB LED Interno con CircuitPython

Todas las tarjetas tienen un LED RGB integrado. Puedes utilizar a CircuitPython para controlar el color y la intensidad de este LED. Hay dos tipos diferentes de LEDs RGB integrados, los DotStar y los NeoPixel. Esta sección los cubre a ambos y explica cual tarjeta tiene cual tipo de LED.

circuitpython_NeoPixelDotStar.jpg
Un NeoPixel en la izquierda, un DotStar a la derecha. No es a escala... ¡los DotStars integrados son pequeños!

Este primer ejemplo de muesta como cambiar de color e intensidad en el LED RGB integrado.

Copia y pega el código dentro de code.py utilizando tu editor favor y salva el archivos.

import time
import board

# For Trinket M0, Gemma M0, ItsyBitsy M0 Express, and ItsyBitsy M4 Express
import adafruit_dotstar
led = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1)
# For Feather M0 Express, Metro M0 Express, Metro M4 Express, and Circuit Playground Express
# import neopixel
# led = neopixel.NeoPixel(board.NEOPIXEL, 1)

led.brightness = 0.3

while True:
    led[0] = (255, 0, 0)
    time.sleep(0.5)
    led[0] = (0, 255, 0)
    time.sleep(0.5)
    led[0] = (0, 0, 255)
    time.sleep(0.5)

Creando el objeto LED

Primero, creamos el objeto LED y lo conectamos con el pin o pines correctos. En el caso del NeoPixel, solo es necesario un pin, y lo hemos llamado NEOPIXEL para facilidad de uso. Sin embargo, para el caso de un DotStar es necesario dos pines, así vamos a usar los pines nombrados como APA102_MOSI y APA102_SCK para configurarlo. Ya que estamos usando un solo LED integrado, ¡lo siguiente que queremos es decirle que la cantidad de LEDs es 1!

En las Trinket M0, Gemma M0, ItsyBitsy M0 Express, y las ItsyBitsy M4 Express tienen su propio LED Dotstar integrado, por lo que no se requieren cambios a la versión inicial de este ejemplo.

Para las Feather M0 Express, Feather M4 Express, Metro M0 Express, Metro M4 Express, y Circuit Playground Express tienen su propio LED  NeoPixel integrado, así que debes comentar  import adafruit_dotstar y led = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1), y descomentar import neopixel y led = neopixel.NeoPixel(board.NEOPIXEL, 1).

Recuerda: Para "comentar" una línea, agrega un # y un espacio en blanco al inicio. Para "descomentar" una línea, remueva el # más el espacio en blanco del inicio.

Brillo

Para definir el brillo, simplemente utilice el atributobrightness. El brillo se define con un número entre 0 y 1, que representa un porcentaje de 0% a 100%. Así que, led.brightness = (0.3) ajusta el brillo del LED a un 30%. El brillo por omisión es 1 o 100%, y ¡en su máximo el LED es demasiado brillante! Lo puedes bajar si así lo deseas.

Ciclo Principal

Los colores del LED se definen con una combinación de rojo (red), verde (green), y azul (blue), en la forma de una tupla (RG, B). Cada miembro de la tupla es un número entre 0 y 255 que determina la cantidad de color presente. ¡Rojo, verde y azul en diferentes combinaciones pueden crear todos los colores del arcoiris! Así que por ejemplo, para prender el LED en rojo, la tupla sería (255, 0, 0), lo cual es el máximo de color para el rojo, y nada de verde o azul. Verde sería (0, 255, 0) y así. Para los colores intermedios, puedes definir una combinación como cían sería (0, 255, 255), con cantidades iguales de verde y azul.

El ciclo principal es muy sencillo. Define el primer LED en rojo utilizando (255, 0, 0), luego verde usando (0, 255, 0), y finalmente azul usando (0, 0, 255). Luego hacemos un llamado a  time.sleep() para que se quede en cada color un periodo de tiempo. Escogemos  time.sleep(0.5), o medio segundo. ¡Sin el time.sleep() va a parpadear los colores demasiado rápido y va a ser difícil de ver!

Observe que definimos led[0]. Esto quiere decir el primero, en el caso de la mayoría de tarjetas, el único LED. En CircuitPython, los contadores inician en 0. ¡Así que el primero objeto de por ejemplo una lista, va a ser 0!

Trata cambiando los números en las tuplas, para cambiar tu LED a cualquier color del arcoiris. O, puedes agregar más líneas con diferentes tuplas de color para agregar más colores a la secuencia. Siempre agrega time.sleep(), ¡pero trata cambiando la cantidad de tiempo para crear diferentes animaciones de ciclo!

Haciendo Arcoiris (¿a quién no le gustan?)

Programar efectos de arcoiris involucra un poquito de matemática y una función llamada wheel. Para detalles de como funciona wheel, ¡observa esta explicación!!

El último ejemplo muestra como agregar la animación de arcoiris al LED RGB integrado.

Copia y pega el código en code.py utilizando tu editor favorito y salva el archivo. Recuerda comentar y descomentar las líneas apropiadas para tu tarjeta, según se explicó arriba.

import time
import board

# For Trinket M0, Gemma M0, ItsyBitsy M0 Express and ItsyBitsy M4 Express
import adafruit_dotstar
led = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1)
# For Feather M0 Express, Metro M0 Express, Metro M4 Express and Circuit Playground Express
# import neopixel
# led = neopixel.NeoPixel(board.NEOPIXEL, 1)


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


led.brightness = 0.3

i = 0
while True:
    i = (i + 1) % 256  # run from 0 to 255
    led.fill(wheel(i))
    time.sleep(0.1)

Vamos a agregar la función wheel luego de setup, pero antes de nuestro ciclo principal.

Y justo antes de nuestro ciclo principal, asignamos a la variable i = 0, así que está listo para usarse dentro del ciclo.

El ciclo principal contiene algo de matemática que cicla i de 0 a 255 y de vuelta de nuevo de forma repetida. ¡Usamos esto para ciclar wheel() alrededor del arcoiris!

El time.sleep() determina la velocidad con la que el arcoiris cambia. ¡Trata un número mayor para un arcoiris más lento, y un número menor para uno más rápido!

Arcoiris en la Circuit Playground Express

Note que aquí usamos led.fill en lugar de led[0]. Esto significa que prendemos todo los LEDs, que en nuestro código actual es solo uno. ¿Para que preocuparnos con fill? Bueno, es posible que tengas una Circuit Playground Express, la cual tiene DIEZ LEDs NeoPixel integrados. Los ejemplos hasta el momento solo han prendido el primero. Si deseas realizar un arcoiris con todos los diez LEDs, cambie el 1 en:

led = neopixel.NeoPixel(board.NEOPIXEL, 1)

por 10 para que lea:

led = neopixel.NeoPixel(board.NEOPIXEL, 10).

Esto le dice al código que busque 10 LEDs, en lugar de solo 1. Ahora salve el código y ¡observe como se mueve el arcoiris! Puede cambiar el mismo 1 por 10 en los ejemplos anteriores, y ¡utilizar led.fill para prender los LEDs con los colores que escoja! Para más detalles, revise la sección de NeoPixel en la guía de CPX!

NeoPixeles en CircuitPython

Los NeoPixeles son una forma revolucionaria y muy popular para agregarle luces y color a tu proyecto. Estas tiras de luces RGB tienen controladoras dentro de cada LED, así que solo le envías los datos RGB y los LEDs realizan todo el trabajo por ti. ¡Son la combinación perfecta para CircuitPython!

Puedes controlar 300 LEDs tipo NeoPixel con control de brillo (se le define brightness=1.0 a la hora de crear el objeto) y 1000 LEDs sin control de brillo. Esto porque el ajustar el brillo requiere que se regenere dinamicamente los datos a enviar, con cada escritura.

¡Vas a necesitar la librería neopixel.mpy si no las tienes ahorita en tu carperta /lib! La puedes obtener 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 NeoPixeles. Verifica que tu conexión sea hacia el lado de DATA INPUT o DIN. ¡Conectarse a DATA OUT o a DOUT es un error común! Estas conexiones están etiquetadas y algunas tienen flechas para resaltar hacia donde deben fluir los datos.

Para alimentar los pixeles desde la tarjeta, el regulador de salida de 3.3V puede manejar picos de alrededor de 500mA, lo cual es suficiente para 50 pixeles de uso 'promedio'. Si quieres luces realmente brillantes y muchos pixeles, recomendamos alimentar directamente de una fuente externa.

  • 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 NeoPixeles 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 NeoPixeles!
Tome nota que el orden de los cables en tu tira de NeoPixeles 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 - NeoPixel
import time
import board
import neopixel

pixel_pin = board.A1
num_pixels = 8

pixels = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=0.3, 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_chase(color, wait):
    for i in range(num_pixels):
        pixels[i] = color
        time.sleep(wait)
        pixels.show()
    time.sleep(0.5)


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)
GREEN = (0, 255, 0)
CYAN = (0, 255, 255)
BLUE = (0, 0, 255)
PURPLE = (180, 0, 255)

while True:
    pixels.fill(RED)
    pixels.show()
    # Increase or decrease to change the speed of the solid color change.
    time.sleep(1)
    pixels.fill(GREEN)
    pixels.show()
    time.sleep(1)
    pixels.fill(BLUE)
    pixels.show()
    time.sleep(1)

    color_chase(RED, 0.1)  # Increase the number to slow down the color chase
    color_chase(YELLOW, 0.1)
    color_chase(GREEN, 0.1)
    color_chase(CYAN, 0.1)
    color_chase(BLUE, 0.1)
    color_chase(PURPLE, 0.1)

    rainbow_cycle(0)  # Increase the number to slow down the rainbow

Creando el LED

Lo primero que tenemos que hacer es instanciar al objeto LED. El objeto para NeoPixel 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 controlar tus NeoPixeles y 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 cualquier pin. Hemos escogido A1. Para configurar el pin, asigne la variable  pixel_pin hacia el pin que desea utilizar, en nuestro caso board.A1.

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

Hemos escogido definir el brillo en un 30% con brightness=0.3.

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 NeoPixeles

Hemos incluído algunas funciones utilitarias para crear efectos visuales muy divertidos, que puedes encontrar en este código. El primero es wheel() de la cual acabamos de aprender en LED RGB Integrado. Luego tenemos color_chase() (persecución de color) la cual pide que le digas un color y la cantidad de segundos que deseas entre cada paso de la persecución. Luego tenemos a rainbow_cycle()(ciclo de arcoiris), la cual pide que le indices el tiempo en segundos que deseas que tome 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.

Ciclo Principal

Gracias a nuestros utilitarios, el ciclo principal es muy sencillo. Hemos incluido el código para configurar todos los NeoPixeles que estamos usando a rojo, verde y azul por un segundo cada uno. Luego llamamos a color_chase(), una vez para cada color de nuestra lista, con una pausa de 0.1 segundos antes de cambiar el LED en la persecución. Por último llamamos a rainbow_cycle(0), lo que quiere decir que la animación es tan rápida como sea posible. ¡Aumente ambos números para bajar la velocidad de cada animación!

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 NeoPixeles en nuestra guía NeoPixel UberGuide https://learn.adafruit.com/adafruit-neopixel-uberguide

NeoPixeles RGBW

Los NeoPixeles se pueden conseguir en RGB que quiere decir que contiene tres LEDs, uno rojo, uno verde y uno azul. También se pueden conseguir RGBW, que quiere decir que contiene cuatro LEDS, rojo, verde, azul y blanco. El código para manejar NeoPixeles tipo RGBW es un poco diferente al de RGB.

Si trata de correr código de RGB con NeoPixeles de tipo RGBW, aproximadamente ¾ de los LEDs van a prender, y van a ser de un color incorrecto aunque se vea que están cambiando. Esto porque los NeoPixeles requieren que se les envíe un pedazo de información para cada color disponible (rojo, verde, azul y probablemente blanco).

De esta manera, los LEDs RGB requiere tres pedazos de información mientras que los LEDs RGBW requieren CUATRO piezas de información. Así que cuando cree un objeto de LED para trabajar con LEDs de tipo RGBW, les vas a agregar bpp=4, lo cual define la cantidad de pedazos de información por bit a cuatro (¡las cuatro piezas de información!).

Luego, debes incluir un número adicional en cada tupla de color que crees. Por ejemplo, rojo va a ser (255, 0, 0, 0). Así es como envías las cuarta pieza de información. ¡Revise el ejemplo a continuación para observar como se ve nuestro código usando LEDs de tipo RGBW!

# CircuitPython demo - NeoPixel RGBW

import time
import board
import neopixel

pixel_pin = board.A1
num_pixels = 8

pixels = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=0.3, auto_write=False,
                           pixel_order=(1, 0, 2, 3))


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


def color_chase(color, wait):
    for i in range(num_pixels):
        pixels[i] = color
        time.sleep(wait)
        pixels.show()
    time.sleep(0.5)


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, 0)
YELLOW = (255, 150, 0, 0)
GREEN = (0, 255, 0, 0)
CYAN = (0, 255, 255, 0)
BLUE = (0, 0, 255, 0)
PURPLE = (180, 0, 255, 0)

while True:
    pixels.fill(RED)
    pixels.show()
    # Increase or decrease to change the speed of the solid color change.
    time.sleep(1)
    pixels.fill(GREEN)
    pixels.show()
    time.sleep(1)
    pixels.fill(BLUE)
    pixels.show()
    time.sleep(1)

    color_chase(RED, 0.1)  # Increase the number to slow down the color chase
    color_chase(YELLOW, 0.1)
    color_chase(GREEN, 0.1)
    color_chase(CYAN, 0.1)
    color_chase(BLUE, 0.1)
    color_chase(PURPLE, 0.1)

    rainbow_cycle(0)  # Increase the number to slow down the rainbow

Lea la Documentación

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

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".

UART Serial en CircuitPython

Además de la conexión USB-serial que usamos para el REPL, también existe un UART por hardware que puedes utilizar. ¡Esto es útil para hablar con dispositivos como GPSs, algunos sensores y otras microcontrladoras!

Este ejemplo para iniciar muestra como puede crear un dispositivo UART para comunicarse por hardware con dispositivos seriales.

Para utilizar este ejemplo, necesita algo que pueda generar datos UART. ¡Nosotros hemos usado un GPS! Note que el GPS va a enviar datos UARL sin necesidad de tener fija tu ubicación. ¡Ustedes puede probar este ejemplo desde su escritorio! Vas a tener datos para poder leer, simplemente que puede que no incluyan tu ubicación.

¡Vas a necesitar a la librería adafruit_bus_device copiada a la carpeta /lib si no lo has hecho todavía! La puedes conseguir del Compilador de Librerías para CircuitPython. Si necesita ayuda instalando las librerías, puedes revisar la página sobre Librerías para CircuitPython.

Copie y pegue el código dentro de code.py utilizando su editor favorito y salve el archivo.

# CircuitPython Demo - USB/Serial echo

import board
import busio
import digitalio

led = digitalio.DigitalInOut(board.D13)
led.direction = digitalio.Direction.OUTPUT

uart = busio.UART(board.TX, board.RX, baudrate=9600)

while True:
    data = uart.read(32)  # read up to 32 bytes
    # print(data)  # this is a bytearray type

    if data is not None:
        led.value = True

        # convert bytearray to string
        data_string = ''.join([chr(b) for b in data])
        print(data_string, end="")

        led.value = False

El Código

Primero creamos un objeto UART. Le enviamos los pines que vamos a utilizar, board.TX and board.RX, y le configuramos baudrate=9600. Mientras estos pines están etiquetados en la mayoría de las tarjetas, tenga cuidado que RX y TX no están etiquetados en las Gemma, y están etiquetados por debajo de las Trinket. Vea los diagramas a continuación para ayuda encontrando los pines correctos para su tarjeta.

Una vez que el objeto ha sido creado, usted leer los datos de entrada conread(numbytes) donde se le puede especificar el número máximo de bytes a leer. Va a retornar un objeto de arreglo de bytes si ha recibido algo. ¡Note que siempre va a retornar inmediatamente porque hay un buffer interno! Así que lea tantos datos como pueda procesar.

Si no hay datos disponibles, read() va a retornar None, así que revise esto antes de continuar.

Los datos retornados vienen en un arreglo de bytes, si lo quieres convertir a una cadena, puede utilizar este útil código que ejecuta chr() en cada byte:

datastr = ''.join([chr(b) for b in data]) # convert bytearray to string

Sus resultados se van a ver algo como esto:

Para más información sobre como los datos que estás leyendo y sobre el Ultimate GPS, revise la guía Ultimate GPS: https://learn.adafruit.com/adafruit-ultimate-gps

Cableándolo

Vas a necesitar un par de cosas para conectar tu GPS a tu tarjeta.

Para las Gemma M0 y las CircuitPlayground Express, usted puede utilizar cables de lagarto para conectarse al Flora Ultimate GPS Module.

Para las Trinket M0, Feather M0 Express, Metro M0 Express y ItsyBitsy M0 Express, vas a necesitar una tabla de prototipado y cables para conectarse al Ultimate GPS Breakout.

Hemos incluido diagramas para mostrarte como conectar el GPS a tu tarjeta. En estos diagramas, el color de los cables son los mismos pines en todas las tarjetas:

  • El cable negro conecta entre los pines de tierra (ground).
  • El cable rojo conecta los pines de alimentación (power) entre el GPS y tu tarjeta.
  • El cable azul conecta TX del GPS al RX en tu tarjeta.
  • El cable blanco conecta RX del GPS al TX en tu tarjeta.

¡Revise la lista a continuación para un diagrama específico para tu tarjeta!

¡Cuidado! ¡Una confusión típica con seriales UART es que RX en una tarjeta se conecta a TX de la otra! Sin embargo, algunas tarjetas tienen a RX etiquetado como TX y viceversa. ¡Así que vas a querer comenzar RX con TX, pero si eso no funciona, trata cambiando los cables!

Circuit Playground Express y Circuit Playground Bluefruit

  • Conecte 3.3v en su CPX a 3.3v en su GPS.
  • Conecte GND en su CPX a GND en su GPS.
  • Conecte RX/A6 en su CPX a TX en su GPS.
  • Conecte TX/A7 en su CPX a RX en su GPS.

Trinket M0

  • Conecte USB de la Trinket hacia VIN del GPS.
  • Conecte Gnd de la Trinket hacia GND del GPS.
  • Conecte D3 de la Trinket hacia TX del GPS.
  • Conecte D4 de la Trinket hacia RX del GPS.

Gemma M0

  • Conecte 3vo de la Gemma a 3.3v del GPS.
  • Conecte GND de la Gemma a GND del GPS.
  • Conecte A1/D2 de la Gemma a TX del GPS.
  • Conecte A2/D0 de la Gemma a RX del GPS.

Feather M0 Express y Feather M4 Express

  • Conecte USB de la Feather a VIN del GPS.
  • Conecte GND de la Feather a GND del GPS.
  • Conecte RX de la Feather a TX del GPS.
  • Conecte TX de la Feather a RX del GPS.

ItsyBitsy M0 Express y ItsyBitsy M4 Express

  • Conecte USB de la ItsyBitsy a VIN del GPS
  • Conecte G de la ItsyBitsy a GND del GPS.
  • Conecte RX/0 de la ItsyBitsy a TX del GPS.
  • Conecte TX/1 de la ItsyBitsy a RX del GPS.

Metro M0 Express y Metro M4 Express

  • Conecte 5V de la Metro a VIN del GPS.
  • Conecte GND de la Metro a GND del GPS.
  • Conecte RX/D0 de la Metro a TX del GPS.
  • Conecte TX/D1 de la Metro a RX del GPS.

¿Donde está mi UART?

En las SAMD21, tenemos la flexibilidad de poder usar una gama de pines para UART. Compare esto a algunos chips como los ESP8266 con pines fijos para UART. La buenas noticia es que puedes usar muchos pero no todos los pines. Por la gran cantidad de tarjetas con chips SAMD que tenemos, es imposible garantizar cualquier otra cosa que el uso de los etiquetados en 'TX' y 'RX'. Así que si requiere usar otra combinación, o múltiples UARTs, ¿como vas a encontrar esos pines? ¡Sencillo! Hemos escrito una script útil.

Todo lo que necesitas hacer es copiar este archivo a tu tarjeta, renombrarlo como code.py, conectar a la consola serial, ¡y ver la salida! El resultado imprime una bonita lista de pares de pines TX y RX que puedes utilizar.

Así es como se ven los resultados en una Trinket M0, tu salida puede variar y puede que sea muy larga. Para más detalles sobre UARTs y comunicaciones seriales revise nuestra guía detallada, aquí

import board
import busio
from microcontroller import Pin


def is_hardware_uart(tx, rx):
    try:
        p = busio.UART(tx, rx)
        p.deinit()
        return True
    except ValueError:
        return False


def get_unique_pins():
    exclude = ['NEOPIXEL', 'APA102_MOSI', 'APA102_SCK']
    pins = [pin for pin in [
        getattr(board, p) for p in dir(board) if p not in exclude]
            if isinstance(pin, Pin)]
    unique = []
    for p in pins:
        if p not in unique:
            unique.append(p)
    return unique


for tx_pin in get_unique_pins():
    for rx_pin in get_unique_pins():
        if rx_pin is tx_pin:
            continue
        else:
            if is_hardware_uart(tx_pin, rx_pin):
                print("RX pin:", rx_pin, "\t TX pin:", tx_pin)
            else:
                pass

Trinket M0: Crear UART antes de I2C

En las Trinket M0 (solamente), si estás utilizando tanto busio.UART y busio.I2C, debes crear el objeto de UART primero, de esta forma:

Download: file
>>> import board,busio
>>> uart = busio.UART(board.TX, board.RX)
>>> i2c = busio.I2C(board.SCL, board.SDA)

Si creas primero busio.I2C no funciona:

Download: file
>>> import board,busio
>>> i2c = busio.I2C(board.SCL, board.SDA)
>>> uart = busio.UART(board.TX, board.RX)
Traceback (most recent call last):
File "", line 1, in 
ValueError: Invalid pins

I2C en CircuitPython

I2C es un protocolo de dos cables para comunicarse con sensores simples y dispositivos, lo que quiere decir que usa dos conexiones para transmitir y recibir datos. Existen muchos dispositivos I2C disponibles y son muy sencillos de utilizar con CircuitPython. Tenemos librerías para muchos dispositivos I2C en nuestro compilado de librerías. (Si no ves tu sensor, sigue revisando cada tanto, ¡escribimos más todo el tiempo!)

En esta sección, vamos a aprender como escanear el bus I2C para buscar dispositivos conectados. Luego vamos a aprender como interactuar con un dispositivo I2C.

Vamos a utilizar el TSL2561, un sensor de luz muy común y de bajo costo. Mientras que el código que ejecutamos es específico para el TSL2561, el proceso general es el mismo para cualquier sensor o dispositivo I2C.

¡Vas a necesitar la librería adafruit_tsl2561.mpy y la librería adafruit_bus_device en tu carpeta /lib si no los has copiado todavía! Los puedes conseguir del compilado de Librerías para CircuitPython. Si necesita ayuda instalando la librería, revise la página de Librerías para CircuitPython.

Estos ejemplos van a utilizar el sensor de lux TSL2561 versión Flora y versión breakout. Lo primero que quieres hacer es conectar el sensor I2C para que tu tarjeta tenga con quién hablar.

Cableándolo

Vas a necesitar un par de cosas para conectar el TSL2561 a tu tarjeta.

Para las Gemma M0 y las Circuit Playground Express, puede utilizar cables de lagarto para conectarse a la versión Flora del sensor de lux TSL2561.

Para las Trinket M0, Feather M0 Express, Metro M0 Express y las ItsyBitsy M0 Express, vas a necesitar una tabla de prototipo y cables para conectarse a la versión Breakout del sensor de lux TSL2561.

Hemos incluido diagramas para mostrarte como conectar la TSL2561 a tu tarjeta. En estos diagramas el color de los cables es el mismo para los pines de cualquier tarjeta.

  • El cable negro conecta entre los pines de tierra (ground).
  • El cable negro conecta entre los pines de alimentación de la TSL2561 y tu tarjeta.
  • El cable amarillo conecta del SCL de tu TSL2561 a SCL de tu tarjeta.
  • El cable azul conecta de SDA de tu TSL2561 a SDA de tu tarjeta.

¡Revisar la lista a continuación para el diagrama de tu tarjeta!

¡Tenga cuidado que las microcontroladoras de Adafruit no tienen resistencias de I2C integradas! Los breakouts si los tienen, pero si estás construyendo tu propia tarjeta o usando un breakout de otra marca que no sea Adafruit, debes agregar resistencias de 2.2K-10K ohms en función de pull-up para ambos SDA y SCL hacia 3.3V.

Circuit Playground Express y Circuit Playground Bluefruit

  • Conecte 3.3v de la CPX a 3.3v del TSL2561.
  • Conecte GND de la CPX a GND del TSL2561.
  • Conecte SCL/A4 de la CPX a SCL del TSL2561.
  • Conecte SDL/A5 de la CPX a SDA del TSL2561.

Trinket M0

  • Conecte USB de la Trinket a VIN del TSL2561.
  • Conecte Gnd de la Trinket a GND del TSL2561.
  • Conecte D2 de la Trinket a SCL del TSL2561.
  • Conecte D0 de la Trinket a SDA del TSL2561.

Gemma M0

  • Conecte 3vo de la Gemma a 3V del TSL2561.
  • Conecte GND de la Gemma a GND del TSL2561.
  • Conecte A1/D2 de la Gemma a SCL del TSL2561.
  • Conecte A2/D0 de la Gemma a SDA del TSL2561.

Feather M0 Express and Feather M4 Express

  • Conecte USB de la Feather a VIN del TSL2561.
  • Conecte GND de la Feather a GND del TSL2561.
  • Conecte SCL de la Feather a SCL del TSL2561.
  • Conecte SDA de la Feather a SDA del TSL2561.

ItsyBitsy M0 Express y ItsyBitsy M4 Express

  • Conecte USB de la ItsyBitsy a VIN del TSL2561.
  • Conecte G de la ItsyBitsy a GND del TSL2561.
  • Conecte SCL de la ItsyBitsy a SCL del TSL2561.
  • Conecte SDA de la ItsyBitsy a SDA del TSL2561.

Metro M0 Express y Metro M4 Express

  • Conecte 5V de la Metro a VIN del TSL2561.
  • Conecte GND de la Metro a GND del TSL2561.
  • Conecte SCL de la Metro a SCL del TSL2561.
  • Conecte SDA de la Metro a SDA del TSL2561.

Encontrando tu Sensor

Lo primero que quieres hacer luego de cablear tu sensor, es asegurarse que esté conectado correctamente. Vamos a realizar un escaneo del bus I2C para ver si la tarjeta está conectada, y si lo está, imprima su dirección I2C.

Copie y pegue el código hacia code.py utilizando su editor favorito, y salve el archivo.

# CircuitPython demo - I2C scan

import time

import board
import busio

i2c = busio.I2C(board.SCL, board.SDA)

while not i2c.try_lock():
    pass

while True:
    print("I2C addresses found:", [hex(device_address)
                                   for device_address in i2c.scan()])
    time.sleep(2)

Primero creamos un objeto i2c y le enviamos los pines I2C: board.SCL y board.SDA.

Para poder escanearlo, debemos amarrar a I2C para que la única cosa que lo acceda sea este código. Luego incluimos un ciclo que se espera hasta que I2C esté amarrado y luego continúa a la función de escaneado.

Por último, tenemos un ciclo que ejecuta el escaneo como tal, i2c_scan(). Dado que I2C normalmente se refiere a sus direcciones en formato hexadecimal, hemos incluido un poco de código para retornar los resultados en este formado:[hex(device_address) for device_address in i2c.scan()].

¡Abra la consola serial para ver los resultados! El código imprime un arreglo de direcciones. Hemos conectado el TSL2561 el cual tiene una dirección de 7-bits de I2C de 0x39. El resultado para este sensor es I2C addresses found: ['0x39']. Si no retornan direcciones, revise los diagramas de cableado para verificar que ha cableado su sensor de forma correcta.

Datos del Sensor I2C

Ahora tenemos certeza de que nuestro sensor se encuentra conectado y listo para usar. ¡Ahora vamos a aprender como leer los datos del sensor!

Copie y pegue este código dentro de code.py utilizando su editor favorito y salve el archivo.

# CircuitPython Demo - I2C sensor

import time

import adafruit_tsl2561
import board
import busio

i2c = busio.I2C(board.SCL, board.SDA)

# Lock the I2C device before we try to scan
while not i2c.try_lock():
    pass
# Print the addresses found once
print("I2C addresses found:", [hex(device_address)
                               for device_address in i2c.scan()])

# Unlock I2C now that we're done scanning.
i2c.unlock()

# Create library object on our I2C port
tsl2561 = adafruit_tsl2561.TSL2561(i2c)

# Use the object to print the sensor readings
while True:
    print("Lux:", tsl2561.lux)
    time.sleep(1.0)

Este código comienza de la misma forma que el código de escaneo. Hemos incluido el código de escaneo para que tengas verificación de que tu sensor está conectado correctamente y es detectado. Imprime su dirección una vez. Luego del escaneo, deamarramos el bus I2C con i2c_unlock() para que podamos usar el sensor para datos.

Creamos un objeto sensor utilizando la librería del sensor. Lo llamamos tsl2561  y nos provee el objeto i2c.

Luego tenemos un simple ciclo que imprime la lectura de lux usando el objeto de sensor que hemos creado. Agregamos un time.sleep(1.0), para que solo imprima una vez por segundo.  Saque la consola serial para ver los resultados. Trate alumbrando una luz al sensor para que vea como cambian los resultados.

¿Donde está mi I2C?

En las SAMD21, SAMD51 y nRF52840, tenemos la flexibilidad de poder usar una gama de pines para I2C. En las nRF52840, ¡cualquier pin puede ser usado para I2C! Algunos chips como las ESP8266, requieren uso de bitbangio, pero también puedes usar cualquier pin para I2C. Algunos otros chips tienen sus pines de I2C fijos.

La buena noticia es que puedes usar muchos, pero no todos los pines. Por la gran cantidad de tarjetas SAMD que tenemos, es imposible garantizar con otros pines que no sean los etiquetados como 'SDA' y 'SCL'.  Así que si desea otra configuración o múltiples interfaces I2C, ¿como encontramos esos pines? ¡Sencillo! Hemos escrito un script bien útil.

Todo lo que tiene que hacer es copiar este archivo a su tarjeta, renombrarlo como code.py, conectarse a la consola serial y ver el resultado. En la salida vemos una bonita lista con los pares de pines de SCL y SDA que puede utilizar.

Esto son los resultados para una ItsyBitsy M0 Express. Tu salida puede variar y puede ser muy larga. Para más detalles sobre I2C y comunicaciones seriales, revise nuestra guía detallada, aquí.

import board
import busio
from microcontroller import Pin

def is_hardware_I2C(scl, sda):
    try:
        p = busio.I2C(scl, sda)
        p.deinit()
        return True
    except ValueError:
        return False
    except RuntimeError:
        return True


def get_unique_pins():
    exclude = ['NEOPIXEL', 'APA102_MOSI', 'APA102_SCK']
    pins = [pin for pin in [
        getattr(board, p) for p in dir(board) if p not in exclude]
            if isinstance(pin, Pin)]
    unique = []
    for p in pins:
        if p not in unique:
            unique.append(p)
    return unique


for scl_pin in get_unique_pins():
    for sda_pin in get_unique_pins():
        if scl_pin is sda_pin:
            continue
        else:
            if is_hardware_I2C(scl_pin, sda_pin):
                print("SCL pin:", scl_pin, "\t SDA pin:", sda_pin)
            else:
                pass

Teclado y Ratón HID en CircuitPython HID

Estos ejemplos han sido actualizados para la versión de la librería HID para CircuitPython 4+. En algunas tarjetas como las CircuitPlayground Express, esta librería está integrada en CircuitPython. Así que use la última versión de CircuitPython para estos ejemplos. (Al menos 5.0.0-beta3).

Una de las cosas que hemos integrado a CircuitPython es 'HID' o Dispositivo control para Interfaces Humanas - lo que quiere decir, capacidades de teclado y de mouse. Esto significa que tu tarjeta de CircuitPython puede trabajar como un dispositivo de teclado, presionando teclas y comandos, o como un mouse que mueve su puntero y presiona botones. Esto puede ser muy útil porque incluso si no puedes adaptar tu software para trabajar con hardware, siempre hay una interface de teclado - así que si deseas una interfaz de toque capacitivo para un juego, por ejemplo, ¡el emular un teclado es algo que tienes funcionando en momento!

Esta sección te guía sobre el código necesario para crear un emulador de teclado o mouse. Primero, vamos a recorrer un ejemplo que utiliza pines en tu tarjeta para emular una entrada de teclado. Luego, vamos a mostrarte como cablear un joystick para que funcione como mouse, y analizar el código que hace que esto sea posible.

Vas a necesitar la librería de adafruit_hid en tu carpeta /lib si no las has copiado todavía. Puedes conseguirla en el compilado de Librerías de CircuitPython. Si necesitas ayuda instalando esta librería, revisa la página de Librerías para CircuitPython.

Emulador de Teclado con CircuitPython

Copia y pega el código hacia code.py utilizando tu editor favorito y salva el archivo.

# CircuitPython demo - Keyboard emulator

import time

import board
import digitalio
import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
from adafruit_hid.keycode import Keycode

# A simple neat keyboard demo in CircuitPython

# The pins we'll use, each will have an internal pullup
keypress_pins = [board.A1, board.A2]
# Our array of key objects
key_pin_array = []
# The Keycode sent for each button, will be paired with a control key
keys_pressed = [Keycode.A, "Hello World!\n"]
control_key = Keycode.SHIFT

# The keyboard object!
time.sleep(1)  # Sleep for a bit to avoid a race condition on some systems
keyboard = Keyboard(usb_hid.devices)
keyboard_layout = KeyboardLayoutUS(keyboard)  # We're in the US :)

# Make all pin objects inputs with pullups
for pin in keypress_pins:
    key_pin = digitalio.DigitalInOut(pin)
    key_pin.direction = digitalio.Direction.INPUT
    key_pin.pull = digitalio.Pull.UP
    key_pin_array.append(key_pin)

led = digitalio.DigitalInOut(board.D13)
led.direction = digitalio.Direction.OUTPUT

print("Waiting for key pin...")

while True:
    # Check each pin
    for key_pin in key_pin_array:
        if not key_pin.value:  # Is it grounded?
            i = key_pin_array.index(key_pin)
            print("Pin #%d is grounded." % i)

            # Turn on the red LED
            led.value = True

            while not key_pin.value:
                pass  # Wait for it to be ungrounded!
            # "Type" the Keycode or string
            key = keys_pressed[i]  # Get the corresponding Keycode or string
            if isinstance(key, str):  # If it's a string...
                keyboard_layout.write(key)  # ...Print the string
            else:  # If it's not a string...
                keyboard.press(control_key, key)  # "Press"...
                keyboard.release_all()  # ..."Release"!

            # Turn off the red LED
            led.value = False

    time.sleep(0.01)

Conecta el pin A1 o A2 hacia tierra, usando un cable de lagarto, y luego lo desconectas para presionar la tecla "A" o para escribir el texto "Hello world!" (o ¡Hola mundo!)

Este ejemplo de cableado muestra A1 y A2 conectados a tierra.

Recuerde, ¡en las Trinket, A1 y A2 están etiquetados como 2 y 0! En otras tarjetas, si vas a tener a A1 y A2 etiquetadas de forma esperada.

Creando los Objetos y las Variables

Primero, vamos a asignar unas variables para utilizar más tarde. Vamos a crear tres arreglos asignados a variables: keypress_pins, key_pin_array, y keys_pressed. El primero es los pines que vamos a utilizar. El segundo está vacío porque lo vamos a rellenar luego. El tercero lo que queremos que nuestro teclado escriba - en este caso la letra "A" y la frase "Hello World!". Creamos nuestra última variable, asignada a control_key el cual permite usar la tecla de "shift" cuando presionamos teclas. Nosotros vamos a utilizar hasta dos teclas de forma simultánea, pero es posible tener hasta seis teclas presionadas a la vez.

Luego creamos los objetos de keyboard y keyboard_layout. Por ahora solo tenemos US (si usted crea otro diseño de teclado, ¡favor envíe un Pull Request en Github!). Con time.sleep(1) nos evitamosun error que puede suceder si el programa comienza a trabajar apenas se conecta la tarjeta, antes de que la computadora pueda inicializar a la tarjeta como un teclado.

Luego tomamos los pines que seleccionamos arriba, y creamos los objetos de pin, definimos la dirección y les damos a cada uno un pull-up. Luego aplicamos los objetos de pin hacia key_pin_array para poderlos utilizar más tarde.

Luego, configuramos el LED rojo para poder utilizarlo como una luz de estado.

¡La última cosa que realizamos antes de comenzar el ciclo es imprimir (print) el texto "Waiting for key pin..." (o "Esperando a pin de tecla...") para que sepas que tu código está listo y esperando!

El Ciclo Principal

Dentro del ciclo, vamos a revisar cada pin para verificar que el estado haya cambiado, por ejemplo, si has conectado el pin hacia tierra. Una vez que cambie, imprime "Pin # grounded." para indicar que se ha detectado el estado en tierra. Luego prendemos el LED rojo. El código espera que el estado cambie de nuevo, por ejemplo, que desconectes el pin conectado a tierra.

Luego, el código recibe las teclas que debe presionar correspondientes al pin manipulado. Si conectaste a tierra y luego desconectaste A1, el código recibe para presionar la tecla de a, y si conectaste a tierra y luego desconectaste A2 el código recibe para presionar el texto de "Hello world!".

Si el código encuentra que ha recibido una cadena de texto, imprime la cadena usando el keyboard_layout para determinar las teclas que debe presionar. De otra forma, el código presiona las teclas de control_key y se presioa "a", lo que resulta en "A". Luego hace una llamada a keyboard.release_all() (para soltar todas las teclas presionadas). ¡Siempre quieres hacer este llamado tan pronto como presionas teclas o te va a ocasionar una tecla pegada que es realmente molesto!

En lugar de utilizar un cable para conectar los pines hacia tierra, puede tratar de cablear los botones como hicimos en Entradas y Salidas Digitales con CircuitPython. ¡Trata de modificar el código para agregar más pines para mayor opción de teclas para presionar!

Emulador de Ratón con CircuitPython

Copie y pegue el código dentro de code.py utilizando su editor preferido y salve el archivo.

import time

import analogio
import board
import digitalio
import usb_hid
from adafruit_hid.mouse import Mouse

mouse = Mouse(usb_hid.devices)

x_axis = analogio.AnalogIn(board.A0)
y_axis = analogio.AnalogIn(board.A1)
select = digitalio.DigitalInOut(board.A2)
select.direction = digitalio.Direction.INPUT
select.pull = digitalio.Pull.UP

pot_min = 0.00
pot_max = 3.29
step = (pot_max - pot_min) / 20.0


def get_voltage(pin):
    return (pin.value * 3.3) / 65536


def steps(axis):
    """ Maps the potentiometer voltage range to 0-20 """
    return round((axis - pot_min) / step)


while True:
    x = get_voltage(x_axis)
    y = get_voltage(y_axis)

    if select.value is False:
        mouse.click(Mouse.LEFT_BUTTON)
        time.sleep(0.2)  # Debounce delay

    if steps(x) > 11.0:
        # print(steps(x))
        mouse.move(x=1)
    if steps(x) < 9.0:
        # print(steps(x))
        mouse.move(x=-1)

    if steps(x) > 19.0:
        # print(steps(x))
        mouse.move(x=8)
    if steps(x) < 1.0:
        # print(steps(x))
        mouse.move(x=-8)

    if steps(y) > 11.0:
        # print(steps(y))
        mouse.move(y=-1)
    if steps(y) < 9.0:
        # print(steps(y))
        mouse.move(y=1)

    if steps(y) > 19.0:
        # print(steps(y))
        mouse.move(y=-8)
    if steps(y) < 1.0:
        # print(steps(y))
        mouse.move(y=8)

Para este ejemplo, hemos conectado un joystick de pulgar de 2 ejes con botón de selección. Usamos esto para emular el movimiento de un ratón y para realizar un click izquierdo. Para cablear este joystick:

  • Conecte VCC en el joystick a 3V de tu tarjeta. Conecte tierra a tierra (GND).
  • Conecte Xout en el joystick al pin A0 de tu tarjeta.
  • Conecte Yout en el joystick al pin A1 de tu tarjeta.
  • Conecte Sel en el joystick al pin A2 de tu tarjeta.

Recuerda, en las Trinket los pines están etiquetados de forma diferente. Revisa la  página de pines para las Trinket para verificar tu cableado.

Para utilizar esta demostración, simplemente mueva el joystick un poco. El puntero del ratón se va a mover lentamente si mueves el joystick un poco fuera del centro y más rápido si lo alejas más del centro. Presiona hacia abajo el joystick para realizar un click del ratón. ¡Asombroso! Ahora vamos a revisar el código.

Creando los Objetos y las Variables

Primero creamos el objeto mouse o ratón.

Luego, asociamos los ejes con x_axis y y_axis a los pines A0 y A1. Luego asociamos select con A2, lo definimos como una entrada y le asignamos un pull-up.

Los ejes "x" y "y" del joystick funcionan como 2 potenciómetros. Los vamos a usar de forma similar a como lo hicimos en Entradas Analógicas con CircuitPython. Definimos pot_min y pot_max para ser los valores mínimos y máximos que leen los potenciómetros. Asignamos step = (pot_max - pot_min) / 20.0 para usar en la función utilitario.

Utilitarios para Ratón HID en CircuitPython

Primero debemos obtener el voltaje con el utilitario get_voltage() para recibir lecturas correctas de los potenciómetros. ¿Le parece familiar? Aprendimos a utilizarlo en en Entradas Analógicas.

Segundo, tenemos steps(axis). Para usarlo, le damos el eje que vas a leer. Aquí es donde vamos a usar la variable step que asignamos anteriormente. El rango del potenciómetro es de 0-3.29. Esto es un rango pequeño. Es todavía más pequeño con el joystick porque el joystick está en el centro de su rango, 1.66, y la parte positiva o negativa de cada eje está por abajo o encima de este número. Ya que requerimos de umbrales en nuestro código, vamos a mapear el rango de 0-3.29 a números entre 0-20.0 utilizando esta función utilitario. De esta forma podemos simplificar nuestro código y utilizar rangos más grandes para nuestros umbrales en lugar de tratar de entender cambios decimales muy pequeños.

Ciclo Principal

Primero asignamos x y y para leer los voltajes de x_axis y y_axis.

Luego, revisamos si el estado del botón de select es False. Por omisión es True cuando no está presionado, así que si el estado es False, el botón ha sido presionado. Cuando es presionado, envía el comando para realizar un click izquierdo del puntero. time.sleep(0.2) previene que leamos múltiples clicks cuando solo se presionó una vez.

Ahora utilizamos la función de steps() para poner el puntero de nuestro ratón en movimiento. Tenemos unas parejas de if para cada eje. Recuerde que 10 es la posición central dado que la hemos mapeado a un rango de 0-20. Las primeras parejas le dicen a cada eje que si el joystick se mueve un paso fuera del centro (a la izquierda o a la derecha para el eje x y arriba o abajo para el eje y), mueva el puntero del ratón en la dirección apropiada por 1 unidad. Las segundas parejas para cada eje le dicen que si el joystick se mueve lo más lejos del centro como es posible, mueva el puntero del mouse en la dirección apropiada 8 unidades. ¡De esta manera tienes la opción de mover el ratón rápido o despacio!

Para ver cual step (o paso) está el joystick cuando lo mueves, descomenta las líneas con  print removiendo el de las líneas que se vean como # print(steps(x)), y conectando la consola serial para que puedas ver la salida. ¡Considera descomentarlas una a la vez, o vas a terminar con mucha información que tienes que navegar en la pantalla y puede que sea difícil de leer!

Para más detalles revisa la última versión de la documentación en https://circuitpython.readthedocs.io/projects/hid/en/latest/

Almacenamiento en CircuitPython

Las tarjetas CircuitPython aparecen como una unidad de disco USB, permitiéndote editar el código directamente en la tarjeta. Ya hasta estado haciendo esto por un buen rato. Es posible que te hayas preguntado, "¿Puedo escribir datos de CircuitPython hacia la unidad de disco para que funcione para bitácoras de datos (o un datalogger)?" ¡La respuesta es !

Sin embargo, tiene algo de truco. Necesitas agregar un código especial a boot.py, no solo en code.py. Esto es porque hay que definir que el sistema de archivos va a ser de solo lectura cuando necesitas editar el código desde tu computadora, pero lo define para escritura cuando deseas que el núcleo de CircuitPython pueda escribir.

Solo puedes tener edición ya sea desde tu computadora para editar archivos en la unidad de disco CIRCUITPY, o para que CircuitPython escriba. No es posible que ambos escriban al mismo sistema de archivos. (Malas Cosas Van a Suceder, ¡así que no lo permitimos!)

A continuación es como se va a ver tu archivo boot.py. Copia y pega el código hacia boot.py utilizando tu editor preferido. Es posible que tengas que crearlo como un archivo nuevo.

import board
import digitalio
import storage

# For Gemma M0, Trinket M0, Metro M0/M4 Express, ItsyBitsy M0/M4 Express
switch = digitalio.DigitalInOut(board.D2)

# For Feather M0/M4 Express
# switch = digitalio.DigitalInOut(board.D5)

# For Circuit Playground Express, Circuit Playground Bluefruit
# switch = digitalio.DigitalInOut(board.D7)

switch.direction = digitalio.Direction.INPUT
switch.pull = digitalio.Pull.UP

# If the switch pin is connected to ground CircuitPython can write to the drive
storage.remount("/", switch.value)

Para las Gemma M0, Trinket M0, Metro M0 Express, Metro M4 Express, ItsyBitsy M0 Express y ItsyBitsy M4 Express, no es necesario realizar cambios al código inicial.

Para las Feather M0 Express y Feather M4 Express, comente switch = digitalio.DigitalInOut(board.D2), y descomente switch = digitalio.DigitalInOut(board.D5).

Para las Circuit Playground Express y Circuit Playground Bluefruit, comente switch = digitalio.DigitalInOut(board.D2), y descomente switch = digitalio.DigitalInOut(board.D7). Recuerde, D7 es el interruptor integrado, así que no se requieren cables extra o clips de lagarto.

Recuerda: Para "comentar" una línea, le pones un # y un espacio antes. Para "descomentarla", le remueves el # y el espacio al inicio de la línea.

A continuación está el código para tu code.py. Copia y pega el código hacia code.py utilizando tu editor favorito.

import time

import board
import digitalio
import microcontroller

led = digitalio.DigitalInOut(board.D13)
led.switch_to_output()

try:
    with open("/temperature.txt", "a") as fp:
        while True:
            temp = microcontroller.cpu.temperature
            # do the C-to-F conversion here if you would like
            fp.write('{0:f}\n'.format(temp))
            fp.flush()
            led.value = not led.value
            time.sleep(1)
except OSError as e:
    delay = 0.5
    if e.args[0] == 28:
        delay = 0.25
    while True:
        led.value = not led.value
        time.sleep(delay)

Bitácora de Temperatura

La forma en como trabaja boot.py es revisando si el pin que dijiste a la hora de definir el interruptor en tu código, está conectado a tierra. Si lo está, cambia el estado de lectura-escritura del sistema de archivos, de forma que el núcleo de CircuitPython puede comenzar a escribir la temperatura en la tarjeta.

Como ayuda para encontrar los pines correctos, observe los diagramas e información en la sección de Encuentre los Pines de la guía de Entradas y Salidas Digitales con CircuitPython. En lugar de conectar un swtich, vas a conectar el in a tierra directamente con un cable de lagarto o con cables.

boot.py solo se ejecuta cuando el dispositivo inicia, no si recargas la consola serial con ctrl+d o si salvas un archivo. ¡Debes expulsar la unidad de disco USB y luego presionar físicamente el botón de reset!

Una vez que haz copiado los archivos a la tarjeta, la expulsas y desconectas de tu computadora. Si está utilizando una Circuit Playground Express, todo lo que tienes que hacer es asegurarte que el interruptor esté del lado derecho. De otra manera, utilizar clips de lagarto o cables para conectar el pin designado hacia tierra. Ahora, conectar la tarjeta de nuevo a tu computadora.

¡Ya no vas a poder editar código en CIRCUITPY!

El LED rojo debería parpadear una vez por segundo, y vas a ver un nuevo archivo llamado temperature.txt en la unidad de disco CIRCUITPY.

El archivo se actualiza una vez por segundo, pero no vas a ver los datos escribiéndose en vivo. En cambio, cuando estés listo para obtener los datos, expulsa y desconecta tu tarjeta. Para CPX, mueva el interruptor hacia la izquierda, de otra forma desconecte el cable que has conectado hacia tierra. Ahora va a ser posible escribir al sistema de archivos de nuevo, pero no vas a poder grabar datos.

Tenemos una guía más detallada sobre este proyecto disponible aquí: Grabadora de Bitácoras de CPU con CircuitPython. Si te gustaría conocer más detalles, ¡revísela!

Temperatura de CPU en CircuitPython

Hay un sensor de temperatura del CPU integrado en todos los chips ATSAMD21, ATSAMD51 y nRF52840. CircuitPython hace que sea muy sencillo leer datos de este sensor. Esto funciona con las microcontroladoras usadas en las tarjetas de Adafruit para CircuitPython.

Los datos se lee utilizando dos comandos sencillo. Vamos a digitarlos en el REPL. Conecte su tarjeta a la consola serial, y entre al REPL. Luego, ejecute los siguientes comandos en el REPL:

Download: file
import microcontroller
microcontroller.cpu.temperature

¡Listo! Has impreso las temperatura en Celsius al REPL. Tome nota que no es exáctamente la temperatura ambiente y no es super preciso. ¡Pero se le acerca!

Si lo deseas imprimir en Fahrenheit, utilice esta fórmula sencilla: Celsius * (9/5) + 32. Es muy sencillo hacer matemática en CircuitPython. ¡Observa!

Tome nota que el sensor de temperatura integrado en los chips nRF52840 tiene una resolución de 0.25 Celsius, así que si imprimes la temperatura será con incrementos de 0.25 Celsius.

¿Qué Esperar de CircuitPython?

Mientras seguimos desarrollando CircuitPython y crear nuevas versiones, vamos a ir dejando de darle mantenimiento a versiones anteriores. Visite https://circuitpython.org/downloads para descargar la última versión de CircuitPython para su tarjeta. Debe descargar el compilado de Librerías para CircuitPython acorde a su versión de CircuitPython. Favor actualice CircuitPython y luego visite https://circuitpython.org/libraries para descargar la última versión del compilado de librerías.

Siempre Corra la Última Versión de CircuitPython y sus Librerías

Mientras seguimos desarrollando CircuitPython y creando nuevas version, vamos a dejar de darle mantenimiento a versiones anterior. Necesita actualizarse a la última versión de CircuitPython.

Necesita actualizar el compilado de Librerías para CircuitPython acorde a su versión de CircuitPython. Favor actualice CircuitPython y luego descargue la última versión del compilado.

Mientras seguimos sacando nuevas versiones de CircuitPython, vamos a dejar de proveer compilados de librerías que puedes descargar del repositorio de Adafruit CircuitPython Library Bundle. Si debe seguir utilizando una versión anterior, todavía puede descargar la versión apropiada de mpy-cross para su versión particula de CircuitPython del repositorio de CircuitPython y crear sus propios archivos de librería de tipo .mpy. Sin embargo, es mejor actualizar a ambas la última versión de CircuitPython y del compilado de librerías.

Debo seguir usando CircuitPython 3.x o 2.x, ¿donde puedo encontrar librerías compatibles?

Ya no le estamos dando mantenimiento o construyendo compilados de Librerías para CircuitPython 2.x y 3.x. Lo alentamos fuertemente a actualizar CircuitPython a la última versión y a utilizar una  versión actualizada de las librerías. Sin embargo, si por alguna razón no puede actualizar, puede encontrar la última construcción del  compilado de Librerías para 2.x, aquí y la última versión del compilado para 3.x, aquí.

Cambiando entre CircuitPython y Arduino

Muchas de las tarjetas que corren CircuitPython, también corren Arduino. ¿Como me puedo cambiar entre las dos? Cambiar entre CircuitPython y Arduino es muy sencillo.

Si está utilizando Arduino y desea comenzar a utilizar CircuitPython, siga los pasos de Bienvenido a CircuitPython: Instalando CircuitPython.

Si ya está utilizando CircuitPython y desea comenzar a utilizar Arduino, conecte su tarjeta y cargue el sketch de Arduino. Si tiene problemas, puede darle doble click al botón de reset para entrar en modo de bootloader, y luego tratar de subir su sketch. Siempre respalde cualquier archivo que estaba utilizando con CircuitPython, ya que pueden ser borrados.

¡Eso es todo! Es muy sencillo cambiar entre los dos lenguajes.

La Diferencia entre Tarjetas Express y Tarjetas No-Express

Comúnmente hacemos referencia a tarjetas "Express" y a tarjetas "No-Express" cuando hablamos de CircuitPython. ¿Esto que quiere decir?

Express se refiere a que se ha agregado un chip extra para tener un flash de 2MB que te da mayor espacio para CircuitPython y para tu código. Esto significa que puedes incluir más funcionalidad en CircuitPyhon, y que puedes hacer más con tu código en una tarjeta Express de lo que puedes hacer en una tarjeta No-Express.

Las tarjetas Express incluyen a las Circuit Playground Express, ItsyBitsy M0 Express, Feather M0 Express, Metro M0 Express y las Metro M4 Express.

Las tarjetas No-Express incluyen a las Trinket M0, Gemma M0, Feather M0 Basic, y otras variantes de tarjeta M0 No-Express.

Tarjetas No-Express: Gemma y Trinket

CircuitPython corre bien en las Gema M0 y las Trinket M0, pero hay algunas limitaciones.

Poco Espacio en Disco

Como estamos utilizando el flash interno como disco, es compartido con código de ejecución, ¡y es limitado! Solo tenemos como 50KB de espacio.

Sin Audio o NVM

Parte de tener que dar algo de FLASH para usarlo como disco, quiere decir que no nos cabe todo. O sea, no hay capacidades para usar el audio por hardware o al 'eeprom' NVM. Módulos como audioio y bitbangio no se incluyen. Para tener estas capacidades, revise las tarjetas CircuitPlayground Express y otras tarjetas Express.

¡Sin embargo, I2C, UART, toque capacitivo, NeoPixeles, DotStar, PWM, entrada y salida analógica, IO digitales, bitácoras a almacenamiento y HID funcionan! Revise los Esenciales de CircuitPython para ejemplos de todos estos.

Diferencias entre CircuitPython y MicroPython

Para las diferencias entre CircuitPython y MicroPython, revise la documentación de CircuitPython.

Diferencias entre CircuitPython y Python

Python (también conocido como CPython) es el lenguaje en que tanto MicroPython como CircuitPython se basan. Existen muchas similaridades, pero también muchas diferencias. Esta es una lista de algunas de las diferencias.

Librerías de Python

Python es anunciado que tiene "baterías incluidas", que quiere decir que muchas de las librerías estándar vienen incluidas. Desafortunadamente, por razones de espacio, muchas librerías de Python no están disponibles. Así que por ejemplo, mientras nos gustaría poder ejecutar un import numpy, la librería numpy no está disponible. ¡Así que puede que te toque portar código!

Integers en CircuitPython

En las tarjetas no-Express, los números de tipo integer solo pueden tener una longitud de 31 bits. Números de tipo integer de tamaño ilimitado no están soportados. El número positivo más grande que puede ser representado es 230-1, 1073741823, y el número más negativo posible es -230, -1073741824.

Desde CircuitPython 3.0, las tarjetas Express tienen números tipo integer de longitud arbitraria como en Python.

Números de Punto Flotante y Digitos de Precisión para Float en CircuitPython

Los números de punto flotante son de precisión sencilla en CircuitPython (a diferencia de precisión doble como en Python). El número de punto flotante más grande que se puede representar es de +/-3.4e38. La magnitud más pequeña que puede ser representada con precisión completa es +/-1.7e-38, aunque número tan pequeños como +/-5.6e-45 pueden ser representados con precisión reducida.

Los float de CircuitPython tienen 8 bits para el exponente y 22 bits para mantissa (no 24 como los puntos flotantes de precisión sencilla), que es como cinco seis dígitos decimales de precisión.

Diferencias entre MicroPython y Python

Para una lista más detallada entre las diferencias entre CircuitPython y Python, puedes revisar la documentación de MicroPython. Nosotros nos mantenemos actualizados con las versiones estables de MicroPython, así que revise el documento de diferencias en el núcleo, aquí

Librerías para CircuitPython

Tenemos una tonelada de liberías para CircuitPython que pueden ser utilizadas por tarjetas con microcontroladoras o por computadoras de una sola tarjeta como las RaspberryPi. Aquí hay una lista rápida que es generada automáticamente.

Adafruit CircuitPython Libraries

Blinka Reading

Here is a listing of current Adafruit CircuitPython Libraries. There are 236 libraries available.

Drivers:

Helpers:

This guide was first published on Jun 24, 2020. It was last updated on Jun 24, 2020.