我做了一个超级简易的收音机,制作材料、电路、代码都很简单。
简易收音机有5大功能:显示收音机频率,天气信息,股票价格、联wifi,获取粉丝数量,等等。

硬件组成
收音机由5大模块制作:
主控芯片:ESP8266
驱动:RDA5807
显示屏:240*240 LCD
信号指示灯:WS2812用作
充电模块:CD42,断开充电线也能使用。
外壳:PCB板
硬件原理图

用嘉立创EDA设计的原理图

用嘉立创EDA设计的PCB
详细的网络连接如下图:

软件代码
为了方便开发和修改,软件是采用MicroPython实现的,核心代码如下:
import time
from machine import Timer,Pin
from ST7789V import LCD_240_240
from biliflow import BiliFlow
from RDA58XX import RDA5807
from neopixel import NeoPixel
tim = Timer(-1)
bf = BiliFlow() #b站粉丝数量显示
lcd = LCD_240_240()#显示屏驱动
rda = RDA5807() #收音机启动
np = NeoPixel(Pin(12, Pin.OUT) , 1) #WS2812驱动
lcd.Disp_Pic(0x320000) #显示背景图片
def bilibili(t): #定时刷新B站的粉丝数
r, g, b = np[0]
np[0] = (50, g, b)
np.write()
lcd.Disp_Str(90,140,str(bf.get_follower()).encode('utf-8'))
np[0] = (0, g, b)
np.write()
tim.init(period=10000, mode=Timer.PERIODIC, callback=bilibili)
key0 = Pin(0, Pin.IN, Pin.PULL_UP)
key0_statue = key0.value()
key1 = Pin(2, Pin.IN, Pin.PULL_UP)
key1_statue = key1.value()
need_re = 0
while True:
if not key0_statue == key0.value(): #按下编码器 静音
key0_statue = key0.value()
time.sleep_ms(10)
if key0.value() == 0:
print("mute")
rda.mute()
if not key1_statue == key1.value(): #右旋编码器,向下搜台
key1_statue = key1.value()
if key1.value() == 0:
print("next")
rda.next_sta()
time.sleep_ms(3000)
need_re = 1
if need_re == 1: #刷新当前电台的频率
rda.refresh_info()
need_re = 0
lcd.Disp_Str(0,0,b' ')
lcd.Disp_Str(0,0,("FM:" + str(rda.tune)).encode('utf-8'))
print("FM:", rda.tune ,"RSSI:", rda.rssi)
另外还需要有收音机芯片驱动,LCD显示屏驱动及粉丝数显示相关的代码:
RDA58XX.py 收音机驱动代码
from machine import Pin, SoftI2C
import time
import machine
class RDA5807(object):
def __init__(self):
self.i2c = SoftI2C(scl=Pin(4), sda=Pin(5), freq=10000)
self.i2c_buf = bytearray(2)
self.i2c_buf4 = bytearray(4)
self.is_mute = 0
self.rssi = 0
self.tune = 0
def next_sta(self): #向下搜台
self.i2c_buf[0] = 0xd3
self.i2c_buf[1] = 0x81
self.i2c.writeto(0x10, self.i2c_buf)
def pro_sta(self): #向上搜台
self.i2c_buf[0] = 0xd1
self.i2c_buf[1] = 0x81
self.i2c.writeto(0x10, self.i2c_buf)
def set_ch(self, ch): #设置频率eg. 965 unit 100KHz
self.i2c_buf4[0] = 0xd0
self.i2c_buf4[1] = 0x01
ch -= 870
self.i2c_buf4[2] = ((ch >> 2) & 0xff)
self.i2c_buf4[3] = ((ch << 5) & 0xff)
self.i2c.writeto(0x10, self.i2c_buf4)
def refresh_info(self): #获取当前频率,信号强度等
self.i2c.readfrom_into(0x11, self.i2c_buf4)
self.tune = 870 + self.i2c_buf4[1]
self.rssi = self.i2c_buf4[2] >> 1
def mute(self): #静音/撤销静音
if self.is_mute == 1:
self.i2c_buf[0] = 0xd0
self.is_mute = 0
else:
self.i2c_buf[0] = 0x90
self.is_mute = 1
self.i2c_buf[1] = 0x01
self.i2c.writeto(0x10, self.i2c_buf)
ST7789V.py 显示屏驱动
from machine import Pin, SPI
import time
import machine
import esp
class LCD_240_240(object):
def __init__(self):
self.hspi = SPI(1, 40000000)
self.lcd_dc = Pin(15, Pin.OUT)
self.lcd_dc.off()
self.hspi.write(b'x11')
time.sleep(0.05)
self.LCD_Cmd_Data(b'x36',b'x00')
self.LCD_Cmd_Data(b'x3A',b'x05')
self.LCD_Cmd_Data(b'xB2',b'x0Cx0Cx00x33x33')
self.LCD_Cmd_Data(b'xB7',b'x35')
self.LCD_Cmd_Data(b'xBB',b'x19')
self.LCD_Cmd_Data(b'xC0',b'x2C')
self.LCD_Cmd_Data(b'xC2',b'x01')
self.LCD_Cmd_Data(b'xC3',b'x12')
self.LCD_Cmd_Data(b'xC4',b'x20')
self.LCD_Cmd_Data(b'xC6',b'x0F')
self.LCD_Cmd_Data(b'xD0',b'xA4xA1')
self.LCD_Cmd_Data(b'xE0',b'xD0x04x0Dx11x13x2Bx3Fx54x4Cx18x0Dx0Bx1Fx23')
self.LCD_Cmd_Data(b'xE1',b'xD0x04x0Cx11x13x2Cx3Fx44x51x2Fx1Fx1Fx20x23')
self.lcd_dc.off()
self.hspi.write(b'x21x29')
def LCD_Cmd_Data(self,cmd, data):
self.lcd_dc.off()
self.hspi.write(cmd)
self.lcd_dc.on()
self.hspi.write(data)
def SetDisArea(self,xStart,yStart,xEnd,yEnd):
buf = bytearray(4)
buf[0] = 0
buf[1] = xStart
buf[2] = 0
buf[3] = xEnd
self.LCD_Cmd_Data(b'x2A',buf)
buf[1] = yStart
buf[3] = yEnd
self.LCD_Cmd_Data(b'x2B',buf)
self.lcd_dc.off()
self.hspi.write(b'x2C')
def Disp_Color(self,Color): #整屏填充某个颜色
self.SetDisArea(0,0,239,239)
self.lcd_dc.on()
buf = bytearray(480)
for j in range(240):
buf[j*2] = Color >> 8
buf[j*2+1] = Color & 0xFF
for i in range(240):
self.hspi.write(buf)
def DrawPoint(self,x,y,color):#在指定位置打点
buf = bytearray(2)
buf[0] = 0
buf[1] = x
self.LCD_Cmd_Data(b'x2A',buf)
buf[1] = y
self.LCD_Cmd_Data(b'x2B',buf)
buf[0] = color >> 8
buf[1] = color &0xFF
self.LCD_Cmd_Data(b'x2C',buf)
def Disp_Pic(self, star_addr): #显示图像,从Flash固定位置读取图像并显示在屏幕上
self.SetDisArea(0,0,239,239)
self.lcd_dc.on()
buf = bytearray(480)
byte_offset = star_addr
for i in range(240):
esp.flash_read(byte_offset, buf)
self.hspi.write(buf)
byte_offset += 480
def Disp_Str(self,x,y,str_datda):#显示字符串,需提前将字库烧录到0x300000位置
font_buf = bytearray(64)
for c in str_datda:
start_addr = 0x300000 + 65*(c - 0x20)
esp.flash_read(start_addr, font_buf)
self.SetDisArea(x,y,x+15,y+31)
x+=16
self.lcd_dc.on()
for j in range(64):
for k in range(8):
if (font_buf[j] & (0x01<<k)) == (0x01 << k):
self.hspi.write(b'xf8x00')
else:
self.hspi.write(b'xffxff')
bilibiliflow.py 获取B站粉丝数
import network
import json # 导入json功能模块
import urequests #导入urequests功能模块
class BiliFlow(object):
def __init__(self):
wifi = network.WLAN(network.STA_IF) # 将模块设为STA模式
wifi.active(True) # 开启WIFI
if not wifi.isconnected(): # 如果wifi模块未连接到热点
print('WiFi 连接中...')
wifi.connect('your_wifi' , 'xx123456') #连接自己的手机热点
while not wifi.isconnected(): #等待wifi连接
pass
print('WiFi 连接成功' , wifi.ifconfig()) #连接成功
def get_follower(self):#获取粉丝数,将下列vmid修改成自己的即可
r = urequests.get('http://api.bilibili.com/x/relation/stat?vmid=604244921')
p = json.loads(r.text)
return p['data']['follower']
结语
如果你喜爱的话这个简易的收音机,欢迎参考着DIY一个!
需要电路源文件,请评论区滴滴,无偿分享~
文中所有资料参考来源:立创开源硬件平台《8266驱动RDA5807实现收音机,粉丝数量显示》作者:Dr.Zhang
https://oshwhub.com/Dr.Zhang/511radio
如果你喜爱这篇文章,欢迎点赞、关注、转发、收藏~
我会持续更新优质开源项目!
© 版权声明
文章版权归作者所有,未经允许请勿转载。
相关文章
您必须登录才能参与评论!
立即登录



有eda教程吗?老人家不懂,以前手搓过类似
这个厉害了👏
好想做一个喔,分享一下给我吧,谢谢a
报考文末灰色连接哦
那些很早都出来了,大概有两年了,还是一年多了,然后我就是不知道怎么去用这个东西
想带着小孩做一个
参考文末灰色连接哦
原理?
点赞就是了。
收藏了,感谢分享