Why esp32 cannot sync lcd while playing audio?

321 Views Asked by At

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 <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::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(&_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(&_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(&_touch_instance); // Set the touchscreen to the panel.
    }

    setPanel(&_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->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
  {

    Serial.print("Display buffer size: ");

    lv_disp_draw_buf_init(&draw_buf, disp_draw_buf, disp_draw_buf2, screenWidth * SCR);

    lv_disp_drv_init(&disp_drv);
    disp_drv.hor_res = screenWidth;
    disp_drv.ver_res = screenHeight;
    disp_drv.flush_cb = my_disp_flush;
    disp_drv.draw_buf = &draw_buf;
    lv_disp_drv_register(&disp_drv);

    /* Initialize the input device driver */
    static lv_indev_drv_t indev_drv;
    lv_indev_drv_init(&indev_drv);
    indev_drv.type = LV_INDEV_TYPE_POINTER;
    indev_drv.read_cb = my_touchpad_read;
    lv_indev_drv_register(&indev_drv);

    ui_init();

    Serial.println("Setup done");
  }

  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();
}
2

There are 2 best solutions below

0
On BEST ANSWER

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);
0
On

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