esp32在播放音频时为什么无法同步LCD?

huangapple go评论89阅读模式
英文:

Why esp32 cannot sync lcd while playing audio?

问题

我有一块由Panlee制造的sc01 plus开发板,配备了esp32-s3、16MB闪存、2MB PSRAM、IPS触摸屏、内置2W放大器、WiFi和蓝牙。我的问题是audioi2s库无法与该显示器一起工作。当我在设置中调用setPinput()时,它会使屏幕冻结,因此显示屏始终是黑色的,我无法在上面执行任何操作,但歌曲播放得很好。我使用lvgl进行前端开发。

我尝试在不同的核心上运行lvgl和音频,但它没有起作用。已经双重检查了引脚分配,并将项目清空为仅包含一个按钮的简单程序,但仍然没有任何变化。我只想要同步显示和播放歌曲。

以下是您的代码的翻译:

#include <Arduino.h>
#include <lvgl.h>
#include "ui/ui.h"
#include <LovyanGFX.hpp>
#include <SD.h>
#include <FS.h>
#include <Audio.h>

#define SCR 30
class LGFX : public lgfx::LGFX_Device
{
  // ... (这部分是有关设备配置的代码,未提供完整的翻译)
};

LGFX tft;

static const uint32_t screenWidth = 480;
static const uint32_t screenHeight = 320;

static lv_disp_draw_buf_t draw_buf;
static lv_disp_drv_t disp_drv;

static lv_color_t disp_draw_buf[screenWidth * SCR];
static lv_color_t disp_draw_buf2[screenWidth * SCR];

Audio audio;

#define SD_CS 41
#define SPI_MOSI 40
#define SPI_MISO 38
#define SPI_SCK 39

#define I2S_DOUT 37
#define I2S_BCLK 36
#define I2S_LRC 35

void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
  if (tft.getStartCount() == 0)
  {
    tft.endWrite();
  }

  tft.pushImageDMA(area->x1, area->y1, area->x2 - area->x1 + 1, area->y2 - area->y1 + 1, (lgfx::swap565_t *)&color_p->full);

  lv_disp_flush_ready(disp);
}

void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
{
  uint16_t touchX, touchY;

  bool touched = tft.getTouch(&touchX, &touchY);

  if (!touched)
  {
    data->state = LV_INDEV_STATE_REL;
  }
  else
  {
    data->state = LV_INDEV_STATE_PR;
    data->point.x = touchX;
    data->point.y = touchY;
  }
}

void lvgl_loop(void *parameter)
{
  while (true)
  {
    lv_timer_handler();
    delay(5);
  }
  vTaskDelete(NULL);
}

void guiHandler()
{
  xTaskCreatePinnedToCore(
      lvgl_loop,
      "LVGL LOOP",
      65536,
      NULL,
      2,
      NULL,
      1);
}

void playSound(void *parameter){
  while(true){
    audio.loop();
  }
  vTaskDelete(NULL);
}

void setup()
{
  Serial.begin(115200);

  tft.init();
  tft.initDMA();
  tft.startWrite();
  tft.setBrightness(255);

  lv_init();

  if (!disp_draw_buf)
  {
    Serial.println("LVGL disp_draw_buf allocate failed!");
  }
  else
  {
    // ...(这部分是有关显示和输入设备初始化的代码,未提供完整的翻译)
  }

  pinMode(SD_CS, OUTPUT);
  digitalWrite(SD_CS, HIGH);

  SPI.begin(SPI_SCK, SPI_MISO, SPI_MOSI);

  if (!SD.begin(SD_CS))
  {
    Serial.println("Hiba az SD kartyaval!");
    while (true)
      ;
  }

  audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);

  audio.setVolume(21);
  audio.connecttoFS(SD, "/Azahriah - 'FOUR MOODS' (OFFICIAL VISUALIZER).mp3");

  // xTaskCreatePinnedToCore(playSound, "playSound", 10240, NULL, 1, NULL, 0);

  guiHandler();
}

void loop()
{
  audio.loop();
}

希望这可以帮助您更好地理解您的代码。如果您有任何进一步的问题或需要进一步的帮助,请随时提出。

英文:

I have an sc01 plus devboard by panlee which comes with esp32-s3 16mb flash 2mb psramm an ips touch screen, a built-in 2w amplifier, wifi and bluetooth. My problem is audioi2s library cannot work with that display. When I call setPinput() in the setup it freezes the screen so the display always black and a I cannot do anything on it, but the song is playing nicely. I use lvgl for frontend.

I tried to run lvgl and audio on different cores, but it didn't worked. Double checked the pinouts, cleared the project to a simply program that has a button only but nothing happens yet. I just want to sync the display and play a song at the same time.

The code:

