基于ESP32S2实现网络收音机和FM收音机的功能
基于ESP32S2实现网络收音机和FM收音机的功能,主要通过Arduino与Pycharm进行实现。
标签
嵌入式系统
Arduino
ESP32
收音机
2022寒假在家练
gyh
更新2022-03-02
北京理工大学
2289

研究平台介绍

1 核心控制器介绍

本平台使用了乐鑫公司的ESP32-S2-Mini-1模块,ESP32-S2-MINI-1是一颗通用型Wi-Fi MCU模组,功能强大,具有丰富的外设接口,可用于可穿戴电子设备、智能家居等场景。

2 模块构成

3 核心功能介绍:

  • 基于ESP32-S2 WiFi核心模块
  • 128*64 OLED显示,SPI接口,显示信息、参数、波形
  • 4个按键,用于参数控制、菜单选择
  • 1路Mic音频输入 - 模拟电路,通过电位计可以调节增益0-40dB调节范围,并有带通滤波器
  • 1路耳机插座音频输入 - 模拟电路,通过电位计可以调节增益 0-40dB调节范围,并有带通滤波器
  • 2路音频输出,并有功率放大,可以驱动喇叭和耳机插座
  • 一个FM接收模块,ESP32通过I2C接口对其进行参数设置,调节FM电台以及设置音量大小
  • 一个模拟开关切换来自ESP32产生的音频还是FM输出的音频,模块开关的输出送到喇叭或耳机输出

项目内容实现

1 项目要求:

  • 可以通过WiFi接收网络上的电台,也可以通过FM模块接收空中的电台,并可以通过按键进行切换、选台
  • 在OLED显示屏上显示网络电台的IP地址、节目名字等相关信息或FM信号的频段
  • 系统能够自动校时,开机后自动调节到准确的时间(年、月、日、时、分、秒)
  • 可以通过FM接收电台信号,并播放出来
  • 通过OLED显示电台的频率

2 功能流程:

Fgh2X9VOOMRU7TCPtRuMV8dXSqJy

3 项目环境:

本项目使用arduino作为开发环境,使用U8G2库驱动屏幕,收音机模块使用RDA5807进行控制。

 

以下为各模块主要部分代码以及功能实现中遇到的问题

FM模块

该模块实现了FM收音功能,由于测试的环境电台收音质量较差,故在信号阈值方面作了放宽,若是环境较好,可适当调高阈值。若同学想要通过硬件方式提高收音质量,可以另外购买天线进行组装。以下为主要代码展示:

//选择信号最好的频段
uint16_t findBest(uint16_t freq, uint8_t rssi) {
  while (rx.isStereo()) {
    rx.setFrequencyUp();
    delay(100);
    if (rx.isStereo() && rx.getRssi() > rssi) {
      freq = rx.getFrequency();
      rssi = rx.getRssi();
    }
  }
  return freq;
}

//搜索收音机的台  从8700~10800 MZH
void search() {
  uint16_t i = 0;
  uint8_t num = 0;
  rx.setFrequency(8700);      //从8700MHZ开始扫描
  while (i < 210) {
    delay(100);
    if (rx.isStereo() && rx.getRssi() > 25) { //如果搜到台,切信号值大于25
      fmstation[num++] = findBest(rx.getFrequency(), rx.getRssi());
      Serial.print("Good Frequency: ");
           Serial.println(rx.getFrequency());
      if (num >= MAX_STA) return;   
    }
    rx.setFrequencyUp();
    i++;
       Serial.print("Search FM");
       Serial.print(rx.getFrequency());
       Serial.print(":");
  }
}



//当前可用的电台数
uint8_t count() {
  uint8_t i;
  for (i = 0; i < MAX_STA; i++) {
    if (fmstation[i] == 0) return i;
  }
  return i;
}


//收音机换台
void change() {
  while (1) {
    if (stations == MAX_STA - 1) {
      stations = 0;
      rx.setFrequency(fmstation[stations]);
      return;
    }
    if (fmstation[stations + 1] != 0) {
      rx.setFrequency(fmstation[stations + 1]);
      stations++;
      Serial.println(fmstation[stations]);
      return;
    }
    stations++;
  }
}

 

WIFI与校时模块

该模块实现了WIFI连接与校时,由于ESP32无法连接5G热点,故使用手机热点进行连接。在校时的代码部分,gmtoffset_sec可以根据当地时区的不同进行更改,下图代码即为东八区校时。以下为代码展示:

//连接网络
char const* ssid     = (char*)"HHH";
char const* password = (char*)"123456123"; 

const char *ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 8 * 3600;
const int daylightOffset_sec = 3600;

