At this point, all the supporting software pieces should be in place, music has been added, playlist(s) created, and an available broadcast frequency has be determined. Now we can use a Python program to configure the Si4713 FM radio transmitter, start music playback, and use the TFT to provide status and basic control (via the buttons).
Here's the code. Save a copy of this as radio.py in the pi users home directory /home/pi.
# 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
And save it as radio_bg.py onto the Pi in /home/pi - the same directory where radio.py is saved.
Configure and Run
There are a few lines at the top of the radio.py code that can be changed. Look for these lines:
#--| User Config |----------------------------------- FREQ = 89.00 PLAYLIST = "test" STATION_NAME = "PiPyPirate Radio" UPDATE_RATE = 0.5 #----------------------------------------------------
And change, if needed, as follows:
- FREQ - Set this to the frequency that was found to be available from the frequency scan performed in the previous section.
- PLAYLIST - Set this to the playlist that will be broadcast over the radio. The default test playlist was created earlier in this guide.
- STATION_NAME - Change this text to be your station name. It actually gets broadcast (via RDS) and will show up on radios that display this kind of information.
- UPDATE_RATE - This sets how often the TFT display is refreshed, in seconds. The default 0.5 value should be fine, but the adjustment is here if needed.
Once the changes have been saved, run the radio.py program to start broadcasting:
python3 radio.py
It will print the station name and frequency being used. As long as the program is running, the radio is broadcasting.
Info and Status
When the radio.py program runs, the PiTFT is updated with with playback information and status.
- Animated radio "waves" will show around the antenna if the radio is broadcasting.
- These three lines show artists, album, and title for the current song playing.
- Along the bottom is a playback progress bar.
- The billboard displays the currently set broadcast frequency. Tune to this!
Text editor powered by tinymce.