开发板介绍:
本次项目我使用的是电子森林发放的esp32开发板,该开发板使用了乐鑫公司的ESP32-S2-Mini-1模块,ESP32-S2-MINI-1是一颗通用型Wi-Fi MCU模组,功能强大,具有丰富的外设接口,可用于可穿戴电子设备、智能家居等场景。
ESP32-S2-MINI-1采用PCB板载天线,模组配置了4MB SPI flash,采用的是 ESP32-S2FN4 芯片。该芯片搭载了Xtensa® 32 位LX7 单核处理器,工作频率高达 240 MHz。用户可以关闭 CPU 的电源,利用低功耗协处理器监测外设的状态变化或某些模拟量是否超出阈值。ESP32-S2-FH4 还集成了丰富的外设接口。在通用低功耗 IoT 传感器 Hub,通用低功耗 IoT 数据记录器,USB 设备,语音识别,图像识别,Mesh 网络,家庭自动化,智慧楼宇,工业自动化,健康/医疗/看护,Wi-Fi 玩具,可穿戴电子产品,零售 & 餐饮,智能 POS 应用等领域有广泛应用。
ESP32-S2-MINI-1模组
功能实现:
我选择完成的项目是:项目1 实现网络收音机和FM收音机的功能
1、可以通过WiFi接收网络上的电台,也可以通过FM模块接收空中的电台,并可以通过按键进行切换、选台。
2、在OLED显示屏上显示网络电台的IP地址、节目名字等相关信息或FM信号的频段。
3、系统能够自动校时,开机后自动调节到准确的时间(年、月、日、时、分、秒)。
4、可以通过FM接收电台信号,并播放出来。
5、通过OLED显示电台的频率。
软件实现:
我选择使用arduino IDE来编写及烧录程序。因为arduino的环境配置比较简单。
环境配置:
首先在官网上下载arduino IDE,然后根据乐鑫官网上的地址下载esp32相关程序如下图,
但是我没有下载成功。后来根据老师给的网盘下载相关软件,放在文档的arduino下。
下载esp32库,然后在工具开发板选择中选择esp32s2 dev module.如下图
之后在下载一些库,比如u8g2,rda5807等,就可以使用了。
程序实现:
WIFI连接:
连接WiFi,WiFi账号为123456,密码为12345678。
const char* ssid = (char*) "123456";
const char* password = (char*) "12345678";
String wifi_conn(){
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(400);
//Serial.print("-");
}
return WiFi.localIP().toString();
}
时间矫正:得到时间,时区为东八区。
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 3600*8;
const int daylightOffset_sec = 3600;
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
FM电台搜寻:从8750MHZ开始扫描电台,接收信号值大于30的电台
void searchFM() {
uint16_t i = 0;
uint8_t num = 0;
rx.setFrequency(8750); //从8750MHZ开始扫描
while (i < 210) {
delay(100);
if (rx.isStereo() && rx.getRssi() > 30) { //如果搜到台,切信号值大于30
fmstation[num++] = findBest(rx.getFrequency(), rx.getRssi());
if (num >= MAX_STA) return;
}
rx.setFrequencyUp();
i++;
}
}
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++;
}
}
网络收音机:网络电台的IP为192.168.43.110,端口为4999,也是自建网络电台的IP与端口设置。
uint8_t netbuf[3][1024]; //网络数据缓冲区
uint16_t writep = 0; //写入数量
uint16_t readp = 0; //读取数量
WiFiClient client; //声明一个客户端对象,用于与服务器进行连接
#define WEBSERVERIP "192.168.43.110"
#define WEBSERVERPORT 4999
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 < 5) { //最多连接5次
if (client.connect(WEBSERVERIP, WEBSERVERPORT)) {
connstat = true;
Serial.println("SUCES");
return true;
} else {
Serial.println("FAIL");
client.stop(); //
}
i++;
delay(100);
}
return false;
}
还有u2g8屏幕初始化,按键设置,屏幕显示等代码,就不全部展示了。
遇到的主要难题及方法:
在这个项目中遇到的主要问题还是网络收音机的实现部分。按理来说网路收音机的实现可以划为三部分:1、获取音频流,程序使用的 http 协议从一个服务器上面获取的音频数据,并将整个数据存放到一个 buffer 中。2、对音频流进行解码,当 buffer 中有一定的数据后(可以通过宏进行调整),开启解码线程。解码线程会从这个 buffer 中取出数据,然后调用解码库,将音频流解码为可直接输出的数字信号。3、将解码后的数据通过 DAC 输出,解码线程每解完一帧数据后,将它通过 I2C 驱动程序直接送给 DAC。但是esp32无法完成在线音频流的解码,所以无法直接接受网络电台。
经过我在网上的搜索,最终还是决定使用案例中的方法,搭建一个自有电台,直接发送解码完成后的音频。然后在搭建电台的过程中,学习了pycharm的用法。
实现功能及图片展示:
欢迎界面:
时间,日期以及IP显示:
FM电台界面:
网络电台界面:
自建网络电台的运行情况:
设计思路:
该项目的设计思路很简单,上电后,展示欢迎界面,然后连接WiFi和显示时钟与IP地址,按下KEY1进入FM模式,显示频率音量,按下KEY2换台,KEY3KEY4调节音量。再按下KEY1进入网络收音机。
当然首先要进行初始化,包括,包括GPIO初始化 OLED屏幕初始化,FM初始化 音频模块初始化。
未来的计划或建议:
首先就是这次的网络电台搭建的不够好,一次只能放一首歌,做不到自动切歌,歌曲只能播放WAV模式,还都要换成单声道,需要改进。且esp32板子虽然能接收网络电台,但是信号较差,声音很差。
OLED屏幕有点小。
wifi连接有时快有时慢,可能会等一段时间。
在这次活动中,我学习到了许多知识。学习了arduino的环境搭建,如何烧录板子,如何让程序跑起来。如何搭建Pycharm,在Pycharm上进行python程序的编辑,运行等。通过这次项目,我对嵌入式系统一些实际开发过程有了更深的认识。感谢主办方,希望主办方活动越办越好。