Merge pull request #1262 from FoamyGuy/multitasking_with_circuitpython

adding multitasking with circuitpython files
This commit is contained in:
Limor "Ladyada" Fried 2020-10-05 13:09:02 -04:00 committed by GitHub
commit acbe731c8c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 455 additions and 0 deletions

View file

@ -0,0 +1,136 @@
"""
This example script shows the usage of servos, LEDs, and buttons all
used simultaneously without interrupting each other.
"""
import board
import digitalio
import time
import neopixel
import pulseio
from adafruit_motor import servo
from digitalio import DigitalInOut, Direction, Pull
btn = DigitalInOut(board.SWITCH)
btn.direction = Direction.INPUT
btn.pull = Pull.UP
prev_state = btn.value
pixels = neopixel.NeoPixel(board.NEOPIXEL, 1)
pixels[0] = (0, 0, 0)
BLINK_LIST = [
{
"ON": 0.5,
"OFF": 0.5,
"PREV_TIME": -1,
"PIN": board.D5,
},
{
"ON": 0.5,
"OFF": 0.5,
"PREV_TIME": -1,
"PIN": board.D6,
},
{
"ON": 0.5,
"OFF": 0.5,
"PREV_TIME": -1,
"PIN": board.D9,
},
{
"ON": 0.5,
"OFF": 0.5,
"PREV_TIME": -1,
"PIN": board.D10,
}
]
SERVO_LIST = [
{
"MAX_ANGLE": 180,
"MIN_ANGLE": 0,
"PREV_TIME": -1,
"PIN": board.A1,
"DELAY_BETWEEN": 0.05,
"SERVO": None,
"MOVE_BY": 5
},
{
"MAX_ANGLE": 90,
"MIN_ANGLE": 0,
"PREV_TIME": -1,
"PIN": board.A3,
"DELAY_BETWEEN": 0.02,
"SERVO": None,
"MOVE_BY": 2
}
]
for cur_servo in SERVO_LIST:
pwm = pulseio.PWMOut(cur_servo["PIN"], duty_cycle=2 ** 15, frequency=50)
# Create a servo object.
cur_servo["SERVO"] = servo.Servo(pwm)
for led in BLINK_LIST:
led["PIN"] = digitalio.DigitalInOut(led["PIN"])
led["PIN"].direction = digitalio.Direction.OUTPUT
disabled_leds = []
# temporarily remove first two from the blink list
disabled_leds.append(BLINK_LIST.pop(0))
disabled_leds.append(BLINK_LIST.pop(0))
while True:
# Store the current time to refer to later.
now = time.monotonic()
cur_state = btn.value
if cur_state != prev_state:
if not cur_state:
print("BTN is down")
# swap the LED Blink patterns to the opposite pairs of LEDs
temp = []
temp.append(BLINK_LIST.pop(0))
temp.append(BLINK_LIST.pop(0))
BLINK_LIST.append(disabled_leds.pop(0))
BLINK_LIST.append(disabled_leds.pop(0))
disabled_leds.append(temp.pop(0))
disabled_leds.append(temp.pop(0))
else:
print("BTN is up")
prev_state = cur_state
for led in BLINK_LIST:
if led["PIN"].value == False:
if now >= led["PREV_TIME"] + led["OFF"]:
led["PREV_TIME"] = now
led["PIN"].value = True
if led["PIN"].value == True:
if now >= led["PREV_TIME"] + led["ON"]:
led["PREV_TIME"] = now
led["PIN"].value = False
for servo in SERVO_LIST:
if now >= servo["PREV_TIME"] + servo["DELAY_BETWEEN"]:
try:
servo["SERVO"].angle += servo["MOVE_BY"]
except ValueError as e:
if servo["MOVE_BY"] > 0:
servo["SERVO"].angle = servo["MAX_ANGLE"]
else:
servo["SERVO"].angle = servo["MIN_ANGLE"]
if servo["SERVO"].angle >= servo["MAX_ANGLE"] or \
servo["SERVO"].angle <= servo["MIN_ANGLE"]:
servo["MOVE_BY"] = -servo["MOVE_BY"]
servo["PREV_TIME"] = now

View file

