Introduction
May 2, 2022 ยท View on GitHub
.. image:: https://readthedocs.org/projects/tinkeringtech-circuitpython-rda5807m/badge/?version=latest :target: https://circuitpython-rda5807m.readthedocs.io/ :alt: Documentation Status
.. image:: https://img.shields.io/discord/327254708534116352.svg :target: https://adafru.it/discord :alt: Discord
.. image:: https://github.com/tinkeringtech/Tinkeringtech_CircuitPython_rda5807m/workflows/Build%20CI/badge.svg :target: https://github.com/tinkeringtech/Tinkeringtech_CircuitPython_rda5807m/actions :alt: Build Status
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg :target: https://github.com/psf/black :alt: Code Style: Black
rda5807m FM radio chip CircuitPython library
Dependencies
This driver depends on:
Adafruit CircuitPython <https://github.com/adafruit/circuitpython>_Bus Device <https://github.com/adafruit/Adafruit_CircuitPython_BusDevice>_
Please ensure all dependencies are available on the CircuitPython filesystem.
This is easily achieved by downloading
the Adafruit library and driver bundle <https://circuitpython.org/libraries>_
or individual libraries can be installed using
circup <https://github.com/adafruit/circup>_.
Installing to a Connected CircuitPython Device with Circup
Make sure that you have circup installed in your Python environment.
Install it with the following command if necessary:
.. code-block:: shell
pip3 install circup
With circup installed and your CircuitPython device connected use the
following command to install:
.. code-block:: shell
circup install rda5807m
Or the following command to update an existing version:
.. code-block:: shell
circup update
Usage Example
.. code-block:: shell
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
Documentation
API documentation for this library can be found on Read the Docs <https://circuitpython-rda5807m.readthedocs.io/>_.
For information on building library documentation, please check out
this guide <https://learn.adafruit.com/creating-and-sharing-a-circuitpython-library/sharing-our-docs-on-readthedocs#sphinx-5-1>_.
Contributing
Contributions are welcome! Please read our Code of Conduct <https://github.com/tinkeringtech/Tinkeringtech_CircuitPython_rda5807m/blob/HEAD/CODE_OF_CONDUCT.md>_
before contributing to help this project stay welcoming.