code.py
  1  # SPDX-FileCopyrightText: 2018 Limor Fried for Adafruit Industries
  2  #
  3  # SPDX-License-Identifier: MIT
  4  
  5  import time
  6  import audioio
  7  import audiocore
  8  from digitalio import DigitalInOut, Pull, Direction
  9  from adafruit_seesaw.seesaw import Seesaw
 10  from adafruit_seesaw.pwmout import PWMOut
 11  from adafruit_motor import stepper
 12  from busio import I2C
 13  import neopixel
 14  import board
 15  
 16  # Create seesaw object
 17  i2c = I2C(board.SCL, board.SDA)
 18  seesaw = Seesaw(i2c)
 19  
 20  led = DigitalInOut(board.D13)
 21  led.direction = Direction.OUTPUT
 22  
 23  buttona = DigitalInOut(board.BUTTON_A)
 24  buttona.direction = Direction.INPUT
 25  buttona.pull = Pull.DOWN
 26  
 27  buttonb = DigitalInOut(board.BUTTON_B)
 28  buttonb.direction = Direction.INPUT
 29  buttonb.pull = Pull.DOWN
 30  
 31  BOTTOM_SENSOR = 2
 32  TOP_SENSOR = 3
 33  seesaw.pin_mode(BOTTOM_SENSOR, seesaw.INPUT_PULLUP)
 34  seesaw.pin_mode(TOP_SENSOR, seesaw.INPUT_PULLUP)
 35  
 36  # Create one stepper motor using the 4 'drive' PWM pins 13, 43, 12 and 42
 37  pwms = [PWMOut(seesaw, 13), PWMOut(seesaw, 43), PWMOut(seesaw, 12), PWMOut(seesaw, 42)]
 38  for p in pwms:
 39      p.frequency = 2000
 40  stepper_motor = stepper.StepperMotor(pwms[0], pwms[1], pwms[2], pwms[3])
 41  
 42  pixels = neopixel.NeoPixel(board.NEOPIXEL, 10, brightness=1)
 43  pixels.fill((0,0,0))
 44  
 45  
 46  def rainbow():
 47      pixels.fill((20,0,0))
 48      time.sleep(0.05)
 49      pixels.fill((20,20,0))
 50      time.sleep(0.05)
 51      pixels.fill((0,20,0))
 52      time.sleep(0.05)
 53      pixels.fill((0,20,20))
 54      time.sleep(0.05)
 55      pixels.fill((0,0,20))
 56      time.sleep(0.05)
 57      pixels.fill((20,0,20))
 58      time.sleep(0.05)
 59  
 60  # Audio playback object and helper to play a full file
 61  a = audioio.AudioOut(board.A0)
 62  def play_file(wavfile):
 63      with open(wavfile, "rb") as file:
 64          wavf = audiocore.WaveFile(file)
 65          a.play(wavf)
 66          while a.playing:
 67              rainbow()
 68  
 69  
 70  last_b_time = last_a_time = 0
 71  steps = speed = 0
 72  MINIMUM_SPEED = 1  # in taps per second
 73  drift_counter = 0
 74  TOUCH_THRESH = 900
 75  won = False
 76  
 77  def reset():
 78      print("Resetting..", end="")
 79      while seesaw.digital_read(BOTTOM_SENSOR):
 80          stepper_motor.onestep(direction=stepper.BACKWARD, style=stepper.DOUBLE)
 81      print("Done!")
 82  
 83  print("Racooon crawl!")
 84  
 85  reset()
 86  paused = False
 87  
 88  while True:
 89      # pause button B
 90      if buttonb.value:
 91          while buttonb.value:
 92              pass
 93          paused = not paused
 94  
 95      # reset button A
 96      if buttona.value:
 97          while buttona.value:
 98              pass
 99          pixels.fill((0, 0, 0))
100          reset()
101  
102      if not seesaw.digital_read(TOP_SENSOR):
103          play_file("madeit.wav")
104          for i in range(20):
105              rainbow()
106          reset()
107      #print(seesaw.touch_read(0))
108      #print(seesaw.touch_read(3))
109      if seesaw.touch_read(0) > TOUCH_THRESH:
110          while seesaw.touch_read(0) > TOUCH_THRESH:
111              pass
112          last_a_time = time.monotonic()
113  
114      if seesaw.touch_read(3) > TOUCH_THRESH:
115          while seesaw.touch_read(3) > TOUCH_THRESH:
116              pass
117          last_b_time = time.monotonic()
118  
119      delta_a = time.monotonic() - last_a_time
120      delta_b = time.monotonic() - last_b_time
121      #print("Lately... %0.1f & %0.1f" % (delta_a, delta_b))
122  
123      speed = 1.0 / max(delta_a, delta_b)
124      print("Speed %0.1f\tSteps %d" % (speed, steps))
125      if speed > MINIMUM_SPEED:
126          # Climb up
127          pixels.fill((0, int(speed*10), 0))
128          for i in range(6):
129              stepper_motor.onestep(direction=stepper.FORWARD, style=stepper.DOUBLE)
130              steps += 1
131      elif not paused:
132          # Fall down
133          pixels.fill((50, 0, 0))
134          if seesaw.digital_read(BOTTOM_SENSOR):
135              stepper_motor.onestep(direction=stepper.BACKWARD)
136              steps -= 1