现在根据这个代码,我写在了vscode软件里的demo.cpp文件中,以platformio为插件辅助
#include <app/pages/demo.h>
#include <lvgl.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
// 全局UI对象
static lv_obj_t *tabview;
static lv_obj_t *wifi_switch;
static lv_obj_t *ssid_textarea;
static lv_obj_t *pass_textarea;
static lv_obj_t *music_btn;
static lv_obj_t *music_btn_stop;
static lv_obj_t *music_btn_Previous;
static lv_obj_t *music_btn_Next;
static lv_obj_t *time_value;
/*--- 事件回调函数实现 ---*/
// WiFi开关状态变化
static void wifi_switch_event(lv_event_t *e) {
lv_event_code_t code = lv_event_get_code(e);
if(code == LV_EVENT_VALUE_CHANGED) {
bool en = lv_obj_has_state(wifi_switch, LV_STATE_CHECKED);
printf("lv_obj_has_state=[%d]\r\n", en);
if(en)
{
lv_obj_clear_flag(ssid_textarea, LV_OBJ_FLAG_HIDDEN);
lv_obj_clear_flag(pass_textarea, LV_OBJ_FLAG_HIDDEN);
}
else
{
lv_obj_add_flag(ssid_textarea, LV_OBJ_FLAG_HIDDEN);
lv_obj_add_flag(pass_textarea, LV_OBJ_FLAG_HIDDEN);
}
// 实际开发中需调用系统API启用WiFi
}
}
// 连接WiFi网络
static void connect_wifi_event(lv_event_t *e) {
const char *ssid = lv_textarea_get_text(ssid_textarea);
const char *pass = lv_textarea_get_text(pass_textarea);
// 实际开发中调用网络连接API[6](@ref)
printf("Connecting to WiFi: SSID=%s, Password=%s\n", ssid, pass);
// wifi_connect(ssid, pass);
}
// 切换到音乐播放页并开始播放
static void play_music_event(lv_event_t *e) {
// lv_tabview_set_act(tabview, 1, LV_ANIM_ON); // 切换到索引1(播放页)[2](@ref)
// 实际开发中启动播放逻辑[9,10](@ref)
printf("Starting music playback...\n");
// audio_play("/sdcard/music.mp3");
}
void build_pages() {
/* 1. 创建Tabview容器 */
tabview = lv_tabview_create(lv_scr_act()); // 顶部标签栏高度30px[1,2](@ref)
/* 2. 添加三个Tab页 */
lv_obj_t *tab_config = lv_tabview_add_tab(tabview, "Config");
lv_obj_t *tab_music = lv_tabview_add_tab(tabview, "Player");
lv_obj_t *tab_info = lv_tabview_add_tab(tabview, "Infor");
/* 3. 配置页内容:WiFi设置 */
// WiFi开关标签
lv_obj_t *wifi_label = lv_label_create(tab_config);
lv_label_set_text(wifi_label, "WiFi:");
lv_obj_align(wifi_label, LV_ALIGN_TOP_LEFT, 10, 20);
// WiFi开关控件
wifi_switch = lv_switch_create(tab_config);
lv_obj_align_to(wifi_switch, wifi_label, LV_ALIGN_OUT_RIGHT_MID, 20, 0);
lv_obj_add_event_cb(wifi_switch, wifi_switch_event, LV_EVENT_VALUE_CHANGED, NULL);
// SSID输入框
lv_obj_t *ssid_label = lv_label_create(tab_config);
lv_label_set_text(ssid_label, "SSID:");
lv_obj_align(ssid_label, LV_ALIGN_TOP_LEFT, 10, 60);
ssid_textarea = lv_textarea_create(tab_config);
lv_textarea_set_placeholder_text(ssid_textarea, "WiFi Name");
lv_obj_set_size(ssid_textarea, 200, 40);
lv_obj_align_to(ssid_textarea, ssid_label, LV_ALIGN_OUT_RIGHT_MID, 10, 0);
// 密码输入框
lv_obj_t *pass_label = lv_label_create(tab_config);
lv_label_set_text(pass_label, "Password:");
lv_obj_align(pass_label, LV_ALIGN_TOP_LEFT, 10, 110);
pass_textarea = lv_textarea_create(tab_config);
lv_textarea_set_password_mode(pass_textarea, true); // 密码模式
lv_textarea_set_placeholder_text(pass_textarea, "Password");
lv_obj_set_size(pass_textarea, 200, 40);
lv_obj_align_to(pass_textarea, pass_label, LV_ALIGN_OUT_RIGHT_MID, 10, 0);
// 连接按钮
lv_obj_t *connect_btn = lv_btn_create(tab_config);
lv_obj_t *connect_label = lv_label_create(connect_btn);
lv_label_set_text(connect_label, "Network");
lv_obj_align(connect_btn, LV_ALIGN_TOP_LEFT, 10, 160);
lv_obj_add_event_cb(connect_btn, connect_wifi_event, LV_EVENT_CLICKED, NULL);
/* 4. 配置页内容:音乐播放按钮 */
music_btn = lv_btn_create(tab_music);
lv_obj_t *btn_label = lv_label_create(music_btn);
lv_label_set_text(btn_label, "Play");
lv_obj_align(music_btn,LV_ALIGN_TOP_RIGHT, -20, 20);
lv_obj_add_event_cb(music_btn, play_music_event, LV_EVENT_CLICKED, NULL);
music_btn_stop = lv_btn_create(tab_music);
lv_obj_t *btn_label_stop = lv_label_create(music_btn_stop);
lv_label_set_text(btn_label_stop, "stop");
lv_obj_align_to(music_btn_stop,tab_music, LV_ALIGN_TOP_RIGHT, -20, 80);
lv_obj_add_event_cb(music_btn_stop, play_music_event, LV_EVENT_CLICKED, NULL);
music_btn_Previous = lv_btn_create(tab_music);
lv_obj_t *btn_label_prev = lv_label_create(music_btn_Previous);
lv_label_set_text(btn_label_prev, "Previous");
lv_obj_align_to(music_btn_Previous,tab_music, LV_ALIGN_TOP_RIGHT, -20, 140);
lv_obj_add_event_cb(music_btn_Previous, play_music_event, LV_EVENT_CLICKED, NULL);
music_btn_Next = lv_btn_create(tab_music);
lv_obj_t *btn_label_next = lv_label_create(music_btn_Next);
lv_label_set_text(btn_label_next, "Next");
lv_obj_align_to(music_btn_Next,tab_music, LV_ALIGN_TOP_RIGHT, -20, 200);
lv_obj_add_event_cb(music_btn_Next, play_music_event, LV_EVENT_CLICKED, NULL);
/* 5. 音乐播放页内容 */
lv_obj_t *title_label = lv_label_create(tab_music);
lv_label_set_text(title_label, "Music Name");
lv_obj_align(title_label, LV_ALIGN_TOP_MID, 0, 20);
lv_obj_t *play_btn = lv_btn_create(tab_music);
lv_obj_t *play_symbol = lv_label_create(play_btn);
lv_label_set_text(play_symbol, LV_SYMBOL_PLAY);
lv_obj_center(play_symbol);
lv_obj_align(play_btn, LV_ALIGN_CENTER, 0, 0);
lv_obj_t *time_label = lv_label_create(tab_info);
lv_label_set_text(time_label, "Time:");
lv_obj_align(time_label, LV_ALIGN_TOP_LEFT, 10, 60);
time_value = lv_label_create(tab_info);
lv_label_set_text(time_value, "2025-08-04 12:01:02");
lv_obj_align(time_value, LV_ALIGN_TOP_RIGHT, 40, 60);
lv_obj_align_to(time_value, time_label, LV_ALIGN_OUT_RIGHT_MID, 10, 0);
}
void update_time(const char * text)
{
lv_label_set_text(time_value, text);
}我要拓展一个新的领域,通过设置的四个按键分别实现播放,停止,上一首,下一首SD卡中的music文件夹里的1.mp3歌曲,
我的main.cpp文件中代码如下/*Using LVGL with Arduino requires some extra steps:
*Be sure to read the docs here: https://docs.lvgl.io/master/get-started/platforms/arduino.html */
#include <lvgl.h>
/*To use the built-in examples and demos of LVGL uncomment the includes below respectively.
*You also need to copy `lvgl/examples` to `lvgl/src/examples`. Similarly for the demos `lvgl/demos` to `lvgl/src/demos`.
Note that the `lv_examples` library is for LVGL v7 and you shouldn't install it for this version (since LVGL v8)
as the examples and demos are now part of the main LVGL library. */
// #include <examples/lv_examples.h>
// #include <demos/lv_demos.h>
// #define DIRECT_MODE // Uncomment to enable full frame buffer
// https://blog.csdn.net/weixin_41589183/article/details/140234622
#include <Arduino_GFX_Library.h>
#include "TCA9554.h"
#include "TouchDrvFT6X36.hpp"
#include "esp_lcd_touch_axs15231b.h"
#include "app/pages/demo.h"
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <examples/lv_examples.h>
#include <demos/lv_demos.h>
#include "Wire.h"
#include "esp_check.h"
#include "Arduino.h"
#include "WiFiMulti.h"
#include "Audio.h"
#include "SD_MMC.h"
#define LCD35
// 任务优先级定义(数值越大优先级越高)
#define TASK_PRIORITY_LVGL 2 // LVGL 任务优先级
#define TASK_PRIORITY_SENSOR 1 // 传感器任务优先级
// 任务栈大小(单位:字节)
#define TASK_STACK_LVGL 8192
#define TASK_STACK_SENSOR 4096
#define GFX_BL 6 // default backlight pin, you may replace DF_GFX_BL to actual backlight pin
TCA9554 TCA(0x20);
#define I2C_SDA 8
#define I2C_SCL 7
#define LCD_HOR_RES 320
#define LCD_VER_RES 480
#ifdef LCD35
#define SPI_MISO 2
#define SPI_MOSI 1
#define SPI_SCLK 5
#define LCD_CS -1
#define LCD_DC 3
#define LCD_RST -1
// I2S GPIOs
#define I2S_SDOUT 16
#define I2S_BCLK 13
#define I2S_LRCK 15
#define I2S_MCLK 12
#define EXAMPLE_SAMPLE_RATE (48000)
#define EXAMPLE_MCLK_MULTIPLE (256) // If not using 24-bit data width, 256 should be enough
#define EXAMPLE_MCLK_FREQ_HZ (EXAMPLE_SAMPLE_RATE * EXAMPLE_MCLK_MULTIPLE)
#define EXAMPLE_VOICE_VOLUME (70)
Audio audio;
#define SD_MMC_CLK 11
#define SD_MMC_CMD 10
#define SD_MMC_D0 9
#define I2C_SDA 8
#define I2C_SCL 7
#ifndef DEMO_H
#define DEMO_H
// 函数声明
void build_pages();
void update_time(const char *text);
#endif
Arduino_DataBus *bus = new Arduino_ESP32SPI(LCD_DC /* DC */, LCD_CS /* CS */, SPI_SCLK /* SCK */, SPI_MOSI /* MOSI */, SPI_MISO /* MISO */);
Arduino_GFX *gfx = new Arduino_ST7796(
bus, LCD_RST /* RST */, 0 /* rotation */, true, LCD_HOR_RES, LCD_VER_RES);
#else
#define DIRECT_RENDER_MODE // Uncomment to enable full frame buffer
#define LCD_QSPI_CS 12
#define LCD_QSPI_CLK 5
#define LCD_QSPI_D0 1
#define LCD_QSPI_D1 2
#define LCD_QSPI_D2 3
#define LCD_QSPI_D3 4
Arduino_DataBus *bus = new Arduino_ESP32QSPI(LCD_QSPI_CS, LCD_QSPI_CLK, LCD_QSPI_D0, LCD_QSPI_D1, LCD_QSPI_D2, LCD_QSPI_D3);
Arduino_GFX *gfx = new Arduino_AXS15231B(bus, -1 /* RST */, 0 /* rotation */, false, LCD_HOR_RES, LCD_VER_RES);
#endif
TouchDrvFT6X36 touch;
uint32_t screenWidth;
uint32_t screenHeight;
uint32_t bufSize;
lv_display_t *disp;
lv_color_t *disp_draw_buf1;
lv_color_t *disp_draw_buf2;
#if LV_USE_LOG != 0
void my_print(lv_log_level_t level, const char *buf)
{
LV_UNUSED(level);
Serial.println(buf);
Serial.flush();
}
#endif
uint32_t millis_cb(void)
{
return millis();
}
/* LVGL calls it when a rendered image needs to copied to the display*/
void my_disp_flush(lv_display_t *disp, const lv_area_t *area, uint8_t *px_map)
{
uint32_t w = lv_area_get_width(area);
uint32_t h = lv_area_get_height(area);
gfx->draw16bitRGBBitmap(area->x1, area->y1, (uint16_t *)px_map, w, h);
//printf("my_disp_flush[%d][%d]\r\n", w, h);
/*Call it to tell LVGL you are ready*/
lv_disp_flush_ready(disp);
}
/*Read the touchpad*/
void my_touchpad_read(lv_indev_t *indev, lv_indev_data_t *data)
{
#ifdef LCD35
int16_t x[1], y[1];
uint8_t touched = touch.getPoint(x, y, 1);
if (touched) {
data->state = LV_INDEV_STATE_PR;
/*Set the coordinates*/
data->point.x = x[0];
data->point.y = y[0];
} else {
data->state = LV_INDEV_STATE_REL;
}
#else
touch_data_t touch_data;
bsp_touch_read();
if (bsp_touch_get_coordinates(&touch_data)) {
data->state = LV_INDEV_STATE_PR;
/*Set the coordinates*/
data->point.x = touch_data.coords[0].x;
data->point.y = touch_data.coords[0].y;
} else {
data->state = LV_INDEV_STATE_REL;
}
#endif
//printf("X:%d, Y:%d, State:%d\n", data->point.x, data->point.y, data->state);
}
void lcd_reset(void) {
TCA.write1(1, 1);
delay(10);
TCA.write1(1, 0);
delay(10);
TCA.write1(1, 1);
delay(200);
}
static void event_debug(lv_event_t *e) {
// printf("Event: %d\n", lv_event_get_code(e));
}
#include"es8311.h"
static const char* TAG = "es8311_init";
static esp_err_t es8311_codec_init(void) {
/* 初始化es8311芯片 */
es8311_handle_t es_handle = es8311_create(I2C_NUM_0, ES8311_ADDRRES_0);
ESP_RETURN_ON_FALSE(es_handle, ESP_FAIL, TAG, "es8311 create failed");
const es8311_clock_config_t es_clk = {
.mclk_inverted = false,
.sclk_inverted = false,
.mclk_from_mclk_pin = true,
.mclk_frequency = EXAMPLE_MCLK_FREQ_HZ,
.sample_frequency = EXAMPLE_SAMPLE_RATE
};
ESP_ERROR_CHECK(es8311_init(es_handle, &es_clk, ES8311_RESOLUTION_16, ES8311_RESOLUTION_16));
// ESP_RETURN_ON_ERROR(es8311_sample_frequency_config(es_handle, EXAMPLE_SAMPLE_RATE * EXAMPLE_MCLK_MULTIPLE, EXAMPLE_SAMPLE_RATE), TAG, "set es8311 sample frequency failed");
ESP_RETURN_ON_ERROR(es8311_voice_volume_set(es_handle, EXAMPLE_VOICE_VOLUME, NULL), TAG, "set es8311 volume failed");
ESP_RETURN_ON_ERROR(es8311_microphone_config(es_handle, false), TAG, "set es8311 microphone failed");
return ESP_OK;
}
void lvgl_task(void *pvParameters) {
Serial.begin(115200);
es8311_codec_init();
Wire.begin(I2C_SDA, I2C_SCL);
TCA.begin();
TCA.pinMode1(1,OUTPUT);
lcd_reset();
printf("Arduino_GFX Hello World example\n\r");
#ifdef LCD35
if (!touch.begin(Wire, FT6X36_SLAVE_ADDRESS)) {
printf("Failed to find FT6X36 - check your wiring!\r\n");
while (1) {
delay(1000);
}
}
#else
bsp_touch_init(&Wire, -1, 0, 320, 480);
#endif
// Init Display
if (!gfx->begin()) {
printf("gfx->begin() failed!\r\n");
}
gfx->fillScreen(RGB565_BLACK);
#ifdef GFX_BL
pinMode(GFX_BL, OUTPUT);
digitalWrite(GFX_BL, HIGH);
#endif
lv_init();
/*Set a tick source so that LVGL will know how much time elapsed. */
lv_tick_set_cb(millis_cb);
/* register print function for debugging */
#if LV_USE_LOG != 0
lv_log_register_print_cb(my_print);
#endif
screenWidth = gfx->width();
screenHeight = gfx->height();
#ifdef DIRECT_RENDER_MODE
bufSize = screenWidth * screenHeight;
disp_draw_buf1 = (lv_color_t *)heap_caps_malloc(bufSize * 2, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
disp_draw_buf2 = (lv_color_t *)heap_caps_malloc(bufSize * 2, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
#else
bufSize = screenWidth * 40;
disp_draw_buf1 = (lv_color_t *)heap_caps_malloc(bufSize * 2, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
disp_draw_buf2 = (lv_color_t *)heap_caps_malloc(bufSize * 2, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
#endif
if (!disp_draw_buf1 || !disp_draw_buf2)
{
printf("LVGL disp_draw_buf allocate failed!\r\n");
}
else
{
disp = lv_display_create(screenWidth, screenHeight);
lv_display_set_flush_cb(disp, my_disp_flush);
#ifdef DIRECT_RENDER_MODE
lv_display_set_buffers(disp, disp_draw_buf1, disp_draw_buf2, bufSize * 2, LV_DISPLAY_RENDER_MODE_FULL);
#else
lv_display_set_buffers(disp, disp_draw_buf1, disp_draw_buf2, bufSize * 2, LV_DISPLAY_RENDER_MODE_PARTIAL);
#endif
/*Initialize the (dummy) input device driver*/
lv_indev_t *indev = lv_indev_create();
lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); /*Touchpad should have POINTER type*/
lv_indev_set_read_cb(indev, my_touchpad_read);
#if 0
/* Initialize the (dummy) input device driver */
lv_obj_t *label = lv_label_create(lv_scr_act());
lv_label_set_text(label, "Hello Arduino! (V" GFX_STR(LVGL_VERSION_MAJOR) "." GFX_STR(LVGL_VERSION_MINOR) "." GFX_STR(LVGL_VERSION_PATCH) ")");
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
lv_obj_t *sw = lv_switch_create(lv_scr_act());
lv_obj_align(sw, LV_ALIGN_TOP_MID, 0, 50);
sw = lv_switch_create(lv_scr_act());
lv_obj_align(sw, LV_ALIGN_BOTTOM_MID, 0, -50);
#else
/* Option 3: Or try out a demo. Don't forget to enable the demos in lv_conf.h. E.g. LV_USE_DEMOS_WIDGETS*/
build_pages();
//lv_demo_widgets();
//lv_demo_benchmark();
//lv_demo_keypad_encoder();
//lv_demo_music();
//lv_demo_stress();
#endif
lv_obj_add_event_cb(lv_scr_act(), event_debug, LV_EVENT_ALL, NULL);
printf("Setup done\r\n");
}
#if 1
while (1) {
lv_task_handler(); // 处理 LVGL 事件
vTaskDelay(pdMS_TO_TICKS(5)); // 5ms 延迟,避免 CPU 过载
}
#endif
}
void sensor_task(void *pvParam) {
char time[64] = {0};
int i = 0;
while (1) {
// 读取传感器数据(如温度、加速度)
vTaskDelay(pdMS_TO_TICKS(1000)); // 100ms 延迟
i++;
sprintf(time, "2025-08-04 12:23:%d", i);
update_time(time);
if(i>59) i=0;
}
}
void setup() {
xTaskCreatePinnedToCore(lvgl_task, "LVGL", TASK_STACK_LVGL, NULL, TASK_PRIORITY_LVGL, NULL, 0);
// 1. 串口初始化
Serial.begin(115200);
delay(1000);
Serial.println("Initializing...");
// 2. I2C 初始化(Codec 用)
Wire.begin(8, 7); // 根据硬件调整 SDA/SCL 引脚
// 3. 音频 codec 初始化(ES8311)
es8311_codec_init();
// 4. SD 卡初始化(根据硬件调整引脚)
SD_MMC.setPins(11, 10, 9); // CLK, CMD, D0
if (!SD_MMC.begin("/sdmmc", true, false, 20000)) {
Serial.println("SD Card Mount Failed!");
while (1);
}
Serial.println("SD Card Mounted.");
// 6. 音频初始化(I2S 引脚根据硬件调整)
audio.setPinout(13, 15, 16, 44); // BCLK, LRC, DOUT, MCLK
audio.setVolume(21); // 音量 0~21
// 启动音频循环
xTaskCreate([](void *arg) {
while (1) {
audio.loop(); // 音频库主循环
delay(1);
}
}, "audio_task", 4096, NULL, 2, NULL);
}
/*创建传感器任务(核心 1)
xTaskCreatePinnedToCore(sensor_task, "Sensor", TASK_STACK_SENSOR, NULL, TASK_PRIORITY_SENSOR, NULL, 1);
}*/
void loop() {
//lv_timer_handler(); /* let the GUI do its work */
// 主循环可处理其他逻辑(如定时更新时间)
static unsigned long lastTime = 0;
if (millis() - lastTime > 1000) { // 1 秒更新一次时间
update_time("2025-08-04 12:01:03"); // 实际可读取 RTC 或网络时间
lastTime = millis();
}
delay(100);
}
现在我有一个可以在Arduino软件上运行的代码,关于播放SD卡中我要求的music文件夹里的音乐的代码如下#include "Arduino.h"
#include "WiFiMulti.h"
#include "Audio.h"
#include "SD_MMC.h"
#include "FS.h"
#include "es8311.h"
#include "esp_check.h"
#include "Wire.h"
#define SD_MMC_CLK 11
#define SD_MMC_CMD 10
#define SD_MMC_D0 9
#define I2S_MCLK 44
#define I2S_DOUT 16
#define I2S_BCLK 13
#define I2S_LRC 15
#define I2C_SDA 8
#define I2C_SCL 7
#define EXAMPLE_SAMPLE_RATE (16000)
#define EXAMPLE_MCLK_MULTIPLE (256) // If not using 24-bit data width, 256 should be enough
#define EXAMPLE_MCLK_FREQ_HZ (EXAMPLE_SAMPLE_RATE * EXAMPLE_MCLK_MULTIPLE)
#define EXAMPLE_VOICE_VOLUME (75)
Audio audio;
WiFiMulti wifiMulti;
String ssid = "";
String password = "";
static esp_err_t es8311_codec_init(void) {
es8311_handle_t es_handle = es8311_create(I2C_NUM_0, ES8311_ADDRRES_0);
ESP_RETURN_ON_FALSE(es_handle, ESP_FAIL, TAG, "es8311 create failed");
const es8311_clock_config_t es_clk = {
.mclk_inverted = false,
.sclk_inverted = false,
.mclk_from_mclk_pin = true,
.mclk_frequency = EXAMPLE_MCLK_FREQ_HZ,
.sample_frequency = EXAMPLE_SAMPLE_RATE
};
ESP_ERROR_CHECK(es8311_init(es_handle, &es_clk, ES8311_RESOLUTION_16, ES8311_RESOLUTION_16));
// ESP_RETURN_ON_ERROR(es8311_sample_frequency_config(es_handle, EXAMPLE_SAMPLE_RATE * EXAMPLE_MCLK_MULTIPLE, EXAMPLE_SAMPLE_RATE), TAG, "set es8311 sample frequency failed");
ESP_RETURN_ON_ERROR(es8311_voice_volume_set(es_handle, EXAMPLE_VOICE_VOLUME, NULL), TAG, "set es8311 volume failed");
ESP_RETURN_ON_ERROR(es8311_microphone_config(es_handle, false), TAG, "set es8311 microphone failed");
return ESP_OK;
}
void setup() {
Serial.begin(115200);
Wire.begin(I2C_SDA, I2C_SCL);
es8311_codec_init();
SD_MMC.setPins(SD_MMC_CLK, SD_MMC_CMD, SD_MMC_D0);
if (!SD_MMC.begin("/sdmmc", true, false, 20000))
{
esp_rom_printf("Card Mount Failed\n");
while (1)
{
};
}
if (ssid != "" || password != ""){
WiFi.mode(WIFI_STA);
wifiMulti.addAP(ssid.c_str(), password.c_str());
wifiMulti.run();
if (WiFi.status() != WL_CONNECTED) {
WiFi.disconnect(true);
wifiMulti.run();
}
}
audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT, I2S_MCLK);
audio.setVolume(21); // 0...21
audio.connecttoFS(SD_MMC, "music/1.mp3");
// audio.connecttohost("http://www.wdr.de/wdrlive/media/einslive.m3u");
// audio.connecttohost("http://somafm.com/wma128/missioncontrol.asx"); // asx
// audio.connecttohost("http://mp3.ffh.de/radioffh/hqlivestream.aac"); // 128k aac
// audio.connecttohost("http://mp3.ffh.de/radioffh/hqlivestream.mp3"); // 128k mp3
}
void loop() {
vTaskDelay(1);
audio.loop();
if (Serial.available()) { // put streamURL in serial monitor
audio.stopSong();
String r = Serial.readString();
r.trim();
if (r.length() > 5) audio.connecttohost(r.c_str());
log_i("free heap=%i", ESP.getFreeHeap());
}
}
// optional
void audio_info(const char *info) {
Serial.print("info ");
Serial.println(info);
}
void audio_id3data(const char *info) { //id3 metadata
Serial.print("id3data ");
Serial.println(info);
}
void audio_eof_mp3(const char *info) { //end of file
Serial.print("eof_mp3 ");
Serial.println(info);
}
void audio_showstation(const char *info) {
Serial.print("station ");
Serial.println(info);
}
void audio_showstreamtitle(const char *info) {
Serial.print("streamtitle ");
Serial.println(info);
}
void audio_bitrate(const char *info) {
Serial.print("bitrate ");
Serial.println(info);
}
void audio_commercial(const char *info) { //duration in sec
Serial.print("commercial ");
Serial.println(info);
}
void audio_icyurl(const char *info) { //homepage
Serial.print("icyurl ");
Serial.println(info);
}
void audio_lasthost(const char *info) { //stream URL played
Serial.print("lasthost ");
Serial.println(info);
}请问我如何把他整合到vscode中实现我要求的功能(main.cpp和demo.cpp应该都要修改吧)