/ Motion_Buddy / code.py
code.py
1 # SPDX-FileCopyrightText: 2022 Charlyn G for Adafruit Industries 2 # 3 # SPDX-License-Identifier: MIT 4 # 5 # Code for the Adafruit Learning System tutorial 6 # Exercise Buddy: Motion aware BLE media controller 7 # https://learn.adafruit.com/exercise-buddy/overview 8 # 9 import time 10 import board 11 import supervisor 12 13 import neopixel 14 import adafruit_ble 15 import adafruit_lis3dh 16 from adafruit_ble.advertising.standard import SolicitServicesAdvertisement 17 from adafruit_ble_apple_media import AppleMediaService, UnsupportedCommand 18 19 # Initialize the accelerometer 20 i2c = board.I2C() 21 lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c) 22 23 # Initialize BLE radio 24 radio = adafruit_ble.BLERadio() 25 a = SolicitServicesAdvertisement() 26 a.solicited_services.append(AppleMediaService) 27 radio.start_advertising(a) 28 29 # Neopixel indicator 30 pixel_pin = board.NEOPIXEL 31 pixel = neopixel.NeoPixel(pixel_pin, 1, brightness=0.5) 32 YELLOW = (200, 150, 0) 33 CYAN = (0, 100, 100) 34 PINK = (231, 84, 128) 35 pixel.fill(PINK) 36 37 while not radio.connected: 38 pass 39 40 print("connected") 41 pixel.fill(YELLOW) 42 43 # Initialize variables 44 last_x = 0 45 last_y = 0 46 last_z = 0 47 paused = True 48 49 WAIT = 0.2 50 WIGGLE_ROOM = 5 # Increase this for more jitter compensation. 51 52 53 def is_same_pos(last_position, current_position): 54 # Returns true if current_position is similar enough 55 # to last_position, within the specified wiggle room. 56 diff = abs(current_position - last_position) 57 print((diff,)) 58 return diff <= WIGGLE_ROOM 59 60 61 def not_enough_movement(x, y, z): 62 same_x = is_same_pos(last_x, x) 63 same_y = is_same_pos(last_y, y) 64 same_z = is_same_pos(last_z, z) 65 return same_x and same_y and same_z 66 67 68 while radio.connected: 69 70 for connection in radio.connections: 71 if not connection.paired: 72 connection.pair() 73 print("paired") 74 pixel.fill(PINK) 75 time.sleep(1) 76 77 if connection.paired: 78 pixel.fill(CYAN) 79 ams = connection[AppleMediaService] 80 print("app:", ams.player_name) 81 82 try: 83 xf, yf, zf = lis3dh.acceleration 84 85 if not_enough_movement(xf, yf, zf): 86 # Keep pausing. 87 print("pause!") 88 paused = True 89 ams.pause() 90 91 else: 92 last_x = xf 93 last_y = yf 94 last_z = zf 95 96 if paused: 97 print("play!") 98 paused = False 99 ams.play() 100 101 except OSError: 102 supervisor.reload() 103 except UnsupportedCommand: 104 # This means that we tried to pause but there's 105 # probably nothing playing yet, so just wait a bit 106 # and try again. 107 pixel.fill(PINK) 108 time.sleep(10) 109 supervisor.reload() 110 111 time.sleep(WAIT) 112 113 print("disconnected") 114 pixel.fill(PINK)