|
| 1 | +# SPDX-FileCopyrightText: Copyright (c) 2024 Liz Clark for Adafruit Industries |
| 2 | +# |
| 3 | +# SPDX-License-Identifier: MIT |
| 4 | + |
| 5 | +import board |
| 6 | +import audiocore |
| 7 | +import audiobusio |
| 8 | +import audiomixer |
| 9 | +import pwmio |
| 10 | +from digitalio import DigitalInOut, Direction |
| 11 | +from adafruit_ticks import ticks_ms, ticks_add, ticks_diff |
| 12 | +from adafruit_motor import servo |
| 13 | +import adafruit_vl53l1x |
| 14 | + |
| 15 | +distance_delay = 5 # how often vl53 is read |
| 16 | +servo_delays = [2.0, 1.5, 1.0, 0.5] # servo spin delay |
| 17 | +distances = [400, 200, 100, 50] # in centimeters |
| 18 | +max_audio = 0.5 |
| 19 | +# audio files |
| 20 | +music = audiocore.WaveFile(open("music-loop-3.wav", "rb")) |
| 21 | +fx_1 = audiocore.WaveFile(open("laugh-1.wav", "rb")) |
| 22 | +fx_2 = audiocore.WaveFile(open("laugh-2.wav", "rb")) |
| 23 | +fx_3 = audiocore.WaveFile(open("laugh-3.wav", "rb")) |
| 24 | + |
| 25 | +i2c = board.STEMMA_I2C() |
| 26 | +vl53 = adafruit_vl53l1x.VL53L1X(i2c) |
| 27 | + |
| 28 | +tracks = [music, fx_1, fx_2, fx_3] |
| 29 | +audio = audiobusio.I2SOut(board.I2S_BIT_CLOCK, board.I2S_WORD_SELECT, board.I2S_DATA) |
| 30 | +mixer = audiomixer.Mixer(voice_count=4, sample_rate=22050, channel_count=1, |
| 31 | + bits_per_sample=16, samples_signed=True) |
| 32 | +audio.play(mixer) |
| 33 | +mixer.voice[0].play(tracks[0], loop=True) |
| 34 | +mixer.voice[0].level = 0.0 |
| 35 | + |
| 36 | +# enable external power pin |
| 37 | +# provides power to the external components |
| 38 | +external_power = DigitalInOut(board.EXTERNAL_POWER) |
| 39 | +external_power.direction = Direction.OUTPUT |
| 40 | +external_power.value = True |
| 41 | + |
| 42 | +# servo control |
| 43 | +pwm = pwmio.PWMOut(board.EXTERNAL_SERVO, duty_cycle=2 ** 15, frequency=50) |
| 44 | +servo = servo.ContinuousServo(pwm, min_pulse=750, max_pulse=2250) |
| 45 | + |
| 46 | +vl53.start_ranging() |
| 47 | + |
| 48 | +vl53_clock = ticks_ms() |
| 49 | +vl53_time = distance_delay * 1000 |
| 50 | +servo_clock = ticks_ms() |
| 51 | +servo_time = int(servo_delays[0] * 1000) |
| 52 | +prop_time = False |
| 53 | +servo_throttle = 0 |
| 54 | + |
| 55 | +while True: |
| 56 | + if prop_time: |
| 57 | + if ticks_diff(ticks_ms(), servo_clock) >= servo_time: |
| 58 | + # print(servo_throttle) |
| 59 | + servo.throttle = servo_throttle |
| 60 | + servo_throttle = not servo_throttle |
| 61 | + servo_clock = ticks_add(servo_clock, servo_time) |
| 62 | + if ticks_diff(ticks_ms(), vl53_clock) >= vl53_time: |
| 63 | + if vl53.data_ready: |
| 64 | + # print(f"Distance: {vl53.distance} cm") |
| 65 | + vl53.clear_interrupt() |
| 66 | + closest_distance = min(distances, key=lambda x: abs(vl53.distance - x)) |
| 67 | + # print(closest_distance) |
| 68 | + if vl53.distance <= distances[0]: |
| 69 | + prop_time = True |
| 70 | + mixer.voice[0].level = max_audio |
| 71 | + else: |
| 72 | + prop_time = False |
| 73 | + mixer.voice[0].level = 0.0 |
| 74 | + servo_time = int(servo_delays[0] * 1000) |
| 75 | + if closest_distance == distances[1]: |
| 76 | + mixer.voice[1].play(tracks[1], loop=False) |
| 77 | + servo_time = int(servo_delays[1] * 1000) |
| 78 | + elif closest_distance == distances[2]: |
| 79 | + mixer.voice[2].play(tracks[2], loop=False) |
| 80 | + servo_time = int(servo_delays[2] * 1000) |
| 81 | + elif closest_distance == distances[3]: |
| 82 | + mixer.voice[3].play(tracks[3], loop=False) |
| 83 | + servo_time = int(servo_delays[3] * 1000) |
| 84 | + vl53_clock = ticks_add(vl53_clock, vl53_time) |
0 commit comments