#include &lt;Arduino.h&gt;
#include &lt;lvgl.h&gt;
#include &quot;ui/ui.h&quot;
#include &lt;LovyanGFX.hpp&gt;
#include &lt;SD.h&gt;
#include &lt;FS.h&gt;
#include &lt;Audio.h&gt;
#define SCR 30
class LGFX : public lgfx::LGFX_Device
{
lgfx::Panel_ST7796 _panel_instance;
lgfx::Bus_Parallel8 _bus_instance;
lgfx::Light_PWM _light_instance;
lgfx::Touch_FT5x06 _touch_instance;
public:
LGFX(void)
{
{
auto cfg = _bus_instance.config();
cfg.port = 0;
cfg.freq_write = 40000000;
cfg.pin_wr = 47; // pin number connecting WR
cfg.pin_rd = -1; // pin number connecting RD
cfg.pin_rs = 0;  // Pin number connecting RS(D/C)
cfg.pin_d0 = 9;  // pin number connecting D0
cfg.pin_d1 = 46; // pin number connecting D1
cfg.pin_d2 = 3;  // pin number connecting D2
cfg.pin_d3 = 8;  // pin number connecting D3
cfg.pin_d4 = 18; // pin number connecting D4
cfg.pin_d5 = 17; // pin number connecting D5
cfg.pin_d6 = 16; // pin number connecting D6
cfg.pin_d7 = 15; // pin number connecting D7
_bus_instance.config(cfg);              // Apply the settings to the bus.
_panel_instance.setBus(&amp;_bus_instance); // Sets the bus to the panel.
}
{                                      // Set display panel control.
auto cfg = _panel_instance.config(); // Get the structure for display panel settings.
cfg.pin_cs = -1;   // Pin number to which CS is connected (-1 = disable)
cfg.pin_rst = 4;   // pin number where RST is connected (-1 = disable)
cfg.pin_busy = -1; // pin number to which BUSY is connected (-1 = disable)
cfg.memory_width = 320;  // Maximum width supported by driver IC
cfg.memory_height = 480; // Maximum height supported by driver IC
cfg.panel_width = 320;   // actual displayable width
cfg.panel_height = 480;  // actual displayable height
cfg.offset_x = 0;        // Panel offset in X direction
cfg.offset_y = 0;        // Panel offset in Y direction
cfg.offset_rotation = 1; // 3 ITT KELL FORGATNI
cfg.dummy_read_pixel = 8;
cfg.dummy_read_bits = 1;
cfg.readable = false;
cfg.invert = true;
cfg.rgb_order = false;
cfg.dlen_16bit = false;
cfg.bus_shared = true;
_panel_instance.config(cfg);
}
{
auto cfg = _light_instance.config(); // Get the structure for backlight configuration.
cfg.pin_bl = 45;     // pin number to which the backlight is connected
cfg.invert = false;  // true to invert backlight brightness
cfg.freq = 44100;    // backlight PWM frequency
cfg.pwm_channel = 0; // PWM channel number to use
_light_instance.config(cfg);
_panel_instance.setLight(&amp;_light_instance); // Sets the backlight to the panel.
}
{
auto cfg = _touch_instance.config();
cfg.x_min = 0;   // Minimum X value (raw value) obtained from the touchscreen
cfg.x_max = 319; // Maximum X value (raw value) obtained from the touchscreen
cfg.y_min = 0;   // Minimum Y value obtained from touchscreen (raw value)
cfg.y_max = 479; // Maximum Y value (raw value) obtained from the touchscreen
cfg.pin_int = 7; // pin number to which INT is connected
cfg.bus_shared = false;
cfg.offset_rotation = 0;
// For I2C connection
cfg.i2c_port = 0;    // Select I2C to use (0 or 1)
cfg.i2c_addr = 0x38; // I2C device address number
cfg.pin_sda = 6;     // pin number where SDA is connected
cfg.pin_scl = 5;     // pin number to which SCL is connected
cfg.freq = 400000;   // set I2C clock
_touch_instance.config(cfg);
_panel_instance.setTouch(&amp;_touch_instance); // Set the touchscreen to the panel.
}
setPanel(&amp;_panel_instance); // Sets the panel to use.
}
};
LGFX tft;
static const uint32_t screenWidth = 480;
static const uint32_t screenHeight = 320;
static lv_disp_draw_buf_t draw_buf;
static lv_disp_drv_t disp_drv;
static lv_color_t disp_draw_buf[screenWidth * SCR];
static lv_color_t disp_draw_buf2[screenWidth * SCR];
Audio audio;
#define SD_CS 41
#define SPI_MOSI 40
#define SPI_MISO 38
#define SPI_SCK 39
#define I2S_DOUT 37
#define I2S_BCLK 36
#define I2S_LRC 35
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
if (tft.getStartCount() == 0)
{
tft.endWrite();
}
tft.pushImageDMA(area-&gt;x1, area-&gt;y1, area-&gt;x2 - area-&gt;x1 + 1, area-&gt;y2 - area-&gt;y1 + 1, (lgfx::swap565_t *)&amp;color_p-&gt;full);
lv_disp_flush_ready(disp);
}
void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
{
uint16_t touchX, touchY;
bool touched = tft.getTouch(&amp;touchX, &amp;touchY);
if (!touched)
{
data-&gt;state = LV_INDEV_STATE_REL;
}
else
{
data-&gt;state = LV_INDEV_STATE_PR;
data-&gt;point.x = touchX;
data-&gt;point.y = touchY;
}
}
void lvgl_loop(void *parameter)
{
while (true)
{
lv_timer_handler();
delay(5);
}
vTaskDelete(NULL);
}
void guiHandler()
{
xTaskCreatePinnedToCore(
lvgl_loop,
&quot;LVGL LOOP&quot;,
65536,
NULL,
2,
NULL,
1);
}
void playSound(void *parameter){
while(true){
audio.loop();
}
vTaskDelete(NULL);
}
void setup()
{
Serial.begin(115200);
tft.init();
tft.initDMA();
tft.startWrite();
tft.setBrightness(255);
lv_init();
if (!disp_draw_buf)
{
Serial.println(&quot;LVGL disp_draw_buf allocate failed!&quot;);
}
else
{
Serial.print(&quot;Display buffer size: &quot;);
lv_disp_draw_buf_init(&amp;draw_buf, disp_draw_buf, disp_draw_buf2, screenWidth * SCR);
lv_disp_drv_init(&amp;disp_drv);
disp_drv.hor_res = screenWidth;
disp_drv.ver_res = screenHeight;
disp_drv.flush_cb = my_disp_flush;
disp_drv.draw_buf = &amp;draw_buf;
lv_disp_drv_register(&amp;disp_drv);
/* Initialize the input device driver */
static lv_indev_drv_t indev_drv;
lv_indev_drv_init(&amp;indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = my_touchpad_read;
lv_indev_drv_register(&amp;indev_drv);
ui_init();
Serial.println(&quot;Setup done&quot;);
}
pinMode(SD_CS, OUTPUT);
digitalWrite(SD_CS, HIGH);
SPI.begin(SPI_SCK, SPI_MISO, SPI_MOSI);
if (!SD.begin(SD_CS))
{
Serial.println(&quot;Hiba az SD kartyaval!&quot;);
while (true)
;
}
audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
audio.setVolume(21);
audio.connecttoFS(SD, &quot;/Azahriah - &#39;FOUR MOODS&#39; (OFFICIAL VISUALIZER).mp3&quot;);
// xTaskCreatePinnedToCore(playSound, &quot;playSound&quot;, 10240, NULL, 1, NULL, 0);
guiHandler();
}
void loop()
{
audio.loop();
}

答案1

得分: 1

好的!关于SPIFFS,我没有经验,我只是看了一下功能,似乎很容易使用...
要生成声音,我会使用连接在引脚上的有源蜂鸣器,或者使用被动蜂鸣器生成脉冲信号,例如使用占空比低于50的PWM输出。这些系统在启动mp3文件时响应迅速,我认为需要一个短暂的延迟。
回到WT32-SC01 Plus模块,关于音频,我遇到了在webradio播放> 192K时正确重现的问题,存在短暂的中断,我认为在使用内存方面的库之间存在一些冲突...具有Flac编解码器的文件无法播放。
另一个问题是SD卡阅读器,它不能识别大于16G的SD卡,从2到16G都可以,我想使用一个SanDisk 32G SDHC Class 10 SD。

英文:

Good! for SPIFFS I have no experience, I just saw the features and it seemed simple to use ...
I, to generate a sound, would use an active buzzer connected on a pin out, or, a passive buzzer generating a pulse train for example with a PWM output with a duty cycle lower than 50. These systems respond quickly while starting a file mp3 I think requires a short delay.
Returning to the WT32-SC01 Plus module, on the audio I encountered a problem of correct reproduction with webradio > 192K, there are short interruptions, I think there is some conflict between the libraries with the use of memory ... Files with Flac codec they are not played.
Another problem is with the SD card reader, it does not see SDs larger than 16G, from 2 to 16G everything is ok, I would like to use a SanDisk 32G SDHC Class 10 SD

答案2

得分: 0

我尝试移动音频设置,现在我的显示正常... 也有板上的音频

void setup() {
  Serial.begin(115200);
  delay(100);
  //Serial.setDebugOutput(true);
  audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
  delay(200);
  lcd.init(); 
  delay(100);
}
英文:

I try to move up the audio set, now my display is ok ... also the audio on board

void setup() {
Serial.begin(115200);
delay(100);
//Serial.setDebugOutput(true);
audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
delay(200);
lcd.init(); 
delay(100);

答案3

得分: 0

它工作得很好。我花了几天时间解决这个问题,但我没有想到改变代码的顺序会有帮助。我还有一个问题,如何制作一个简单的蜂鸣声?使用SD卡可以正常工作,但使用SPIFFS不起作用。需要在没有SD卡的情况下播放这个小声音。但我不知道如何将源MP3文件上传到SPIFFS文件系统。我使用带有Platform.io插件的VS Code。

英文:

It works fine. I spent a couple of days to solve this problem, but I did't think changing the order of the code would help. I have another question, how can I make a simple beep sound? With SD card it works fine, but with SPIFFS it doesn't work. It needs to play that small sound without SD card. But I don"t know how can I upload the source mp3 file to SPIFFS filesystem. I use VS code with platform.io plugin.

huangapple
  • 本文由 发表于 2023年8月10日 16:50:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/76874089.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定