硬件介绍
核心控制器介绍:
本平台使用了乐鑫公司的ESP32-S2-Mini-1模块,ESP32-S2-MINI-1是一颗通用型Wi-Fi MCU模组,功能强大,具有丰富的外设接口,可用于可穿戴电子设备、智能家居等场景。
ESP32-S2-MINI-1采用PCB板载天线,模组配置了4MB SPI flash,采用的是ESP32-S2FN4芯片。该芯片搭载了Xtensa32位LX7单核处理器,工作频率高达240MHz。用户可以关闭CPU的电源,利用低功耗协处理器监测外设的状态变化或某些模拟量是否超出阈值。ESP32-S2-FH4还集成了丰富的外设接口。
核心功能介绍:
-
基于ESP32-S2 WiFi核心模块
-
128*64 OLED显示,SPI接口,显示信息、参数、波形
-
4个按键,用于参数控制、菜单选择
-
1路Mic音频输入 - 模拟电路,通过电位计可以调节增益0-40dB调节范围,并有带通滤波器
-
1路耳机插座音频输入 - 模拟电路,通过电位计可以调节增益0-40dB调节范围,并有带通滤波器
-
2路音频输出,并有功率放大,可以驱动喇叭和耳机插座
-
一个FM接收模块,ESP32通过I2C接口对其进行参数设置,调节FM电台以及设置音量大小
-
一个模拟开关切换来自ESP32产生的音频还是FM输出的音频,模块开关的输出送到喇叭或耳机输出
项目介绍
用ESP32-S2模块实现FM/网络收音机,使用Arduino开发平台。
主要实现功能如下:
-
可以通过WiFi接收网络上的电台,也可以通过FM模块接收空中的电台,并可以通过按键进行切换、选台
-
在OLED显示屏上显示网络电台的IP地址、节目名字等相关信息或FM信号的频段
-
系统能够自动校时,开机后自动调节到准确的时间(年、月、日、时、分、秒)
-
可以通过FM接收电台信号,并播放出来
-
通过OLED显示电台的频率
流程图
实现功能
wifi配置和校时:
最开始是wifi配置和校时部分,这部分借助乐鑫提供的丰富的例程,实现较为简单。我选择连接手机热点,以方便可能在不同地方操作开发板。网络校时方面采用自动与因特网时间服务器NTP同步(pool.ntp.org),调整参数为中国所处的东八区。
char* ssid="Minephone5";
char* password="xxx";
const char *ntpServer="pool.ntp.org";
const long gmtOffset_sec=8 * 3600;
const int daylightOffset_sec=0;
configTime(gmtOffset_sec,daylightOffset_sec,ntpServer);
printLocalTime();
配置引脚:
根据ESP32-S2的原理图配置OLED引脚,OLED由U8g2lib库驱动。
U8G2_SSD1306_128X64_NONAME_F_4W_SW_SPI u8g2(U8G2_R0,/*clock=*/36,/*data=*/35,/*cs=*/37,/*dc=*/33,/*reset=*/34);
标志位和按键:
标志位用于确定不同模式,模式由按键切换。
uint8_t modelsign=1;//设置状态标志位
void loop(){
if(modelsign==1)
{
timer_show();
//printLocalTime();
}
if(digitalRead(button1Pin)==LOW)
{
delay(200);
if(digitalRead(button1Pin)==LOW){
modelsign++;
}
}
if(modelsign==2)
{
selectDevice(1);
FM_show();
if(digitalRead(button2Pin)==LOW)
{
rx.setFrequencyUp();
}
if(digitalRead(button3Pin)==LOW)
{
rx.setVolumeUp();
}
if(digitalRead(button4Pin)==LOW)
{
rx.setVolumeDown();
}
}
if(modelsign==3)
{
selectDevice(2);
WebRadio_show();
playMusic();
}
}
//模式切换
void selectDevice(uint8_t dev){
if(dev==0){
digitalWrite(41,LOW);
digitalWrite(42,LOW);
}
if(dev==1){
digitalWrite(41,HIGH);
digitalWrite(42,LOW);
}
if(dev==2){
digitalWrite(41,HIGH);
digitalWrite(42,HIGH);
}
}
网络时钟显示:
清除内部缓冲区,设置字体、位置、屏幕显示内容。
void timer_show() {
struct tm timeinfo;
if (!getLocalTime(&timeinfo))
{
u8g2.clearBuffer();
u8g2.setFontDirection(0);
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.setCursor(0,40);
u8g2.print("Failed to calibrate time");
u8g2.setCursor(2,55);
u8g2.print(ipaddress);
u8g2.sendBuffer();
return;
}
u8g2.clearBuffer();
u8g2.setFontDirection(0);
u8g2.setFont(u8g2_font_ncenB14_tr);
u8g2.setCursor(20,15);
u8g2.print(&timeinfo, "%H:%M:%S");
u8g2.setCursor(15,35);
u8g2.print(&timeinfo, "%Y.%m.%d");
u8g2.setFont(u8g2_font_ncenB12_tr);
u8g2.setCursor(2,55);
u8g2.print(ipaddress);
u8g2.sendBuffer();
}
FM收音模块:
RDA5807是个现成的收音模块,76~108MHz与全球FM频段兼容,可直接用RDA5807库控制FM收音模块。
void FM_show(){
char str[64]={0};
u8g2.firstPage();
u8g2.clearBuffer();//清除内部缓冲区
u8g2.setFontDirection(0);
u8g2.setFont(u8g2_font_ncenB14_tr);//设置字体
u8g2.setCursor(15,20);
u8g2.print("FM Radio");
u8g2.setFont(u8g2_font_ncenB10_tf);
u8g2.setCursor(15,40);
sprintf(str, "%.1u.%u MHz",rx.getFrequency()/100,rx.getFrequency()%100/10);
u8g2.print(str);
u8g2.setCursor(15,60);
sprintf(str, "Volume: %2.2u/15",rx.getVolume());
u8g2.print(str);
u8g2.sendBuffer();
delay(1000);
}
网络收音模块:
网络收音模块编写比较复杂,参考了很多前人的方法,有人使用蜻蜓FM电台实现网络收音功能,但经过学习和实操发现比较困难。与同学交流后决定自建网络电台,并使服务器和Arduino中的IP地址和端口保持一致,IP地址为电脑连接手机热点的IP。OLED屏显示IP和端口号。
void WebRadio_show(){
char str[64]={0};
if (connstat==true) {
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB14_tr);
u8g2.setCursor(10,20);
u8g2.print("Web Radio");
u8g2.setFont(u8g2_font_ncenB08_tf);
u8g2.setCursor(10,46);
sprintf(str, "%s:%d", WEBSERVERIP, WEBSERVERPORT);
u8g2.print(str);
}else {
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB14_tr);
u8g2.setCursor(10,20);
u8g2.print("Web Radio");
u8g2.setFont(u8g2_font_ncenB08_tf);
u8g2.setCursor(10,40);
u8g2.print("Connection failed.");
}
u8g2.sendBuffer();
}
图片展示
遇到问题及解决方法
这次着手ESP32开发板项目非常具有挑战性,尽管有若干现成的库和例程可供参考使用,大多数Arduino平台代码的编写调试运行还是需要花时间的,不过最终也可以看出代码模块分明,有逻辑性。
网络电台的建立是一个重难点,第一次使用pycharm搭建服务器,学习相关操作比较费工夫,最终开发板终于能连上网络电台,虽然音频输出一顿一顿,但至少有了声音,且pycharm的运行窗口可以看到信息流打印,总体感觉很有收获和成就感。