code.py
  1  # SPDX-FileCopyrightText: 2020 FoamyGuy for Adafruit Industries
  2  #
  3  # SPDX-License-Identifier: MIT
  4  
  5  """
  6  This example script shows the usage of servos, LEDs, and buttons all
  7  used simultaneously without interrupting each other.
  8  """
  9  
 10  import time
 11  import board
 12  import digitalio
 13  import neopixel
 14  import pwmio
 15  from adafruit_motor import servo
 16  from digitalio import DigitalInOut, Direction, Pull
 17  
 18  btn = DigitalInOut(board.SWITCH)
 19  btn.direction = Direction.INPUT
 20  btn.pull = Pull.UP
 21  
 22  prev_state = btn.value
 23  
 24  pixels = neopixel.NeoPixel(board.NEOPIXEL, 1)
 25  pixels[0] = (0, 0, 0)
 26  
 27  BLINK_LIST = [
 28      {
 29          "ON": 0.5,
 30          "OFF": 0.5,
 31          "PREV_TIME": -1,
 32          "PIN": board.D5,
 33      },
 34      {
 35          "ON": 0.5,
 36          "OFF": 0.5,
 37          "PREV_TIME": -1,
 38          "PIN": board.D6,
 39      },
 40      {
 41          "ON": 0.5,
 42          "OFF": 0.5,
 43          "PREV_TIME": -1,
 44          "PIN": board.D9,
 45      },
 46      {
 47          "ON": 0.5,
 48          "OFF": 0.5,
 49          "PREV_TIME": -1,
 50          "PIN": board.D10,
 51      }
 52  ]
 53  
 54  SERVO_LIST = [
 55      {
 56          "MAX_ANGLE": 180,
 57          "MIN_ANGLE": 0,
 58          "PREV_TIME": -1,
 59          "PIN": board.A1,
 60          "DELAY_BETWEEN": 0.05,
 61          "SERVO": None,
 62          "MOVE_BY": 5
 63      },
 64      {
 65          "MAX_ANGLE": 90,
 66          "MIN_ANGLE": 0,
 67          "PREV_TIME": -1,
 68          "PIN": board.A3,
 69          "DELAY_BETWEEN": 0.02,
 70          "SERVO": None,
 71          "MOVE_BY": 2
 72      }
 73  ]
 74  
 75  for cur_servo in SERVO_LIST:
 76      pwm = pwmio.PWMOut(cur_servo["PIN"], duty_cycle=2 ** 15, frequency=50)
 77      # Create a servo object.
 78      cur_servo["SERVO"] = servo.Servo(pwm)
 79  
 80  
 81  for led in BLINK_LIST:
 82      led["PIN"] = digitalio.DigitalInOut(led["PIN"])
 83      led["PIN"].direction = digitalio.Direction.OUTPUT
 84  
 85  disabled_leds = []
 86  # temporarily remove first two from the blink list
 87  disabled_leds.append(BLINK_LIST.pop(0))
 88  disabled_leds.append(BLINK_LIST.pop(0))
 89  while True:
 90      # Store the current time to refer to later.
 91      now = time.monotonic()
 92  
 93      cur_state = btn.value
 94      if cur_state != prev_state:
 95          if not cur_state:
 96              print("BTN is down")
 97  
 98              # swap the LED Blink patterns to the opposite pairs of LEDs
 99              temp = []
100              temp.append(BLINK_LIST.pop(0))
101              temp.append(BLINK_LIST.pop(0))
102  
103              BLINK_LIST.append(disabled_leds.pop(0))
104              BLINK_LIST.append(disabled_leds.pop(0))
105  
106              disabled_leds.append(temp.pop(0))
107              disabled_leds.append(temp.pop(0))
108  
109          else:
110              print("BTN is up")
111  
112      prev_state = cur_state
113  
114      for led in BLINK_LIST:
115          if led["PIN"].value is False:
116              if now >= led["PREV_TIME"] + led["OFF"]:
117                  led["PREV_TIME"] = now
118                  led["PIN"].value = True
119          if led["PIN"].value is True:
120              if now >= led["PREV_TIME"] + led["ON"]:
121                  led["PREV_TIME"] = now
122                  led["PIN"].value = False
123  
124      for servo in SERVO_LIST:
125          if now >= servo["PREV_TIME"] + servo["DELAY_BETWEEN"]:
126              try:
127                  servo["SERVO"].angle += servo["MOVE_BY"]
128              except ValueError as e:
129  
130                  if servo["MOVE_BY"] > 0:
131                      servo["SERVO"].angle = servo["MAX_ANGLE"]
132                  else:
133                      servo["SERVO"].angle = servo["MIN_ANGLE"]
134  
135              if servo["SERVO"].angle >= servo["MAX_ANGLE"] or \
136                  servo["SERVO"].angle <= servo["MIN_ANGLE"]:
137  
138                  servo["MOVE_BY"] = -servo["MOVE_BY"]
139  
140              servo["PREV_TIME"] = now