We've created this fairly simple program that allows your CPB to connect to an iOS device, Pair and Bond (so they'll auto-reconnect later), and send data between the two devices to display track info and playback commands.
Libraries
First, make sure you have these libraries that you copied over to the board following this guide page
- adafruit_ble
- adafruit_bus_device
- adafruit_circuitplayground
- adafruit_lis3dh.mpy
- adafruit_st7789.mpy
- adafruit_thermistor.mpy
- neopixel.mpy
Then, we'll also add some libraries for dealing with the Apple Media Service, the TFT display, and the Circuit Playground buttons and switch.
From the library bundle you downloaded in that guide page, transfer the following library onto the CPB boards' /lib directory:
- adafruit_bitmap_font
- adafruit_display_shapes
- adafruit_display_text
- adafruit_gizmo
- adafruit_ble_apple_media.mpy
Your CBP should look like the screenshot above.
You'll also need to get the fonts and .bmp images for the project. Click the "Download: Project Zip" link in the code block below to get all the files from the project's GitHub repo.
Then, uncompress the zip file and open the code.py file in Mu, then save it to your CPB's CIRCUITPY drive as code.py.
Text Editor
Adafruit recommends using the Mu editor for using your CircuitPython code with the Circuit Playground Bluefruit boards. You can get more info in this guide.
Alternatively, you can use any text editor that saves files.
# SPDX-FileCopyrightText: 2020 Melissa LeBlanc-Williams for Adafruit Industries # # SPDX-License-Identifier: MIT """ This example solicits that apple devices that provide notifications connect to it, initiates pairing, prints existing notifications and then prints any new ones as they arrive. """ import time import displayio import terminalio from adafruit_gizmo import tft_gizmo from adafruit_display_text.label import Label from adafruit_display_shapes.rect import Rect from adafruit_bitmap_font import bitmap_font import adafruit_ble from adafruit_ble.advertising.standard import SolicitServicesAdvertisement from adafruit_ble_apple_media import AppleMediaService from adafruit_ble_apple_media import UnsupportedCommand from adafruit_circuitplayground import cp BACKGROUND_COLOR = 0x49523b # Gray TEXT_COLOR = 0xFF0000 # Red BORDER_COLOR = 0xAAAAAA # Light Gray STATUS_COLOR = BORDER_COLOR # PyLint can't find BLERadio for some reason so special case it here. radio = adafruit_ble.BLERadio() # pylint: disable=no-member radio.name = "Now Playing Gizmo" a = SolicitServicesAdvertisement() a.solicited_services.append(AppleMediaService) radio.start_advertising(a) def wrap_in_tilegrid(filename:str): # CircuitPython 6 & 7 compatible odb = displayio.OnDiskBitmap(open(filename, "rb")) return displayio.TileGrid( odb, pixel_shader=getattr(odb, 'pixel_shader', displayio.ColorConverter()) ) # # CircuitPython 7+ compatible # odb = displayio.OnDiskBitmap(filename) # return displayio.TileGrid(odb, pixel_shader=odb.pixel_shader) def make_background(width, height, color): color_bitmap = displayio.Bitmap(width, height, 1) color_palette = displayio.Palette(1) color_palette[0] = color return displayio.TileGrid(color_bitmap, pixel_shader=color_palette, x=0, y=0) def load_font(fontname, text): font = bitmap_font.load_font(fontname) font.load_glyphs(text.encode('utf-8')) return font def make_label(text, x, y, color, font=terminalio.FONT): if isinstance(font, str): font = load_font(font, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.,?()") text_area = Label(font, text=text, color=color) text_area.x = x text_area.y = y return text_area def set_label(label, value, max_length): text = "{}".format(value) if len(text) > max_length: text = text[:max_length-3] + "..." label.text = text def set_status(label, action_text, player): label.text = "{} on {}".format(action_text, player) _, _, label_width, _ = label.bounding_box label.x = display.width - 10 - label_width display = tft_gizmo.TFT_Gizmo() group = displayio.Group() display.root_group = group while True: if not radio.connected: group.append(wrap_in_tilegrid("/graphic_tfts_ams_connect.bmp")) while not radio.connected: pass group.pop() print("connected") known_notifications = set() # Draw the text fields print("Loading Font Glyphs...") group.append(wrap_in_tilegrid("/graphic_tfts_ams_loading.bmp")) title_label = make_label("None", 12, 30, TEXT_COLOR, font="/fonts/Arial-Bold-18.bdf") artist_label = make_label("None", 12, 70, TEXT_COLOR, font="/fonts/Arial-16.bdf") album_label = make_label("None", 12, 184, TEXT_COLOR, font="/fonts/Arial-16.bdf") status_label = make_label("None", 80, 220, STATUS_COLOR, font="/fonts/Arial-16.bdf") group.pop() group.append(make_background(240, 240, BACKGROUND_COLOR)) border = Rect(4, 4, 232, 200, outline=BORDER_COLOR, stroke=2) group.append(title_label) group.append(artist_label) group.append(album_label) group.append(status_label) group.append(border) while radio.connected: for connection in radio.connections: try: if not connection.paired: connection.pair() print("paired") ams = connection[AppleMediaService] except (RuntimeError, UnsupportedCommand, AttributeError): # Skip Bad Packets, unknown commands, etc. continue set_label(title_label, ams.title, 18) set_label(album_label, ams.album, 21) set_label(artist_label, ams.artist, 21) action = "?" if ams.playing: action = "Playing" elif ams.paused: action = "Paused" set_status(status_label, action, ams.player_name) if cp.button_a: ams.toggle_play_pause() time.sleep(0.1) if cp.button_b: if cp.switch: ams.previous_track() else: ams.next_track() time.sleep(0.1) print("disconnected") # Remove all layers while len(group): group.pop()
Text editor powered by tinymce.