<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Atomic Audio Base with M5ATOMS3R]]></title><description><![CDATA[<p dir="auto">I can't get this base to work with the AtomS3R . The example on the website doesn't work due to an i2s conflict between new and legacy i2s drivers. I finally got the following program to run meaning I see the text on the display however I can't seem to hear anything. Not sure if it isn't recording or not playing back properly. Does anyone have recent working code for this pair? Thanks.</p>
<pre><code>#include "M5Unified.h"

// Define buffer size (200KB for ESP32-S3)
#define RECORD_SIZE (1024 * 200)
static uint8_t *buffer = nullptr;

void setup()
{
    auto cfg = M5.config();
    // Enable external I2C for ES8311 codec on the audio base
    cfg.external_imu = true;
    M5.begin(cfg);

    M5.Display.setFont(&amp;fonts::FreeMonoBold9pt7b);
    Serial.begin(115200);

    // --------------------------
    // Speaker Configuration (I2S Output)
    // AtomS3R I2S pins: BCK=8, WS=6, DOUT=5
    // --------------------------
    auto spk_cfg = M5.Speaker.config();
    spk_cfg.pin_data_out = 5;
    spk_cfg.pin_bck      = 8;
    spk_cfg.pin_ws       = 6;
    spk_cfg.sample_rate  = 44100;
    spk_cfg.i2s_port     = I2S_NUM_0;
    spk_cfg.stereo       = false; // Use mono for the base speaker
    M5.Speaker.config(spk_cfg);
    M5.Speaker.begin();

    // --------------------------
    // Microphone Configuration (I2S Input)
    // AtomS3R I2S pins: BCK=8, WS=6, DIN=7
    // --------------------------
    auto mic_cfg = M5.Mic.config();
    mic_cfg.pin_data_in  = 7;
    mic_cfg.pin_bck      = 8;
    mic_cfg.pin_ws       = 6;
    mic_cfg.sample_rate  = 44100;
    mic_cfg.i2s_port     = I2S_NUM_1; // Use separate I2S port for input
    M5.Mic.config(mic_cfg);
    M5.Mic.begin();

    // Set volume/gain
    M5.Speaker.setVolume(50);
    // For v0.2.14, set mic gain via config if needed (default works for most cases)
    // mic_cfg.magnification = 2;

    // Allocate recording buffer
    buffer = (uint8_t *)malloc(RECORD_SIZE);
    if (buffer == nullptr) {
        Serial.println("Memory allocation failed!");
        while (true) delay(1000);
    }

    Serial.println("Device ready! Press button to record/play");
    M5.Display.println("Click to\nRecord &amp; Play");
}

void loop()
{
    M5.update();

    if (M5.BtnA.wasClicked()) {
        M5.Display.fillScreen(BLACK);
        M5.Display.setCursor(0, 0);

        // --------------------------
        // Recording
        // --------------------------
        M5.Display.println("Recording...");
        Serial.println("Start recording");
        M5.Mic.record(buffer, RECORD_SIZE, 44100);
        delay(3000);

        // --------------------------
        // Playback
        // --------------------------
        M5.Display.println("Playing...");
        Serial.println("Start playing");
        M5.Speaker.playRaw(buffer, RECORD_SIZE, 44100, false, 1);
        while (M5.Speaker.isPlaying()) delay(10);

        M5.Display.println("Done");
        Serial.println("Done");
    }
}
</code></pre>
]]></description><link>https://community.m5stack.com/topic/8188/atomic-audio-base-with-m5atoms3r</link><generator>RSS for Node</generator><lastBuildDate>Sun, 26 Apr 2026 12:49:10 GMT</lastBuildDate><atom:link href="https://community.m5stack.com/topic/8188.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 22 Apr 2026 04:32:05 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Atomic Audio Base with M5ATOMS3R on Thu, 23 Apr 2026 06:31:57 GMT]]></title><description><![CDATA[<p dir="auto">I have been able to get a program to work that uses the M5EchoBase library but no luck using the unified library. For example the simple program below doesn't work.</p>
<pre><code>#include &lt;M5Unified.h&gt;