@ -0,0 +1,96 @@
"""
This example script shows the usage of servos, and LEDs
used simultaneously without interrupting each other.
"""
import board
import digitalio
import time
import neopixel
import pulseio
from adafruit_motor import servo
pixels = neopixel.NeoPixel(board.NEOPIXEL, 1)
pixels[0] = (0, 0, 0)
BLINK_LIST = [
{
"ON": 0.25,
"OFF": 0.25,
"PREV_TIME": -1,
"PIN": board.D5,
},
{
"ON": 0.5,
"OFF": 0.5,
"PREV_TIME": -1,
"PIN": board.D6,
},
{
"ON": 1.0,
"OFF": 1.0,
"PREV_TIME": -1,
"PIN": board.D9,
},
{
"ON": 2.0,
"OFF": 2.0,
"PREV_TIME": -1,
"PIN": board.D10,
}
]
SERVO_LIST = [
{
"MAX_ANGLE": 180,
"MIN_ANGLE": 0,
"PREV_TIME": -1,
"PIN": board.A1,
"DELAY_BETWEEN": 0.05,
"SERVO": None,
"MOVE_BY": 5
}
]
for cur_servo in SERVO_LIST:
pwm = pulseio.PWMOut(cur_servo["PIN"], duty_cycle=2 ** 15, frequency=50)
# Create a servo object.
cur_servo["SERVO"] = servo.Servo(pwm)
for led in BLINK_LIST:
led["PIN"] = digitalio.DigitalInOut(led["PIN"])
led["PIN"].direction = digitalio.Direction.OUTPUT
while True:
# Store the current time to refer to later.
now = time.monotonic()
for led in BLINK_LIST:
if led["PIN"].value == False:
if now >= led["PREV_TIME"] + led["OFF"]:
led["PREV_TIME"] = now
led["PIN"].value = True
if led["PIN"].value == True:
if now >= led["PREV_TIME"] + led["ON"]:
led["PREV_TIME"] = now
led["PIN"].value = False
for servo in SERVO_LIST:
if now >= servo["PREV_TIME"] + servo["DELAY_BETWEEN"]:
try:
servo["SERVO"].angle += servo["MOVE_BY"]
except ValueError as e:
if servo["MOVE_BY"] > 0:
servo["SERVO"].angle = servo["MAX_ANGLE"]
else:
servo["SERVO"].angle = servo["MIN_ANGLE"]
if servo["SERVO"].angle >= servo["MAX_ANGLE"] or \
servo["SERVO"].angle <= servo["MIN_ANGLE"]:
servo["MOVE_BY"] = -servo["MOVE_BY"]
servo["PREV_TIME"] = now

View file

@ -0,0 +1,35 @@
"""
Using time.monotonic() to blink the built-in LED.
Instead of "wait until" think "Is it time yet?"
"""
import time
import digitalio
import board
# How long we want the LED to stay on
BLINK_ON_DURATION = 0.5
# How long we want the LED to stay off
BLINK_OFF_DURATION = 0.25
# When we last changed the LED state
LAST_BLINK_TIME = -1
# Setup the LED pin.
led = digitalio.DigitalInOut(board.D13)
led.direction = digitalio.Direction.OUTPUT
while True:
# Store the current time to refer to later.
now = time.monotonic()
if not led.value:
# Is it time to turn on?
if now >= LAST_BLINK_TIME + BLINK_OFF_DURATION:
led.value = True
LAST_BLINK_TIME = now
if led.value:
# Is it time to turn off?
if now >= LAST_BLINK_TIME + BLINK_ON_DURATION:
led.value = False
LAST_BLINK_TIME = now

View file

@ -0,0 +1,23 @@
"""
This example script shows how to read button state with
debouncing that does not rely on time.sleep().
"""
import board
from digitalio import DigitalInOut, Direction, Pull
btn = DigitalInOut(board.SWITCH)
btn.direction = Direction.INPUT
btn.pull = Pull.UP
prev_state = btn.value
while True:
cur_state = btn.value
if cur_state != prev_state:
if not cur_state:
print("BTN is down")
else:
print("BTN is up")
prev_state = cur_state

View file

