尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

用ESP32和MicroPython做个复古FM收音机:TEA5767模块保姆级教程(附完整代码)

用ESP32和MicroPython做个复古FM收音机:TEA5767模块保姆级教程(附完整代码) 用ESP32和MicroPython打造复古FM收音机TEA5767模块全流程实战记得小时候总爱摆弄爷爷那台老式收音机旋钮转动的咔嗒声和偶尔飘出的沙沙声构成了我对无线广播的最初记忆。如今借助ESP32和TEA5767模块我们完全可以自己动手复刻这种复古体验还能加入智能调频等现代功能。本文将带你从零开始用MicroPython构建一个可扩展的FM收音机系统。1. 硬件准备与电路设计1.1 核心组件选型这个项目的核心是ESP32开发板和TEA5767收音模块的完美组合。ESP32以其双核处理器、丰富的外设接口和WiFi/蓝牙功能成为物联网项目的首选。而TEA5767作为经典的数字调谐收音芯片具有以下优势特性特性参数说明工作电压5V DC (±10%)频率范围76MHz-108MHz (覆盖校园广播)信噪比(SNR)≥60dB (典型值)立体声分离度35dB (典型值)总谐波失真(THD)0.3% (典型值)1.2 电路连接详解连接ESP32与TEA5767只需要4根线但有几个关键细节需要注意# 推荐接线方式 (以ESP32 DevKitC为例) TEA5767_VCC - ESP32 5V输出 TEA5767_GND - ESP32 GND TEA5767_SCL - GPIO22 (默认I2C时钟) TEA5767_SDA - GPIO21 (默认I2C数据)注意虽然TEA5767标称5V供电但实测3.3V也能工作只是灵敏度会略有下降。如果追求最佳接收效果建议使用5V供电并添加电平转换电路。2. MicroPython驱动开发2.1 I2C通信基础配置MicroPython的I2C接口配置非常直观但时钟频率的设置会影响通信稳定性from machine import I2C, Pin i2c I2C(0, sclPin(22), sdaPin(21), freq400000) # 400kHz标准模式 print(扫描到I2C设备:, i2c.scan()) # TEA5767地址应为0x60如果扫描不到设备检查接线后可以尝试降低频率到100kHz。我曾遇到某些山寨模块在高速模式下不稳定的情况。2.2 TEA5767驱动实现不同于简单的寄存器操作TEA5767需要按照特定格式组包。下面是一个经过实战检验的驱动类class TEA5767: def __init__(self, i2c, address0x60): self.i2c i2c self.address address self._buffer bytearray(5) self.mute False self.standby False def _calculate_pll(self, freq): return int(4 * (freq * 1000000 225000) / 32768) def set_frequency(self, freq): if freq 76 or freq 108: raise ValueError(频率需在76-108MHz之间) pll self._calculate_pll(freq) self._buffer[0] (pll 8) | 0x40 # 高字节启用搜索模式 self._buffer[1] pll 0xFF # 低字节 self._buffer[2] 0xB0 # 默认设置立体声、高灵敏度 self._buffer[3] 0x10 # 不启用时钟输出 self._buffer[4] 0x00 # 保留位 self.i2c.writeto(self.address, self._buffer)这个实现加入了频率范围校验和PLL计算细节比基础版本更健壮。实际项目中我会进一步封装搜索电台和信号强度检测功能。3. 用户界面与功能扩展3.1 OLED频率显示添加SSD1306 OLED屏可以大幅提升用户体验。以下是显示当前频率的示例import ssd1306 from time import sleep i2c I2C(0, sclPin(22), sdaPin(21)) oled ssd1306.SSD1306_I2C(128, 64, i2c, 0x3C) radio TEA5767(i2c) def update_display(freq): oled.fill(0) oled.text(FM RADIO, 30, 10) oled.text(f{freq:.1f} MHz, 40, 30, 1) oled.text(*int(radio.rssi/10), 20, 50) # 信号强度指示 oled.show()3.2 物理旋钮控制用EC11旋转编码器替代按键还原老式收音机的调谐手感from rotary_irq_esp import RotaryIRQ encoder RotaryIRQ(pin_num_clk14, pin_num_dt12, min_val760, max_val1080, reverseFalse) last_pos encoder.value() while True: pos encoder.value() if pos ! last_pos: radio.set_frequency(pos/10) update_display(pos/10) last_pos pos4. 进阶功能与优化技巧4.1 自动搜台与存储实现电台记忆功能需要解决几个技术难点信号质量检测通过读取TEA5767的状态字节获取RSSI智能搜索算法避免停留在无信号频段非易失存储使用ESP32的NVS或外部EEPROMdef scan_stations(): stations [] radio.set_search_mode(True) # 自定义方法 for freq in range(760, 1081, 5): # 0.5MHz步进 radio.set_frequency(freq/10) time.sleep(0.1) if radio.rssi 30: # 有效信号 stations.append({ freq: freq/10, name: fStation {len(stations)1} }) return stations4.2 网络电台混合播放结合ESP32的WiFi功能可以打造混合型收音机import socket import network def connect_wifi(ssid, pwd): sta_if network.WLAN(network.STA_IF) sta_if.active(True) sta_if.connect(ssid, pwd) while not sta_if.isconnected(): time.sleep(0.5) print(IP:, sta_if.ifconfig()[0]) def play_stream(url): # 简化的网络音频流播放 _, _, host, path url.split(/, 3) addr socket.getaddrinfo(host, 80)[0][-1] s socket.socket() s.connect(addr) s.send(bytes(fGET /{path} HTTP/1.0\r\nHost: {host}\r\n\r\n, utf8)) # 此处应添加音频解码处理5. 外壳设计与复古元素3D打印的外壳能为项目增添个性。设计时需考虑散热孔位ESP32长时间工作会产生一定热量天线布置预留SMA接口或拉杆天线位置旋钮手感使用编码器配套的大尺寸旋钮屏幕开孔精确测量OLED屏可视区域分享一个实测有效的小技巧在机壳内部贴铜箔胶带并接地能显著降低数字电路对收音模块的干扰。我的第二个版本通过这种方式使信噪比提升了约15%。
返回列表