void setup() {
  // 1. Initialize M5Unified
   delay(1000);  // Delay for a moment to allow the system to stabilize.
    auto cfg  = M5.config();
    cfg.serial_baudrate = 115200;
    M5.begin(cfg);
 

  // 2. Configure the Speaker for the Atomic Audio Base (ES8311)
  // We access the speaker configuration directly via M5.Speaker.config()
  auto spk_cfg = M5.Speaker.config();
  
  // Set pins for Atomic Audio Base (ES8311)
  spk_cfg.pin_bck = 8;   // BCLK
  spk_cfg.pin_ws = 6;    // LRCK (WS)
  spk_cfg.pin_data_out = 5; // DAC (DOUT)
  spk_cfg.i2s_port = I2S_NUM_0;
  
  // Configure for external codec (not internal DAC)
  spk_cfg.use_dac = false; 
  spk_cfg.sample_rate = 44100; 
  
  // Apply the configuration
  M5.Speaker.config(spk_cfg);
  
  // 3. Start the speaker
  M5.Speaker.begin();
  
  // 4. Set volume (0-255)
  M5.Speaker.setVolume(128);
}

void loop() {
  M5.update();

  // Play a 1000 Hz tone for 1000 milliseconds (1 second)
  M5.Speaker.tone(1000, 1000);
  // Wait for the tone to finish
  delay(1000);
  
  // Small delay before next loop
  delay(1000);
}
</code></pre>
<p dir="auto">Is there no way to set up the ES8311 codec without using M5EchoBase? strangely if I run the program below then load the above program the tone works? But I can't stick the M5.Speaker.tone(1000, 1000); command in the program below and have it work. Does anyone know how to play a tone using only the Unified library from an AtomS3R into a Atomic Audio Base (ES8311 codec)?</p>
<pre><code>#include &lt;M5Unified.h&gt;
#include &lt;M5EchoBase.h&gt;

#if defined(CONFIG_IDF_TARGET_ESP32S3)
#define RECORD_SIZE (1024 * 400)
#elif defined(CONFIG_IDF_TARGET_ESP32)
#define RECORD_SIZE (1024 * 400)
#endif

#if (ESP_IDF_VERSION &gt;= ESP_IDF_VERSION_VAL(5, 0, 0))
M5EchoBase echobase;
#else
M5EchoBase echobase(I2S_NUM_0);
#endif

static uint8_t *buffer = nullptr;  // Pointer to hold the audio buffer.

void setup()
{
    delay(1000);  // Delay for a moment to allow the system to stabilize.
    auto cfg            = M5.config();
    cfg.serial_baudrate = 115200;
    M5.begin(cfg);

    // Initialize the EchoBase with ATOMS3 pinmap.
#if defined(CONFIG_IDF_TARGET_ESP32S3)
    if (!echobase.init(44100 /*Sample Rate*/, 38 /*I2C SDA*/, 39 /*I2C SCL*/, 7 /*I2S DIN*/, 6 /*I2S WS*/,
                       5 /*I2S DOUT*/, 8 /*I2S BCK*/, Wire) != 0) {
        Serial.println("Failed to initialize EchoBase!");
        while (true) {
            delay(1000);
        }
    }
#elif defined(CONFIG_IDF_TARGET_ESP32)
    // Initialize the EchoBase with ATOM pinmap.
    if (!echobase.init(44100 /*Sample Rate*/, 25 /*I2C SDA*/, 21 /*I2C SCL*/, 23 /*I2S DIN*/, 19 /*I2S WS*/, 22 /*I2S
    DOUT*/, 33 /*I2S BCK*/, Wire) != 0) {
        Serial.println("Failed to initialize EchoBase!");
        while (true) {
            delay(1000);
        }
    }
#endif

    echobase.setSpeakerVolume(80);             // Set speaker volume to 70%.
    echobase.setMicGain(ES8311_MIC_GAIN_0DB);  // Set microphone gain to 0dB.

    buffer = (uint8_t *)malloc(RECORD_SIZE);  // Allocate memory for the record buffer.
    // Check if memory allocation was successful.
    if (buffer == nullptr) {
        // If memory allocation fails, enter an infinite loop.
        while (true) {
            Serial.println("Failed to allocate memory :(");
            delay(1000);
        }
    }

    Serial.println("EchoBase ready, start recording and playing!");
 //  M5.Speaker.tone(2000, 2000);
 //  delay(2000);
}

