rda5807m FM radio chip CircuitPython library
This driver depends on:
Please ensure all dependencies are available on the CircuitPython filesystem. This is easily achieved by downloading the Adafruit library and driver bundle or individual libraries can be installed using circup.
Make sure that you have circup
installed in your Python environment.
Install it with the following command if necessary:
pip3 install circup
With circup
installed and your CircuitPython device connected use the
following command to install:
circup install rda5807m
Or the following command to update an existing version:
circup update
import time
import board
import busio
import supervisor
import displayio
import terminalio
from adafruit_bus_device.i2c_device import I2CDevice
from adafruit_display_text import label
import adafruit_displayio_ssd1306
import tinkeringtech_rda5807m
from digitalio import DigitalInOut, Direction, Pull
# Display
displayio.release_displays()
oled_reset = board.D9
presets = [ # Preset stations
8930,
9510,
9710,
9950,
10100,
10110,
10650
]
i_sidx = 3 # Starting at station with index 3
# Initialize i2c bus
i2c = busio.I2C(board.SCL1, board.SDA1)
# Receiver i2c communication
address = 0x11
radio_i2c = I2CDevice(i2c, address)
vol = 0 # Default volume
band = "FM"
radio = tinkeringtech_rda5807m.Radio(radio_i2c, presets[i_sidx], vol)
radio.setBand(band) # Minimum frequency - 87 Mhz, max - 108 Mhz
rds = tinkeringtech_rda5807m.RDSParser()
# Display initialization
initial_time = time.monotonic() # Initial time - used for timing
toggle_frequency = 5 # Frequency at which the text changes between radio frequnecy and rds in seconds
display_bus = displayio.I2CDisplay(i2c, device_address=0x3C)
display = adafruit_displayio_ssd1306.SSD1306(display_bus, width=128, height=32)
rdstext = "No rds data"
def drawText(text):
# Write text on display
global display
# Make the display context
splash = displayio.Group()
display.show(splash)
color_bitmap = displayio.Bitmap(128, 32, 1)
color_palette = displayio.Palette(1)
color_palette[0] = 0x000000 # Black
bg_sprite = displayio.TileGrid(color_bitmap, pixel_shader=color_palette, x=0, y=0)
splash.append(bg_sprite)
# Split text into two lines
temp = text.split(" ")
line1 = temp[0]
line2 = " ".join(temp[1:])
# Check that lines are not empty
if not line1.strip() or not line2.strip():
warning = "Unclear rds data"
text_area_1 = label.Label(terminalio.FONT, text=warning, color=0xFFFF00, x=5, y=5)
splash.append(text_area_1)
else:
# Line 1
text_area_1 = label.Label(terminalio.FONT, text=line1, color=0xFFFF00, x=5, y=5)
splash.append(text_area_1)
# Line 2
text_area_2 = label.Label(terminalio.FONT, text=line2, color=0xFFFF00, x=5, y=20)
splash.append(text_area_2)
# RDS text handle
def textHandle(rdsText):
global rdstext
rdstext = rdsText
print(rdsText)
rds.attachTextCallback(textHandle)
# Read input from serial
def serial_read():
if supervisor.runtime.serial_bytes_available:
command = input()
command = command.split(" ")
cmd = command[0]
if cmd == "f":
value = command[1]
runSerialCommand(cmd, int(value))
else:
runSerialCommand(cmd)
time.sleep(0.3)
print("-> ", end="")
def runSerialCommand(cmd, value=0):
# Executes a command
# Starts with a character, and optionally followed by an integer, if required
global i_sidx
global presets
if cmd == "?":
print("? help")
print("+ increase volume")
print("- decrease volume")
print("> next preset")
print("< previous preset")
print(". scan up ")
print(", scan down ")
print("f direct frequency input")
print("i station status")
print("s mono/stereo mode")
print("b bass boost")
print("u mute/unmute")
print("r get rssi data")
print("e softreset chip")
print("q stops the program")
# Volume and audio control
elif cmd == "+":
v = radio.volume
if v < 15:
radio.setVolume(v + 1)
elif cmd == "-":
v = radio.volume
if v > 0:
radio.setVolume(v - 1)
# Toggle mute mode
elif cmd == "u":
radio.setMute(not radio.mute)
# Toggle stereo mode
elif cmd == "s":
radio.setMono(not radio.mono)
# Toggle bass boost
elif cmd == "b":
radio.setBassBoost(not radio.bassBoost)
# Frequency control
elif cmd == ">":
# Goes to the next preset station
if i_sidx < (len(presets) - 1):
i_sidx = i_sidx + 1
radio.setFreq(presets[i_sidx])
elif cmd == "<":
# Goes to the previous preset station
if i_sidx > 0:
i_sidx = i_sidx - 1
radio.setFreq(presets[i_sidx])
# Set frequency
elif cmd == "f":
radio.setFreq(value)
# Seek up/down
elif cmd == ".":
radio.seekUp()
elif cmd == ",":
radio.seekDown()
# Display current signal strength
elif cmd == "r":
print("RSSI: " + str(radio.getRssi()))
# Soft reset chip
elif cmd == "e":
radio.softReset()
# Not in help
elif cmd == "!":
radio.term()
elif cmd == "i":
# Display chip info
s = radio.formatFreq()
print("Station: " + s)
print("Radio info: ")
print("RDS -> " + str(radio.rds))
print("TUNED -> " + str(radio.tuned))
print("STEREO -> " + str(not radio.mono))
print("Audio info: ")
print("BASS -> " + str(radio.bassBoost))
print("MUTE -> " + str(radio.mute))
print("SOFTMUTE -> " + str(radio.softMute))
print("VOLUME -> " + str(radio.volume))
print_rds = False
radio.sendRDS = rds.processData
runSerialCommand("?", 0)
print("-> ", end="")
while True:
serial_read()
radio.checkRDS()
new_time = time.monotonic()
if (new_time - initial_time) > toggle_frequency:
print_rds = not print_rds
if print_rds:
if rdstext == "":
drawText("No rds data")
else:
if len(rdstext.split(" ")) > 1:
drawText(rdstext)
else:
drawText("Unclear rds data")
else:
drawText(radio.formatFreq())
initial_time = new_time
API documentation for this library can be found on Read the Docs.
For information on building library documentation, please check out this guide.
Contributions are welcome! Please read our Code of Conduct before contributing to help this project stay welcoming.