Adafruit_Learning_System_Gu.../Raspberry_Pi_PiPyPirate_Radio/radio.py
2023-05-17 12:13:07 -07:00

141 lines
3.6 KiB
Python
Executable file

# SPDX-FileCopyrightText: 2023 Carter N. for Adafruit Industries
# SPDX-License-Identifier: MIT
import time
import board
import digitalio
import adafruit_si4713
from PIL import Image, ImageDraw, ImageFont
from adafruit_rgb_display import st7789
import mpd
#--| User Config |-----------------------------------
FREQ = 89.00
PLAYLIST = "test"
STATION_NAME = "PiPyPirate Radio"
UPDATE_RATE = 0.5
#----------------------------------------------------
#==| SETUP |=========================================================
# Display
disp = st7789.ST7789(
board.SPI(),
height=240,
y_offset=80,
rotation=180,
cs=digitalio.DigitalInOut(board.CE0),
dc=digitalio.DigitalInOut(board.D25),
rst=digitalio.DigitalInOut(board.D24),
baudrate=64000000,
)
backlight = digitalio.DigitalInOut(board.D22)
backlight.switch_to_output()
backlight.value = True
background = Image.open("radio_bg.png")
STAT_FNT = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSansCondensed-Bold.ttf", 55)
STAT_CLR = (30, 100, 200)
INFO_FNT = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 20)
ARTS_CLR = (0, 100, 0)
ALBM_CLR = (0, 100, 0)
TITL_CLR = (0, 100, 0)
PROG_CLR = (0, 100, 0)
# Buttons
button1 = digitalio.DigitalInOut(board.D23)
button1.switch_to_input(pull=digitalio.Pull.UP)
button2 = digitalio.DigitalInOut(board.D24)
button2.switch_to_input(pull=digitalio.Pull.UP)
# Radio
radio = adafruit_si4713.SI4713(
board.I2C(),
reset=digitalio.DigitalInOut(board.D26),
timeout_s = 0.5
)
radio.tx_frequency_khz = int(FREQ * 1000)
radio.tx_power = 115
radio.configure_rds(0xADAF, station=STATION_NAME.encode())
# MPD
mpc = mpd.MPDClient()
mpc.connect("localhost", 6600)
mpc.stop()
mpc.clear()
mpc.load(PLAYLIST)
mpc.play()
mpc.repeat(1)
#====================================================================
def button1_handler():
if status['state'] == 'play':
mpc.pause()
else:
mpc.play()
def button2_handler():
mpc.next()
def update_display():
image = background.copy()
draw = ImageDraw.Draw(image)
draw.text(
(150, 20),
"{:>5.1f}".format(FREQ),
anchor="mt",
font=STAT_FNT,
fill=STAT_CLR
)
if status['state'] == 'play':
r = 10 * (1 + int(time.monotonic() % 3))
draw.arc( (30-r, 20-r, 30+r, 20+r),
120, 60,
fill = (0, 0, 0),
width = 3
)
info = mpc.currentsong()
artist = info.get('artist', 'unknown')
album = info.get('album', 'unknown')
song = info.get('title', 'unknown')
draw.text( (5, 150), artist, font=INFO_FNT, fill=ARTS_CLR )
draw.text( (5, 170), album, font=INFO_FNT, fill=ALBM_CLR)
draw.text( (5, 190), song, font=INFO_FNT, fill=TITL_CLR)
rds_info = "{}:{}:{}".format(artist, album, song)
radio.rds_buffer = rds_info.encode()
perc = float(status['elapsed']) / float(status['duration'])
draw.rectangle( (5, 215, 235, 230), outline=PROG_CLR)
draw.rectangle (
(5, 215, 5 + int(230*perc), 230),
fill=PROG_CLR
)
disp.image(image)
last_update = time.monotonic()
print("Now broadcasting {} on {}FM".format(STATION_NAME, FREQ))
while True:
now = time.monotonic()
try:
status = mpc.status()
except ConnectionError:
mpc.connect("localhost", 6600)
status = mpc.status()
if not button1.value:
button1_handler()
while not button1.value:
time.sleep(0.001)
if not button2.value:
button2_handler()
while not button2.value:
time.sleep(0.001)
if now - last_update > UPDATE_RATE:
update_display()
last_update = now