void loop()
{
 
    Serial.println("Start recording...");
    // Recording
    echobase.setMute(false);
    echobase.record(buffer, RECORD_SIZE);  // Record audio into buffer.
    delay(100);

    Serial.println("Start playing...");
    // Playing
    echobase.setMute(false);
    delay(10);
    echobase.play(buffer, RECORD_SIZE);  // Play audio from buffer.
    //M5.Speaker.playRaw(buffer, RECORD_SIZE, 44100, false, 1, 0);
    delay(100);
}

</code></pre>
]]></description><link>https://community.m5stack.com/post/30904</link><guid isPermaLink="true">https://community.m5stack.com/post/30904</guid><dc:creator><![CDATA[jimruxton]]></dc:creator><pubDate>Thu, 23 Apr 2026 06:31:57 GMT</pubDate></item><item><title><![CDATA[Reply to Atomic Audio Base with M5ATOMS3R on Thu, 23 Apr 2026 01:58:31 GMT]]></title><description><![CDATA[<p dir="auto">A quick update. If I use the version of the M5Atomic-EchoBase library on github I no longer have the issue with i2s conflicts between that library and M5Unified. So anyone using these 2 libraries together be sure to use the github version and not the version currently showing up in the Arduino Library Manager.</p>
]]></description><link>https://community.m5stack.com/post/30903</link><guid isPermaLink="true">https://community.m5stack.com/post/30903</guid><dc:creator><![CDATA[jimruxton]]></dc:creator><pubDate>Thu, 23 Apr 2026 01:58:31 GMT</pubDate></item><item><title><![CDATA[Reply to Atomic Audio Base with M5ATOMS3R on Wed, 22 Apr 2026 20:42:20 GMT]]></title><description><![CDATA[<p dir="auto">The AtomS3R and Atomic Audio Base will work using the RecordPlay example in  <a href="https://github.com/m5stack/M5Atomic-EchoBase/tree/main/example" target="_blank" rel="noopener noreferrer nofollow ugc">https://github.com/m5stack/M5Atomic-EchoBase/tree/main/example</a> . Whenever I  try to include both M5Unified.h and M5EchoBase in the same sketch I get the i2s conflict between new and legacy i2s drivers .  I cant get any sound however when using just the M5Unified.h library. Below is my latest code. Still no sound?</p>
<pre><code>#include "M5Unified.h"
#include &lt;Wire.h&gt;
// Define buffer size (200KB for ESP32-S3)
#define RECORD_SIZE (1024 * 200)
static uint8_t *buffer = nullptr;