@ -0,0 +1,53 @@
"""
This example script shows how to blink multiple LEDs at different
rates simultaneously without each affecting the others.
"""
import board
import digitalio
import time
BLINK_LIST = [
{
"ON": 0.25,
"OFF": 0.25,
"PREV_TIME": -1,
"PIN": board.D5,
},
{
"ON": 0.5,
"OFF": 0.5,
"PREV_TIME": -1,
"PIN": board.D6,
},
{
"ON": 1.0,
"OFF": 1.0,
"PREV_TIME": -1,
"PIN": board.D9,
},
{
"ON": 2.0,
"OFF": 2.0,
"PREV_TIME": -1,
"PIN": board.D10,
}
]
for led in BLINK_LIST:
led["PIN"] = digitalio.DigitalInOut(led["PIN"])
led["PIN"].direction = digitalio.Direction.OUTPUT
while True:
# Store the current time to refer to later.
now = time.monotonic()
for led in BLINK_LIST:
if led["PIN"].value == False:
if now >= led["PREV_TIME"] + led["OFF"]:
led["PREV_TIME"] = now
led["PIN"].value = True
if led["PIN"].value == True:
if now >= led["PREV_TIME"] + led["ON"]:
led["PREV_TIME"] = now
led["PIN"].value = False

View file

@ -0,0 +1,60 @@
"""
Blinking multiple LEDs at different rates.
Circuit Playground Neopixels.
"""
import time
import digitalio
import board
from adafruit_circuitplayground import cp
BLINK_MAP = {
"RED": {
"ON": 0.25,
"OFF": 0.25,
"PREV_TIME": -1,
"INDEX": 1,
"COLOR": (255, 0, 0)
},
"GREEN": {
"ON": 0.5,
"OFF": 0.5,
"PREV_TIME": -1,
"INDEX": 3,
"COLOR": (0, 255, 0)
},
"BLUE": {
"ON": 1.0,
"OFF": 1.0,
"PREV_TIME": -1,
"INDEX": 6,
"COLOR": (0, 0, 255)
},
"YELLOW": {
"ON": 2.0,
"OFF": 2.0,
"PREV_TIME": -1,
"INDEX": 8,
"COLOR": (255, 255, 0)
}
}
cp.pixels.brightness = 0.02
while True:
# Store the current time to refer to later.
now = time.monotonic()
for color in BLINK_MAP.keys():
# Is LED currently OFF?
if cp.pixels[BLINK_MAP[color]["INDEX"]] == (0, 0, 0):
# Is it time to turn ON?
if now >= BLINK_MAP[color]["PREV_TIME"] + BLINK_MAP[color]["OFF"]:
cp.pixels[BLINK_MAP[color]["INDEX"]] = BLINK_MAP[color]["COLOR"]
BLINK_MAP[color]["PREV_TIME"] = now
else: # LED is ON:
# Is it time to turn OFF?
if now >= BLINK_MAP[color]["PREV_TIME"] + BLINK_MAP[color]["ON"]:
cp.pixels[BLINK_MAP[color]["INDEX"]] = (0, 0, 0)
BLINK_MAP[color]["PREV_TIME"] = now

View file

@ -0,0 +1,49 @@
"""
This example script shows how to sweep servo(s) without using
time.sleep().
"""
import board
import digitalio
import time
import pulseio
from adafruit_motor import servo
SERVO_LIST = [
{
"MAX_ANGLE": 180,
"MIN_ANGLE": 0,
"PREV_TIME": -1,
"PIN": board.A1,
"DELAY_BETWEEN": 0.05,
"SERVO": None,
"MOVE_BY": 5
}
]
for cur_servo in SERVO_LIST:
pwm = pulseio.PWMOut(cur_servo["PIN"], duty_cycle=2 ** 15, frequency=50)
# Create a servo object.
cur_servo["SERVO"] = servo.Servo(pwm)
while True:
# Store the current time to refer to later.
now = time.monotonic()
for servo in SERVO_LIST:
if now >= servo["PREV_TIME"] + servo["DELAY_BETWEEN"]:
try:
servo["SERVO"].angle += servo["MOVE_BY"]
except ValueError as e:
if servo["MOVE_BY"] > 0:
servo["SERVO"].angle = servo["MAX_ANGLE"]
else:
servo["SERVO"].angle = servo["MIN_ANGLE"]
if servo["SERVO"].angle >= servo["MAX_ANGLE"] or \
servo["SERVO"].angle <= servo["MIN_ANGLE"]:
servo["MOVE_BY"] = -servo["MOVE_BY"]
servo["PREV_TIME"] = now

View file

@ -0,0 +1,3 @@
Multitasking With CircuitPython:
https://learn.adafruit.com/multi-tasking-with-circuitpython/