String wifi_conn(){
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(400);
    //Serial.print("-");
  }
  return WiFi.localIP().toString();
}

//时间控制
int oldsec = -1;     //上次显示时的秒
String ipaddress;    //本机的IP地址

 

 

网络收音机模块

该模块实现了网络收音机功能,在借鉴了相关案例的经验后,也出于兴趣,进行了自建网络电台。故该模块的网络收音机功能为连接本项目的自建网络电台,让这个电台发送已解码的音频数据。在服务器中写入自建网络电台的ip和端口,输出音频流数据。

关于已解码的音频数据,因为是自建网络电台,故需要自行准备电台播放的音频文件。具体步骤如下:

1.先下载想要播放的音频文件,若为MP3格式,需先转码为wav文件,该步骤可在网页上完成;

2.得到wav文件后,因为播放采用单声道播放,故可通过server文件夹(见附件)中的wavfileinfo.py代码进行双声道转单声道;

3.最后将得到的wav文件名输入readwaveFile.py代码中的指定位置,运行music_webserver.py即可完成自建网络电台的准备工作。

需要注意的是,本项目是采用python在笔记本上自建网络电台,其ip需要在与ESP32连接同一热点的情况下进行ipconfig确认,具体原因可以阅读局域网ip的相关理论知识,简单来说当笔记本(即服务器)与ESP同连一个热点,它们就处于同一局域网,此时它们的ip都为该局域网分配的私网ip,可通过该ip在局域网中相互连接。而当笔记本(服务器)与ESP连接不同热点时,它们的连接则还需要进行ip转换的操作,更加复杂,例如笔记本(服务器)连接校园网而ESP连接手机热点。其它更加详细的知识请同学自行查阅理解,这里不再进行赘述。

//网络播放控制部分
uint8_t netbuf[3][1024];      //网络数据缓冲区
uint16_t writep = 0;          //写入数量
uint16_t readp = 0;           //读取数量
WiFiClient client; //声明一个客户端对象,用于与服务器进行连接
#define WEBSERVERIP "192.168.43.2"
#define WEBSERVERPORT 9999
bool connstat = false;        //连接状态
bool iswaitecho = false;      //是否等待服务器回应
Ticker flipper;               //时间中断
uint16_t m_offset = 0;

void onTimer(void) {
  if(readp<=writep)  dacWrite(17, netbuf[readp % 3][m_offset++]);      //播放一次声音
  if (m_offset >= 1024) {
    m_offset = 0;
    readp++;      //读取完成一个缓冲区
  }
}

//连接网络音乐服务器
bool CON_MUS() {
  uint8_t i = 0;
  while (i < 10) { //最多连接10次
    if (client.connect(WEBSERVERIP, WEBSERVERPORT)) {
      connstat = true;
      Serial.println("SUCES");
      return true;
    } else {
      Serial.println("FAIL");
      client.stop(); //
    }
    i++;
    delay(100);
  }
  return false;
}

 

4 实现结果展示:

开启界面

FlX7FnO8ZxyArEqRIPdqot5oYlW6

 

待机界面:显示时间与ESP的本机IP

FrVB_5uB7jaxF2nDo9MJbZgYoXzI

 

FM功能

Fku3AY99C4K0bfIfD3krfJamRK22

 

网络电台功能

Fow2CEEkwTQ8TTt-cyTvuYpkbCU6

 

项目总结

本项目在经过暑假一起练之后,在借鉴暑期案例的基础上,各个模块的实现都有了更加丰富的经验基础。所以完成项目的过程也相对顺利,感谢硬禾学堂提供这样一个研发平台,极大地帮助了对软硬件开发有兴趣的朋友。

在本项目过程中,最引起本人兴趣的是自建网络电台部分,该部分本来并不在研发功能的计划之中,但相对单纯接收网络电台来说另辟蹊径,克服了Arduino环境下ESP32-S2不支持I2S的使用的问题。于是在完成本项目的任务之外更增添了对python自建电台服务器的经验知识。在此也十分感谢提供暑期案例的同学让我接触到了这部分内容并顺利完成任务要求。

本项目的完成不仅让本人切实接触了嵌入式系统的开发与实现,也提高了对软硬件开发的认识,相信对本人今后无论是学业还是工作都提供了极大的经验与信心支持。再次感谢硬禾学堂。

附件下载
ESP32S2-Radio.ino
arduino源代码,需要编译后烧录
ESP32S2-Radio.ino.esp32s2.bin
arduino源代码编译后的二进制码,可直接烧录
server.rar
自建网络电台的python代码,详细使用可看代码注释,内附处理后的电台wav音频文件
团队介绍
北京理工大学信息与电子学院
团队成员
gyh
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号