void initES8311() {
  // AtomS3R I2C pins for the Audio Base are SDA=38, SCL=39
  Wire.begin(38, 39);

  // Helper to write to ES8311 registers
  auto writeReg = [](uint8_t reg, uint8_t val) {
    Wire.beginTransmission(0x18);  // Default ES8311 I2C address
    Wire.write(reg);
    Wire.write(val);
    Wire.endTransmission();
  };

  // --- ES8311 Initialization Sequence ---
  writeReg(0x00, 0x00);  // Reset
  writeReg(0x01, 0x3F);  // Power down all
  writeReg(0x0D, 0x01);  // Clock on
  writeReg(0x01, 0x03);  // Power up
  writeReg(0x02, 0x00);  // Master clock
  writeReg(0x05, 0x00);  // DAC power
  writeReg(0x04, 0x00);  // ADC power
  writeReg(0x14, 0x24);  // Set MIC gain
  writeReg(0x46, 0xFF);  // Set Speaker Volume to Max
  writeReg(0x06, 0x00);  // ADC Mute Off
  writeReg(0x09, 0x00);  // Set ADC to I2S format

  Serial.println("ES8311 Codec Initialized!");
}


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


  auto cfg = M5.config();
  // Enable external I2C for ES8311 codec on the audio base
  cfg.external_imu = false;

  M5.begin(cfg);
  initES8311();

  M5.Display.setFont(&amp;fonts::FreeMonoBold9pt7b);


  // --------------------------
  // Speaker Configuration (I2S Output)
  // AtomS3R I2S pins: BCK=8, WS=6, DOUT=5
  // --------------------------
  auto spk_cfg = M5.Speaker.config();
  spk_cfg.pin_data_out = 5;
  spk_cfg.pin_bck = 8;
  spk_cfg.pin_ws = 6;
  spk_cfg.sample_rate = 44100;
  // spk_cfg.i2s_port     = I2S_NUM_0;
  spk_cfg.stereo = false;  // Use mono for the base speaker
  M5.Speaker.config(spk_cfg);
  M5.Speaker.begin();

  // --------------------------
  // Microphone Configuration (I2S Input)
  // AtomS3R I2S pins: BCK=8, WS=6, DIN=7
  // --------------------------
  auto mic_cfg = M5.Mic.config();
  mic_cfg.pin_data_in = 7;
  mic_cfg.pin_bck = 8;
  mic_cfg.pin_ws = 6;
  mic_cfg.sample_rate = 44100;
  //  mic_cfg.i2s_port     = I2S_NUM_0; // Use separate I2S port for input
  mic_cfg.magnification = 2;
  M5.Mic.config(mic_cfg);
  M5.Mic.begin();

  // Set volume/gain
  M5.Speaker.setVolume(100);
  // For v0.2.14, set mic gain via config if needed (default works for most cases)
  mic_cfg.magnification = 2;

  // Allocate recording buffer
  buffer = (uint8_t *)malloc(RECORD_SIZE);
  if (buffer == nullptr) {
    Serial.println("Memory allocation failed!");
    while (true) delay(1000);
  }

  Serial.println("Device ready! Press button to record/play");

  M5.Display.println("Click to\nRecord &amp; Play");
}

void loop() {
  M5.update();

  if (M5.BtnA.wasClicked()) {
    M5.Display.fillScreen(BLACK);
    M5.Display.setCursor(0, 0);

    // --------------------------
    // Recording
    // --------------------------
    M5.Display.println("Recording...");
    Serial.println("Start recording");
    M5.Mic.record(buffer, RECORD_SIZE, 44100);
    delay(500);
    Serial.println(M5.Mic.isRecording());
    delay(3000);
    // while (M5.Mic.isRecording()==1) delay(10);

    // --------------------------
    // Playback
    // --------------------------
    M5.Display.println("Playing...");
    Serial.println("Start playing");
    M5.Speaker.playRaw(buffer, RECORD_SIZE, 44100, false, 1);
    Serial.println(M5.Speaker.isRunning());
    while (M5.Speaker.isPlaying()) delay(10);

    M5.Display.println("Done");
    Serial.println("Done");
  }
}
</code></pre>
]]></description><link>https://community.m5stack.com/post/30902</link><guid isPermaLink="true">https://community.m5stack.com/post/30902</guid><dc:creator><![CDATA[jimruxton]]></dc:creator><pubDate>Wed, 22 Apr 2026 20:42:20 GMT</pubDate></item></channel></rss>